Eben Hewitt on Java

Eben Hewitt writes about Java, Service-Oriented Architecture, and general enterprise software development practices.

97 Things Every Software Architect Should Know

As I am wrapping up work on SOA Cookbook, which will be published by O'Reilly in January or so, I came across this website for Richard Monson-Haefel's new project 97 Things. The flagship book in the series is 97 Things Every Software Architect Should Know, with books for Internet Startups, Programmers, and Project Managers to follow.

I contributed axioms 80, 81, 82 ,88, and 95 to the book.

It's a very cool idea, including entries by Ward Cunningham and Gregor Hohpe. I'm excited about this project. You can check it out at http://97-things.near-time.net/.

 

September 15, 2008 in Articles | Permalink | Comments (0)

Speaking at JavaOne 2008 May 6-9

Just after midnight I got the notice that my talk "Designing and Implementing a Real-World SOA" has been accepted for JavaOne 2008. I'll be presenting this with Kevin. Here is our abstract:

Intended for technical architects and enterprise developers, this talk will help you jump start your Service Oriented Architecture using the latest tools, including Glassfish v2, OpenESB 2, Java EE 5, Java SE 6, and NetBeans 6.

The sprawling world of WS-IT, JAX-WS, SAAJ, JAX-B, SOAP, WSDL, BPEL, ESB, JBI, and WS-* can be daunting to say the least. Even experienced Java EE developers can find themselves bewildered by these standards and specs that operate outside the usual Java domain. What's hype and what's real? Do I need to know WS-Policy or ReliableMessaging? I've heard of Metro and Tango, but how do I use them? Do I need UDDI right now (or ever)? When is relying on generated WSDLs okay and when do I roll my own? What are the trade-offs? Do I need SAAJ? How do I structure my ESB? SOAP is a hassle, why not REST? Can XML really be the lingua franca of an enterprise saturated with decades of EDI and COBOL? How does all of this stay manageable? What's this "Governance" thing?

Beyond these questions, Service-Oriented Architects today still face a variety of more common design decisions regarding service granularity, scaling, design patterns, synchronous and asynchronous services, error handling, and workflow. Beyond the day-to-day technical choices, there are strategic decisions that can have enormous impact on the success of your projects.  To say the least, getting your SOA going through all the hype can be challenging.

Using Glassfish v2, OpenESB 2, Java EE 5, Java SE 6, and NetBeans 6, the speakers developed a successful SOA implementation that includes a set of large scale credit processing Services-based applications. Making lots of mistakes and learning along the way, we've distilled this experience to give SOA developers the talk we wish we'd heard when we were designing our SOA.

There is certainly more than one good answer to the questions posed here. The purpose of this talk is simply to light the way so that technical architects and enterprise developers can more quickly and confidently determine for themselves what they need and what they don't.

Developers will come away from this presentation armed with real-world tools, strategies for dealing with SOA-specific challenges on a strategic and technical level, and straight-talk answers to their questions. We'll cover patterns and best practices for developing real-world composite Web Services applications in Java EE 5 and JAX-WS. Together this will help jump start your SOA projects.

The speakers are principal technical architects leading the SOA Team at a $2.5B retail company. They hold several Java certifications, have published popular books on Java, and have written enterprise Java applications for a decade.

To get the most out of the session, attendees should be already be familiar with Java EE 5 and have a basic understanding of Web Services technologies such as XML, Schema, SOAP, and WSDL.

Hope to see you there!

February 01, 2008 in Articles | Permalink | Comments (3)

Jubilate Java, or, Why I Like Java

Writer Christopher Smart, as he was losing his mind in 1762, wrote a lengthy poem called the “Jubilate Agno”, which includes a shorter piece enumerating the many diverse things he loved about his cat Geoffry. You can read it here: http://www.cs.rice.edu/~ssiyer/minstrels/poems/661.html

Thursday last, someone asked me what I liked about Java. I was surprised to hear my own answer, and, not feeling particularly satisfied with what I had said, I thought that I might spell out here some of the things I was thinking at the time, but did not say. What is my relation to this language that I use every day?

So with my apologies to Christopher Smart, to whose wonderful poem I here pay homage, I thought I would spell out some of the reasons I love Java, even in 2007, to clarify.

For I will consider my language Java.

For Java is open source. The code can be read and freely modified. This is obviously true of a remarkable number of languages.

For Java is not a vehicle for viruses. It is as safe as was advertised. However, the whole “portability” advertisement is really a bit of an exaggeration. By which I mean that the same bytecode does not always run exactly the same on different JREs (volatile keyword implementations stand out). No one would suggest that a J2EE application written to run in WebLogic that uses JAAS for authentication and authorization, and contains EJBs is portable to JBoss without not only recompilation but revision (and the revisions get more extensive depending on what you are doing in your code, and you may not even know what aspects of your code will behave differently, requiring regression testing). For example, the same Filter implementation dealing with HTTP Sessions is executed totally differently in Tomcat than on WebLogic. Depending on the work you’re doing in your filter, this could be very problematic, and is not something one would just expect.

For there shall be little likelihood of buffer overflow.

For Java is strongly typed. Even though I often spend a good deal of time taking care of strong typing, and love weakly typed languages too.

For Java allows for many ways to achieve the same or similar goals. This allows for creativity of expression, and a sense of beauty and mystery.

For Java has many libraries that make it easy to use, and it is easy to extend. If you don’t like the way Calendar are Date are implemented (silly ints), you can use Joda (http://joda-time.sourceforge.net/). You have your choice of numerous XML parsing methods.

For Java implements many design patterns. Borders and JTable components are Flyweights, the XML libraries use Factories and Composite, the Collections give us Singleton wrappers.

For Java sometimes takes its cues from the community. Developers loved Hibernate, they get on the committee and we get the Persistence API; developers loved XDoclet, they get on the committee and we get EJB 3 annotations.

For Java SE 6 contains the Compiler API, which opens the doors wider to generative programming, and the Scripting API, which is fantastic for J2EE developers like me.

For Java has checked exceptions, which are clearer than in C#, and more powerful that the lack of exception handling facilities in VB.

For in Java, whitespace is not meaningful.

For in Java, multithreading is built-in, not added on, and is relatively simple.

For Java is both compiled and interpreted.

For Java has anonymous inner classes, integers are always 32 bits, Unicode is supported, and automatic garbage collection is a really nice thing to have.

For Java stands on the shoulders of giants.

For in Java one can tweak any number of aspects of how your application is compiled and runs. I am thinking of heap allocation, gc hints, assertions, configurable security policies, custom classloaders, and so on.

For Java has always been network ready, and features JNLP/WebStart, Jini, JXTA, and JavaSpaces.

For JMS is a beautiful thing.

For Java code can match, remarkably closely, the real world that one is emulating in a program. This is largely a feature of OO, and not Java itself, but I think Java wants us to adhere to good OO principles more assertively than other OO languages. The “primitives aren’t objects” argument sort of went away with autoboxing. While one can certainly write an 800-line fully procedural program or method in Java, the Java programmer of any experience in that case will have an eerily present feeling that he’s doing it wrong.

For Java provides Generics, and although the type erasure constraint demanded by backward compatibility makes it less powerful than one might hope, it is lovely.

For the Java Virtual Machine is a deceptively simple application of one of the fundamental directives of computer science, that we can eventually bridge to anywhere with another layer of indirection.

For in Java, the keywords are few, and while it may be verbose, it is not verbose where it needn’t be. The Python phrase “def do_work(self):” is longer and tells us less than “void doWork(){“. The “def” is implicit in Java, as is the “self”.

For Java is not pompous or loud or rude or showy or full of itself or standoffish or intimidating, and the tools we have for it, like Eclipse and IntelliJ, are like loving friends.

For Java is faster than its reputation suggests.

For Java is free.

For Java has annotations, which appeals to the meta-person in me who watches.

For Java makes me happy, as it is fun to write, and its programs contain dramatic structure.


While there are any number of these items that are true of other languages, and while in Ruby on Rails you can put together a complete CRUD web app for your 172 table relational database in under 11 seconds, I love Java.

January 14, 2007 in Articles | Permalink | Comments (0)

Swing GUI Design for the SCJD, or, Honey, I’m Just in the Mood to Use Some Software

This is about designing software user interfaces. I am leading a study group on successfully completing the Sun Certified Java Developer project, and we’re talking about UI design this week. So here are some thoughts.

Abstract the GUI to hide how the system works (user should be spared the details).

Think of successful user interfaces in the real world and what is great about them.

-Steering Wheels. They are amazingly simple, hide complexity and implementation. It is simple because you aren’t tied directly to controlling each individual wheel. It could be a truck with 12 wheels or a 4 wheel drive or a front wheel drive and the interface is identical.
-Telephones. Old telephones used to require you speak into the phone base, and hold the receiver to your ear. Modern phones accomplish the same task but afford greater freedom by combining the two in one handset. The UI is roughly the same whether it is a cell phone or a desktop phone. The newest phones free your hands altogether.

Rule #1: Write Use Case Diagrams before doing your GUI.

Even if you are being "agile".

Dr Horstmann is the author of Core Java, and offers Violet as a free UML editor.
You can use Violet via WebStart at
www.horstmann.com/violet

-Keep it abstract and separate from implementation.
-You are required to use a Jtable.
-What components can you use to

Remember that there are three distinct processes to keep in mind—don’t let them spill into one another, though they are obviously complementary:

1. What the system does (what goals can be accomplished with it)
2. How the system does what it does under the hood.
3. What the user has to do to accomplish a goal.

Rule #2: Sketch your GUI on Paper First

After you’ve written use case diagrams, sketch your GUI on paper.
-It is the fastest way possible
-Changes are a breeze.
-You can show colleagues easily
-You can show your mother, or someone who is not a programmer or necessarily interested in your system and use that to help you determine if your UI is easy to use.
-Shoot for 5th grade level. That is, a 12 year old product of standard American public school system education should be able to immediately use your UI without asking any questions, without reading any documentation, and without having been told what the system is even for.

Once you are happy with your GUI layout, make a few Xerox copies of it. Then use a pencil to break up your sketch according to the panels you will need to break it up into. Remember that nesting panels is a good idea. This is like the process of breaking up a Photoshop layout for a web page into HTML tables or divs. Once you are happy with how it is broken up, then the layout managers you need should be clearer. This will also help you work over your GUI design from a different perspective, and maybe notice flaws in it. Only now should you start coding your GUI.

Group your user interface items logically. Duh. Consider the “File” menu that organizes Open, Save, New operations.

Be disciplined about what aspects of your GUI should allow creative flourishes. The order in which your menus appear in your menu bar is NOT one of them. That is, it would be entirely indefensible to organize it like this:

Help Tools File Edit

There is one obvious, conventional way of doing this:

File Edit Tools Help

Which brings us to…

Rule #3: Users do NOT read.
They feel their way across a layout, based on conventions. Users often will click a button without reading the label because they see in their peripheral vision a gray box that they figure is about the size of a button and is located on the UI at the bottom right hand corner of the form, and they guess based on that information that that’s the “Save Changes” button and click it. I am not exaggerating and if you have developed user-facing software for any amount of time you know it’s true.

Rule #4: Software should be so transparent, so invisible, so achingly thin that users forget they are using it.
That’s because users use software to do their real job, accomplish some other goal, which is what they care about. No one in the world cares about software in itself. No one in the world would simply starting using some random piece of software, in order that they might have the pleasure it affords in its own right. No one says to her husband, “Honey, I think I’m going to go use some software now. Any old program will do. I’m just in the mood to use some software”. They say, “I am going to write a letter to the theater downtown in order to voice my objections regarding the lack of Mexican wedding cakes sold at the intermission.” Then they sit down to their laptop and open Word.

Make a Prototype
Once you have your GUI sketched, make a prototype based on it. Stub your data, just print out to the console in your action listener.

Do NOT use editors in Eclipse or Matisse in NetBeans to do your dirty work for you. Not only is this highly questionable and suspect with respect to the rules of the exam, you will rob yourself of the joy of learning GridBadLayout, one of the simple pleasures left in modern life.

If you don’t know any Swing, now is the time to dig in. Do the Sun tutorial and read the code. Read lots of it:

http://java.sun.com/docs/tutorial/uiswing

Rule #5: Don’t forget the keyboard.
Think of how you use software. Do you drag the mouse all the way up to File > Save? No way. You hit Ctrl + S every few seconds as you’re typing. It’s part of the flow that helps you get your work done quickly. Make sure your GUI has all of the keyboard mnemonics that you yourself would expect.

This is not the time to get inventive, either. Do not make Alt + S be the shortcut to Save. Or Ctrl + V. Save is Ctrl + S, forever and always, and if you violate this rule I think that Dante has a special circle of Hell reserved just for people like you.

Rule #6: Use the MVC Pattern or Observer Pattern
If you don’t know the MVC Pattern, now is the time to learn. Once you have your GUI Sketched and prototyped, apply MVC to it.

Check out these resources:

MVC
http://en.wikipedia.org/wiki/Model-view-controller
http://c2.com/cgi/wiki?ModelViewController
http://www.purpletech.com/articles/mvc/refactoring-to-mvc.html

Observer
http://c2.com/cgi/wiki?ObserverPattern
http://www.dofactory.com/Patterns/PatternObserver.aspx

See also java.util.Observer

Rule #7: Combine Layout Managers
Don’t inspect the layout managers and decide that Spring Layout is for you and that’s all you use. They can and should be combined in order to achieve the best control and fluidity and clarity of purpose.

Test your layouts under many conditions: different size screens with different resolutions and on different platforms. Some of the Swing stuff is just not the same on a Mac as on a PC. Aside from the obvious differences, as an example, colored backgrounds on Jtable headers simply did not work in JDK 1.4 on the Mac. Make sure that when you resize your window it fluidly reorganizes all of your components. Users will do this and should be allowed to, and if your UI tumbles apart when its resized, you did it wrong.

Here are a few final points to help you make sure it is production-ready, and encourage you to use finishing touches.

  • Use keyboard shortcuts, as discussed above. Accelerators give power users keyboard shortcuts to bypass menus, while Mnemonics let you navigate with the keyboard (http://java.sun.com/docs/books/tutorial/uiswing/components/menu.html#mnemonic).
  • Select icons and use them on your menus and throughout your app. You can use Sun’s icons from here: http://java.sun.com/developer/techDocs/hi/repository/ They aren’t beautiful or even very good. But you should use them because Sun thinks they are good enough, they are complete and clear, and it is a waste of time to create your own for this project.
  • Set Tool Tips for everything. Consider whether or not you need to use the Accessibility API (http://java.sun.com/docs/books/tutorial/uiswing/misc/access.html). Defend your choice in your choices.txt.
  • Consider using the Preferences API introduced in JDK 1.4 to have your app remember the previous location of the window the last time it was closed.
  • Put borders on your panels to logically separate areas of your UI using BorderFactory.
  • Use JScroll pane. Just because your database only has 25 records doesn’t mean your UI should only handle 25 records.
  • Consider using a JToolbar in addition to Menus.
  • Put labels at the top of your pages so your user knows where he is.
  • If you have a wizard, tell the user what step she is on (“Step 3 of 5”).
  • Consider your server—do you need a GUI for that?
  • Use status messages.
  • Use a Shutdown Hook to clean up any objects and exit safely.
  • Center your window on the screen.
  • Build in logging using the Logging API introduced in JDK 1.4 now. Do not wait. Log absolutely EVERYTHING. Then modify your Handler to tune out the noise as necessary—don’t remove logging statements.
  • Don’t go crazy. You are trying to make the best UI possible. That is assuredly not the UI that shows off how you can cram the greatest number and variety of components into a single panel.
  • Use confirmation dialogues as apporpriate.
  • Note that your requirements mean that you need a dialog on start up to allow the user to specify a few options. You have some choices to make here.
  • Use JFormattedTextField to validate data. Users are guaranteed to type any ridiculous thing, out of negligence, ignorance, and pure spite. Don’t get suckered in.
  • Use the Ocean Look and Feel. It is nice looking, and it is available on all Platforms. Windows LNF is not. Your grader will almost certainly be using a Solaris OE box.

Rule #8: Use common sense!
I have seen this on real UIs, unbelieveable as it is: a pair of check boxes grouped together—one that says “Yes” and one that says “No”. Know what kinds of situations controls are intended for and use them only as intended.

Rule #9: Make the workflow obvious—don’t confuse choices with options.
Users need to be set on a path where they can’t wander away and lose their place and screw up what they were doing and lose their work. But they need to be allowed to change their minds (Cancel). This is a fine line. Make your UI so they can change their minds without killing themselves, but don’t make them think. You just have to feel your way through that one.

Check out
http://www.useit.com/ for more info.

October 05, 2006 in Articles | Permalink | Comments (1)

The Tao of Development: From Programmer to Developer

I recently began a course mentoring some colleagues in Java development. They have passed the SCJP and are beginning the SCJD project. The question of the difference between a Programmer and a Developer came up, and has been a question floating around the web for some time. Erik Sink has written about the difference here, for example: http://www.ericsink.com/No_Programmers.html

I had some thoughts on the matter, and while the terminology itself is not interesting, it proves useful as a function. So here is what I have come up with:

Programmers specialize in writing code. Developers contribute in multiple, diverse ways to a project’s success. Developers write documentation and specs, perform analysis, and work comfortably throughout the tiers of complex applications.

Programmers make programs that compile and run. Developers make programs that are elegant. Developers make it elegant because beautiful is better than ugly. Because creating a beautiful thing is personally meaningful. Because elegance means "succinctly yet completely expressive". That makes elegant code easier to understand for the programmer who will inherit our code. Because programs that use a small amount of intuitive code to great effect are superior to programs that use a large amount of code that is difficult to understand to achieve the same effect. Because elegance is useful theoretically. Because elegant is inviting. Because elegance means unusually effective and simple. Because in Western culture, elegant means consistent, and focused on the basic qualities, and those are viewed as beautiful. Beautiful is desirable for no reason.

Developers know the difference between complicated and complex, and reject complication.

Programmers want to show everyone their activity. Developers know that it is only progress that matters.

Programmers run their code to find out if it works. Developers write automated test cases to make sure that it works. Developers regression test when code changes.

Programmers rely on QA to find out what is wrong with their code. Developers rely on QA as a sanity check to ensure that their code works equally well in unexpected circumstances.

Developers participate actively in Code Reviews as both the Coder and the Reviewer. Developers know that you often learn as much by teaching as you do by learning. Developers mentor every chance they get.

Programmers hire other programmers and worry they will be outshone. They like to be the best. Developers see everyone’s strengths, and surround themselves with more skilled people than themselves.

Programmers consider only their current algorithm, or method, or class. Or perhaps their current use case. Developers consider their entire system, and consider their system as a small piece of a universe of systems that will all have to live together. Developers consider how their system impacts that universe. Programmers think locally. Developers think globally and act locally.

Developers read to push the boundaries of their craft because they understand that they are not just making a program, but adding to the complexity of the entire IT ecosystem that includes other systems, hardware, networks, and more. They are not satisfied being good coders. They must be good IT citizens.

Developers demand to always and only tell the truth in their design, no matter what. That means that their code reflects the real world—not a part of the real world that is modified to work in some program’s use case. Developers do not view the programming problem before them as fixed. Developers know it is fluid, and they are not afraid to change the programming problem if it is necessary in order to tell the truth.

A Programmer’s program is a private language; it uses every bit of the language, and is rigid. It cannot be translated. You can translate a Developer’s program to plain English, and it reads like a children’s book.

Programmers are afraid of what will break in their program when the business rules change. Developers know that when the business rules change, their program will absorb it, because their program tells the truth about the world, and the world makes sense. Extending their program is no more strange or difficult than adding a hobby to your life.

Developers know when code becomes legacy code—the moment it is committed to the repository. Legacy doesn’t mean old—it means existing in the world, so someone will have to determine what is true about it—what it does, doesn’t do, how it works, why it exists, how it relates to other things. Developers are very careful to make legacy code, because they know how expensive it is.

Developers write clear, concise, helpful, correct, updated, cross-referencing documentation. They feel silly doing it, because their code is so simple, expressive, and only ever does one thing—the one thing for which it is named.

Programmers do what the customer asks for. A programmer is a passive receptacle for the customer’s "requirements". Developers refuse to accept a passive role in the customer relationship. Developers know that customers typically describe solutions when they think that they are describing requirements. Developers are brave enough to design the program, and not allow the customer to do what he is not qualified to do.

Programmers listen to what the customer says and believe they are doing their job to simply make what is described. Developers refuse this, because they know it hurts the customer. The Developer hears what the customer says, and also hears what they don’t say. The Developer gets the customer to divulge the problem, not the solution. The Developer does this by knowing the right questions to ask. Only in this way can the Developer get the customer to talk less and say more.

The Programmer is a mirror for the customer’s text. The Developer provides the solution based on true active listening. The Developer interprets the customer’s script, and directs a film.

The Programmer enjoys gathering requirements, because they are finding out what they get to make. They feel their power as they think of ways to implement the requirements. The process excites the customer, because everyone enjoys expressing his desires. The Developer knows nothing is more boring than requirements. The Developer knows his role in the process is to break down everything the customer says until there are no more assumptions, but only many hundreds or thousands of tiny, raw, simple, undeniably true statements about the world. Each of these statements is as interesting as the entries in a phone book.

Programmers feel that they are smart, and focus on programming the customer’s solution exactly as outlined. Developers forget what they have to program. They work hard to maintain only a foggy idea about the business rules. Programmers work in photographs. Developers work in rough chalk sketches. Developers actively do their best to remain dumb about the business rules, and continually express gratitude for the patience of those working with them. Developers stay dumb about the rules in order to stay general. Developers know that rules are at once like commandments—the most important thing, the only thing, the law—and yet also as worthless as gossip on the most trivial breeze. Developers at once respect the rules simultaneously as law and as gossip. The Programmer cares too much for the rules, and he will write a world where the rules are the only true things. The Developer stays dumb about the rules, and so he will write a world where the rules can be true. Because he knows he cannot remember and understand them all, they must be adhered to with utmost precision. But only indirectly. The Developer understands there is a paradox in free will. He does not make mistakes about causation.

The Programmer writes a program that represents the business solution. He loves his solution because he is married to it, and he must guard it jealously from change. The Developer writes a world that the solution inhabits. The Developer knows that his solution is incidental, and has no particular feeling for it. He admires its beauty, because it is something in the world that is pretty, like a leaf.

The Programmer’s program is a room. He cares deeply about the walls, the ornaments, the flooring, the treatments, the colors, the dimensions, and everything about the room. He is delighted when his customers see it. He wants his customers to use what he has made, to feel the textures of the rich fabrics. He will be praised for such richness. The Developer wants the customer to achieve her goal. He knows that his program is successful when it is invisible. He knows it is not the walls and floors and windows that the customer lives in, but the empty space in the room that the customer lives in. He will not be praised, because the customer will believe that the Developer has done nothing--the software appears to have been there all along.

Programmers only ever see one choice before them. Developers have many choices before them. They know they have found the right choice when it comes to appear as if they only ever had one choice all along.

Programmers like programming, and will accept programming work in order to have the pleasure of making a program. Developers ask what interest the program serves. Developers know they are always serving an interest, and their pleasure derives from being in the service of that interest. A Developer knows that it is the interest that matters, and not the program. The fact that he happens to be the person who writes the code is interesting only to him, and is not interesting to anyone else, and is not intrinsically interesting. Developers like complex problems, and are not interested in uninteresting things, such as the fact that they are developers.

Programmers are hired for a job. Developers cannot be hired. Developers must be trained to be Developers from the inside.

Programmers like it that people think they are smart. Developers like it when they know they have been useful. They know they are no smarter than a painter or a cat.

Programmers care intensely about their view of a project. They are agreeable and flexible, and change their views as the business appears to require. Developers know that their view of a project is not interesting to anyone but them. Yet they never compromise on what is required to make the project successful, even if it is unpopular. They do not have to compromise, because they cannot be hurt.

Programmers do not ask questions, because they are afraid of revealing what they do not know. Developers ask questions because they are in love with learning.

Programmers know everything. Developers know they don’t know anything at all. You become a Developer when you give away to others everything you know and everything you do not know.

September 08, 2006 in Articles | Permalink | Comments (0)

Writing online

I've noticed this: one must be very carefully in interpreting emails, and indeed the written word on the Internet.

Emails have no context for the voice. They are not accompanied by gesture, vocal pattern, or facial expression. Much has been written about this and I won't rehash it here. However, there is one thing that can serve as a guide when trying to fathom the general feeling or intent behind an email you get from someone you don't know too well.

People over thirty think that an email message is an quicker, sometimes less formal version of a written letter.

People under thirty think that email is a slower, and unfortunately more formal version of an Instant Message.

Not that we always know the age of our Internet interlocutors. But this does tell us something about how to communicate with each other. I experimented a little with the kind of writing that might feel like the internet in my recent book Java Garage. Some people loved it, and some people hated it. It seemed from my vantage that those who were more inclined to like that book were younger, and it was young people (college age) who were the target audience.

But it was trashed by older, dare I say more vocal, readers, who I think equated its very conscious style with a sort of degeneration of culture. I have a Masters degree with an emphasis in literary theory. I know some things about writing. Like sentence fragments. When I end a sentence with a preposition, I know where it's at. Writing with gerunds and participles comes easily to me. When I split infinitives, uh, it's on purpose; I want to boldly write as no man has written before.

But that book is over, so I'm not selling anything here. I'm trying to make a point about communication, specifically in the tech world where it is crucially important to talk in a very precise manner. This is true of any engineering field (I refer readers to the scene in Spinal Tap where Nigel has the contractor make a 12" Stonehenge monolith for a concert prop).

No one has criticized the Java content of the book. I haven't seen a better explanation of abstract classes anywhere. But they hate the style.

There is an old Ray Bradbury short story called "A Sound of Thunder" that characterizes the total degredation of culture in a series of signs on shop windows and newspapers that are written with broken English--a weird, prescient mix between Prince lyrics and a typical 13 year old's AIM session.

This is perhaps a characterization with which the French Ministry of Culture could agree, as they carefully interrogate words and phrases to be admitted to the language, regardless of the fact that French teenagers use the term "blue jeans" to refer to "blue jeans". This is no different than a manager in America giving a programmer "carte blanche".

I wonder if a very meaningful case can actually be made, that the Internet is helping destroy culture by destroying language. While something in me revolts when I see a phrase such as "I want 2 b a programmer at yr company", I think it is not the language against which I revolt, but the fear that the means of expression is the only one available to the writer. When I read the inner sleeve of Purple Rain as a 13 year old, it didn't occur to me that Prince was anything short of a master of expression--something I still think. He has many means of expression available to him, and writes in what used to be an innovative way.

I am in love with language. If language can be torn down, start tearing. Break its bones. Destroy the English language, which itself, we might do well to recall, is a cacophonous destruction of German, French, Latin, and many other langauges. Have you ever read Chaucer? If you have, I bet money your reaction wasn't "Oh, Eliza, how far we have sunk into the despair of our current English language. How sad a state that we don't still write Middle English." No one thinks that because it would be idiotic. In part, it would mean that one must suggest that Shakespeare had only a paltry language available to him. In many ways, that's true. He was larger than the English language could contain. Shakespeare single-handedly contributed more than 1200 words to our language.

What would the ministry of culture say?

October 03, 2005 in Articles | Permalink | Comments (0)

Getting Better Requirements from Customers

As we know, software projects fail at alarming rates--typically somewhere around
80%.  There are many reasons for this. One reason is that the programmers get the wrong
requirements. Changing requirements and scope creep are separate issues that need addressing
on their own, and I'm not going to talk about that right now. There are more things afoot
with this Getting the Wrong Requirements business. Often, the programmer or analyst
interviews with customers are simply ineffective. The interviews don't get to the bottom of
the issue, or we come away with an incomplete understanding of what the customer wants.

In Extreme Programming, there is the concept of the User Story, which is intended
to capture a use case in its simplest form, and leave details open to continuing
conversations between the customer and the programmer/analyst. The idea is that
requirements change, and because of that, our documentation gets out of date quickly,
and you have a lot of people trying to maintain documentation that generally isn't
trusted anyway (because it's known to often be out of date or incomplete), and that
such maintenance is, like, a waste of time.

I can see that. I agree with that, even, that it's good to focus on the software product, communicate through code, talk a lot with the customer, and not on chasing around these massive documentation tomes.

However. There are many problems here.

The first of which is that the "customer" doesn't exist.

The Customer Doesn't Exist

What we talk about when we talk about customers in software development is often this
necessarily idealized concept of the customer. As if there is one person who can answer all
of the questions. Who knows enough, is available enough, is approachable enough, is articulate
enough. Often the customer consists of more than one person. A committee of executives, perhaps.
You may need all of a few of them to get a decision or clarification.

It is therefore a good idea to get something more out of them when you have the opportunity
than a User Story card with some cryptic phrase like "[Make ecommerce here]" scribbled on it.

But even when we record enough about what the customer states, adjusting as requirements change, we still don't get it right. Why not?

I have observed that frequently customers will give you the Solution, but not the Problem.

This is a Bad Thing. It is your job to write great software, and the customer's job is to help you
do it. They help you do it when they give you the Problem, and you determine the right Solution.
You are a professional. That is your job. This kind of thing makes me nuts.

I don't tell the dentist where to drill, or if he really should give me a root canal or not. I do
as I'm told because I don't want my teeth rotting out of my head and on such matter he knows bloody
well better than I do.

Yet in IT we let customers railroad us all the time. The same customers who wouldn't dream of telling their dentists that the porcelain bridge is actually inappropriate in this case, and shouldn't he
really use this new polymer she heard about from her stock broker.

Notice in your customer's conversation whether they are giving you the Solution instead of the Problem. And don't allow it.

Everyone will pay later if you allow it. You'll pay, the customer will pay, the customer's customers will pay.  It's part of your job as a developer/analyst/architect to notice this, put a stop to it, and _force_ the customer to clear her head and forget what all about what her 14 Year Old
Nephew Who Is Really Not Too Bad At Front Page And Had Some Good Ideas Regarding This told her she could do.

This can be surprisingly difficult. People don't like bad news. They don't like to pay for something they didn't choose. They might not trust you entirely, and think you just want to play with that new toy or get it on your resume.

But that's the name of the meeting in your little digital invitation after all, "Requirements Gathering". It doesn't say "Solution Telling by Customer Meeting". But in the current culture, Front Page is the New Word. Whereas in the 80's only a complete dumbass Luddite geezer didn't know how to use Word Star, and secretaries who took dictation went the way of all things, for the last few years we've been smack in the middle of in the age when only complete dumbass Luddite geezers don't make their own web pages with copied and pasted applets. They know all about it now. They just program their VPN with HTML and send it up to the HTTP and 6 phone calls later to a help desk or that 14 year old nephew and they're good to go. What that means for you 8 times out of 10 in that any given customer now feels sufficiently on top of things that they can tell you what it is they need. I just need a floating applet in the shape of a cube that I can rotate and get my files by clicking on them as the cube rotates around. I saw it at my wife's work, and that's just what I need. 8 times out of 10, that's not at all what they need.

Your Customer is Not Your Customer

Here's another strategy. Pretend, as you develop software and work in requirements meetings, that your customer is not your customer. It turns out that this is a very easy thing to do, because it is true.

Your customer's customers are your customers.

If your customer's customers win, your customer wins.

If your customer's customers win, you win.

If you're writing an ecommerce application, take care of the things that you know people who will shop at that site will need. They'll need SSL. They'll need encryption of stored data. Your customer may not mention this. If you know that your customer is leaving out things your customer's customer will need, get it addressed.

If your customer willingly and knowingly doesn't care about certain important things that your customer's customer cares about, consider stepping away from the project. It's Teenage Suicide (don't do it). Just because Sally customer doesn't want to pay for SSL every year and wants to store credit cards in plain text because it's six hours less you have to get paid to encrypt them, it's not okay to just agree. You're killing your customer's customer when you agree to work you know is a bad idea.

Customers all have Windows ME, and iPod Shuffle, and some old $30 Lexmark printer in their garage, and this entitles them to judge whether or not SSL is a requirement. It's idiotic. Yet we in IT put up with it, because it's easier to do it wrong and then gripe about it to our sweethearts who get to find out what heros we really are because we would never have been so stupid to use an Active X control when Flash can export XML.

If you're the guy who hangs around the garage telling the mechanic what to do, how about you stay home. If you can fix it yourself so great, then stay home and fix it yourself, and leave room on the mechanic's schedule for nimrods like me who only in the last 6 months learned the difference between a tire and a wheel. I need the slot, dammit.

You can recognize meetings where you're going to get the Solution instead of the problem in this way: as you are in the meeting talking to the customer, you find yourself nodding your head, saying little, things vaguely make sense--but the details are sketchy, and when you get out of the meeting you have no idea what the customer actually wants, why they want that, or how to build it.

You can recognize this kind of meeting if the customer is sketching forms for you.

If they are saying anything at all about checkboxes or applets or CSS or XML.

Requirements gathering meetings are not implementation meetings. Just forbid the use of implementation-specific terms unless it's part of the domain, or an absolute. Now one can't be rude, but you have to be disciplined enough to just strike these things from the record, as it were, in the Perry Mason courtroom of your mind.

So how do you maintain the discipline in these meetings, which can be deceptively difficult? It requires a paradigm shift.

In 1649, Richard Lovelace wrote a poem called "To Lucasta, on Going to the Wars". Here it is:

Tell me not, Sweet, I am unkind
That from the nunnery
Of thy chaste breast and quiet mind,
To war and arms I fly.

True, a new mistress now I chase,
The first foe in the field;
And with a stronger faith embrace
A sword, a horse, a shield.

Yet this inconstancy is such
As you too shall adore;
I could not love thee, dear, so much,
Loved I not honor more.

So what does Lovelace teach us about customers on software projects? That you must honor the customer by fixing their problem. Their real problem. Their real problem is not that they need hand holding. Or chocolates at meetings. Or someone who should know better to simply nod their heads in agreement with every utterance. We must not be afraid of our customer. Even if it's the boss. Sometimes if our customer is the CEO of our company, this can be difficult. I understand. It's our job.

They knew in New Orleans that the levees would break. Engineers told them. They made it clear. Years in advance. They could have fixed it. They were told how. The city and the state didn't want to spend the money. They feds didn't want to spend the money.

This frequently happens in IT. It happens every day. I understand. That doesn't mean we get to float through customer meetings griping under our breath that it'll never change around here.

No One's Customer

You cannot solve the customer's problem without solving at least a couple of IT's problems along the way. Frequently, companies are divided up for accounting purposes such that HR would have to pay IT for a project from their own budget. Sometimes this practice is so rampant that the departments are even divided into their own companies. That's fine. I'm not an accountant. But sometimes when this is the situation, we frequently find our IT infrastructure in shambles after years of doing projects for other departments. That's because everyone is our customer, but we're no one's customer. Your company may not like to pay for IT keeping up its infrastructure. They'll deploy Windows XP to 20000 desktops with no discernible improvements over Windows 2000 with the exception of the possibly useful feature of the built in wireless driver manager. But we can't upgrade the SAN. We can't afford another Admin. If you're in such a company, I can't help you. I don't know the cure. If you know the cure, let me know. Because we can't control that. It's not our money.

But the requirements gathering meetings, _are_ our meetings. Our name is on it. It's our shot to help call.

If your customer doesn't want to talk about security, because security is expensive, isn't sexy, and isn't even a _feature_ in the customer's mind, you must force the conversation.

You cannot love your customer so much, love you not IT more.

The customer doesn't want to pay Microsoft for 5000 seats in Active Directory. No one wants to pay Microsoft 5 cents for anything ever again. It somehow just doesn't seem right. But if they want indentity management, there's just no good way around it.

You know what the problems are going to be. The customer probably doesn't. You know that any website worth writing will be hammered non-stop with DoS attacks. Customers don't care. Because security is not the problem they asked you to solve.

In fact, as my friend Barney says, "security is never a problem. Until it's a problem." Then _you're_ the jerk who didn't impress upon me the dire need for SSL and data encryption--I _told you_ that security was important.

Have the conversation now. I just use security here for simplicity. The issue may not be security in your app. Maybe they'll pay for iris scanners till the cows come home. It's something else maybe. But I bet it's there.

I've actually found that there is little predictability in what customers will or will not pay for from project to project. Even the same customer. But I think I know why this is. I've found that this is generally because the customer wants what his golf partner (read Bourgeois rival) just got His IT Guy to do. Hm, you know I overheard in the clubhouse that the CIO of Dial is putting in RFIDs. I better put in some RFIDs too. Let's find something to put them in.

This all sounds so obvious. We all know this. But I see it day after day.

Do not agree to things you know you shouldn't agree to. That includes deadlines, cheesy specs, incoherent requirements. Later they're going to forget all about the fact that you "really tried" to get them to buy the firewall between the web server and the app server. You must make it clear: If you don't buy the firewall, your app will fail. It may take 6 months or a year, but it will fail.

And don't be that guy, the guy that lets the company shoot itself in the foot with your name. If it means you have to walk away, walk away. How many failed projects does it take before the customer decides that you're the common thread in their continual project failures? Two, max? Probably one.

I suppose when the fingers start pointing, and they eventually point at you, your can point at your analyst and your analyst can point back at the customer. And the world will keep turning. But it's not required that we're so passive. They want to know. They might fuss a lot, and really make it seem like they don't want to know. And once they know, they may still not want to pay for it. But then, at the least, we've done an honest day's work.

The onus is on us to get better requirements.

September 15, 2005 in Articles | Permalink | Comments (0)

Contract by Comment

When you write a class, you are not simply writing a class. You are designing an API for clients of your class. Perhaps this sounds obvious. And when you design an API, it is important to balance power with flexibility, convenience with control. Your interface is your contract.

I saw the following code the other day:

/**...
NOTE: For sale items, the productName MUST end with $S$
*/
public String someMethod(String productName) { ... }

What’s the matter here?

The author of this class is trying to enforce his interface in an extra-programmatic way. He wants us to please not pass anything that doesn’t end with an $S$. But he does not forcibly keep us from so doing.

Note that we are not told what fate befalls those poor saps whose productNames do not end with $S$. The author of this method is Asking "Please honor this programmatic "contract", despite the fact that it’s totally fake, because if you don’t honor it the class will break or, worse, fail silently, or even worse, appear to act correctly while it just silently fails".

This is what I call contract by comment, which is no contract at all. Everyone should know what a phenomenally bad idea this is. In fact, it rather seems that we've heard a butt load of times that we aren't supposed to do this sort of thing. Ever. So what's the real issue here?

The lesson is this: in programming, as in life, and contrary to our social intuition, it is actually more generous to be hardcore. Easygoing people are approachable. They happily give you little bite-size Abba Zabbas from the big plastic sacks they keep hidden in their cubes. Lots of them. They are nice people.

More so, it certainly appears that these easygoing, chirpy folks are "nicer" than the pencil-bending guys at the Monday meeting who are always harping on details, beating the dead horse, foregoing chit-chat about your racquetball club, and not shooting the breeze about how loaded they got in Vegas this weekend.

The water cooler guys seem nicer, if even in a bitchy way. It would appear in fact that we are supposed to become water cooler guys. That the company wants us to gravitate toward the middle, where we loosen our belts after an $8 lunch pasta from Nick’s and complain in a vaguely pained, vaguely self-deprecating, vaguely resentful whine for an extra 15 minutes about how the boss won’t get us tools. Even though they’re 3 million ahead of this quarter last year. The bastards. Ha ha ha. Isn’t it true. Aren’t we collegial.

Guys don’t seem nice who have their heads in their screens all the time. They’re always ranting about "standards". They hate mistakes. They don’t suffer fools gladly. They will argue with you about the implementation because they give a damn about the implementation. I submit that it is these programmers who turn out in the end to be nice. Because it is work. It is your job. It is not a party. It is fun, if you’re doing it right, but given the choice, many of us would be somewhere else any given hour of the work day.

It’s not nice to be nice. It’s nice to be hardcore. Because when you’re hardcore, you’re clear. People know what they are supposed to do. They know how to do it, or know they better find out how.

I don’t know about you, but I don’t like to get a phone call at midnight that I need to come in and fix some broken production app. The hardcore guy’s app doesn’t break, and so he doesn’t get that phone call, or cause others to get those phone calls. I appreciate that. I think it’s nice. Because the attention to detail is there, and because things are dotted and crossed, and because he has been very strict about following the rules and very strict about what he’ll allow and disallow through the firewall, within the cluster, into the method.

In my book, that is the nice guy, because he doesn’t ruin my life. if I wanted to shoot the breeze with somebody, it wouldn’t be Chuck the Analyst down the cube farm who is super nice and didn’t want to hurt the customer’s feelings so they didn’t ask for clarification so we wrote the wrong thing. I don’t think that’s nice to me as the programmer, and it isn’t nice to the customer who’s paying for something they don’t want. If I had to shoot the breeze with someone, it ain’t Chuck. It’s Alison. So if the story here is that we’re going to shoot the breeze with Chatty Kathy from HR, then I’ll just go home. That’s just not a reward for me: I want my stuff to work. And I depend on her. Be hardcore and make your stuff work. People will appreciate your generosity in so doing. If you’re concerned about what others think.

If you’re not so concerned, then ask yourself some pretty tough questions about your API. Make it tough. Make it flexible where it needs to be and convenient where it needs to be, and don’t be mean to your clients by silently failing if they don’t do what you ask.

Disneyland doesn’t ask me nicely to put my seatbelt on, shoot me 1200 feet into the air and hope I don’t fall out. They clamp a big huge steel bar down across me and lock it in place.

Be strict in meetings. Get the work done. Ask the tough questions. It’s nicer.

Be strict in your methods about what params you'll accept, and actually disallow something that's unacceptable. Be a dictator about your upper and lower bounds on a class parameter. Don't hope you get a good deal. Don’t pray that your client’s param ends with $S$. Make sure it does. And if it doesn’t, throw an appropriate exception. If it makes sense, give them a delimited set to choose from that only includes things that end in $S$.

Perhaps an obvious reason that this sort of thing happens, even when we all know we're not supposed to do it, is that it's a lot more work to do things right. In my experience, you pay now or you pay later, and it's always more expensive to pay later. It's more work, and more expense, and more angry users, to fix an app in production. (Something else all programming managers know).

Don’t make a contract by comment. Enforce it programmatically.

September 12, 2005 in Articles | Permalink | Comments (0)

On Code Reviews

I think code reviews are crucially important to the success of a
development team. Here are some of my thoughts on how code reviews
might go for a relatively small team.

I understand that at Google they have a dedicated senior person whose
job it is to run the code reviews. That's probably terrific for their
QA. For smaller teams looking to figure out how to do them, here are
some ideas.

On Java Coding Standards
Adopt the Sun standard. Don't think about it too much. It isn't interesting.
You can find this here: http://java.sun.com/docs/codeconv/

Have all of your programmers write their code to conform with it. Their IDEs
should be set up to automatically format it this way. With Eclipse and IntelliJ
and other IDEs, you can create a template so that everyone's source physically
looks the same.

It is terribly boring to sort of drone on and on about whether your fields
belong at the top or bottom of your class, or whether your curly braces belong
on the same line or their own line.

However.

It is also, in my view, very important that everyone's stuff looks the same.
That is, it doesn't matter _that_ your fields are at the top of the class (uh, where
they should be), as long everyone on the team has them in the same place.

This is because code must be readable. If 80% of the cost of software is in the
maintenance, your stuff has to be readable by someone else so that they have the
best chance of finding where the problems are.

This assumes there is some clear set of standards regarding program structure.
Code formatting is worthless if there's no shared understanding of refactoring to
patterns among team members.

The Pragmatic Approach
So here are a few pragmatic ways to approach that matter.

Create a set of development guidelines. These include key aspects of,
for example, Bloch's book Effective Java and books like Bitter Java. These are
an obvious minimum if somehow your team is reading-adverse.
Identify general highlights from these, and publish for everyone to access
(say, on your intranet). Make sure no copyrights are being violated. I'm talking
about standard stuff here.

Add your own guidelines to this as people think of them. Have people
understand and follow these general guidelines. These include reminders such as
"Always override hashcode when you override equals" and
"Here is the definition of a Java Bean",
"Don't use the interface enum antipattern" and like that.

If your developers don't all have a strong, shared understanding of
the Gang of Four and the J2EE patterns, it can take a fairly long time to get it.
Have frequent presentations on design patterns. Have everyone in the
group research and present a different pattern or two.

I have found that if people do these three key things (write to the Sun convention,
follow basic coding guidelines and best practices, and refactoring to patterns),
their code will be clean, readable, maintainable, readily understandable,
and will have the best chance of working and being extensible and scalable.

I know that's a lot of neat marketing words, but it's just true in my
experience.

But what does that have to do with a code review? Everything. It makes
the stuff you bring to the review. You have to minimize the tension
that quickly obtains at code reviews. You also want to focus on interesting
problems and design issues, not curly braces. Set the bar at least that high,
even when your team has some junior and some senior programmers on it,
and you'll have fun and productive code reviews, not bitchy, egomaniacal showdowns.

Setting the bar at least that high also helps move each developer forward at
an appropriate pace.

Code reviews should be something that everyone looks forward to. I love the stuff I write.
I throw half of it away (bad daddy) in refactoring, but it's fun to have interesting conversations
with smart people who care about what they do.

Code reviews should be short, focused, and frequent. What has worked for me is
30 minutes or so every two or three days, first thing in the morning for each employee.
That way, the comments from the reviews can be incorporated into that day's
work, and the reviews will not be general, but be a good learning
opportunity for one or two important things.

At the end of the week, or some similar time frame, the code reviewer
can make some kind of summary statement indicating general things that
the group can focus on. This could be time consuming, and isn't necessary however.
It could be tossed on top of some time reporting or billing tool you might be subject to.

What Code Reviews Accomplish

Doing code reviews this way accomplishes a few things:
1. It helps build the team.
2. Everyone gets individual attention and thereby learns more, faster.
3. It keeps the project focused and moving forward, because people
know they will have to always have something new to bring to the
review.
4.It helps identify parts of the code that can be abstracted up,
refactored in some way, reduced, or eliminated.

Finally, reviews have the obvious benefit of being a way of identifying
people who would really rather be astronauts and ballerinas than coders.
Let those people have an opportunity to reveal their true desires by degrees
as they fail their code reviews. Then they can be let go, into the wild, to
puruse their dreams. Now I don't think "grading" code reviews is a
good idea. It feeds a sort of pervasive macho hierarchical aesthetic which I frankly
find distasteful. But there is a clear record anyway of what sorts of things
are being found in people's code.

The architect, or whoever is doing the code review, should be using it as his
review time as well. He can ask himself, is he doing a good job of
identifying and unifying the issues within use cases, refactoring the design along the way, and
shining a light on paths for developers to take to get there.

Additionally, the architect should have his code reviewed by another
member of the team in order to protect the investment that the
organization makes in the project. You don't want code in the
repository that only one person understands. This can be a disaster.
It will also keep the architect on his toes.

Keep Your Truck Factor High
If you're the guy doing the reviews and you also write code and you're such
a genius that no one else might be trusted to understand what you're writing
when left to their own pitiful devices, then it's your job to make at least
one other person understand. Maintainable code is more maintainable when your
truck factor is high.

Robert Martin is the person I first heard use the term. Your app's truck factor
is the number of people who can get hit by a truck and the company can still maintain
the app.

Take a good, hard look at your organization. What apps do you have with a truck factor of one?
Get pair programming going, even if you hate XP and adopt no other practices, and get your
truck factor up on your apps. Code reviews help keep truck factors high.

Code Reviews and Contractors
For contractors, there are somewhat different rules. If you have contractors writing
apps for your company, you've got to have their stuff reviewed in some regard. You can't
just accept the app. You have to accept the source.

Have the aim of code reviews for contractors be conforming to the spec
and making sure that the reviewer is ensuring durability of the design
in a more general way. This is not a learning experience for the
contractors or team building experience. It is clear and simple
protection of your investment.

These reviews needn't happen in person, and shouldn't. It would be a sort of enormous
waste of money and time and wouldn't be any fun. Contractors should be given a
branch of the repository or some similarly locatable place, and your
team should review that code. The architect should review the code to
make sure that the final product will incorporate well with the common
architecture of SRPMIC. But the real code review can be done by other
members of the team, so that they get used to reading code for
potential performance problems, deadlocks, general strangeness, and so
on.

I've seen a lot of projects where contractor code goes into production, and even they don't
understand the code they committed, because they don't even understand the language it's written
in (Java), because they didn't write the code. Some other guy (a previous customer in many
cases) wrote the code and it went to the big database in the sky and they start the copy and
paste machine and they're off like rabbits.

So, there are two kinds of code reviews with two different purposes. They're both crucial in
my view to your overall success.

September 01, 2005 in Articles | Permalink | Comments (0)

My Photo

Recent Posts

  • My Upcoming Speaking Schedule
  • Service Design Review Checklist for SOA Governance
  • 10 Ways to Beat Writer's Block
  • Moving Main Blog to Cassandra Guide
  • A Literary Life: Our Book Reorganization Project
  • Talk Abstracts for Business & Technology Summit 2009 in Bangalore, India
  • 97 Things Every Software Architect Should Know on Kindle, iPhone, in Japanese
  • Using SOAP Faults and Exceptions in Java JAX-WS Web Services
  • Recipe for the Perfect Margarita
  • Towards a Rhizomatic Software Architecture
Subscribe to this blog's feed

Reading

  • Robert Hanmer: Patterns for Fault Tolerant Software (Wiley Software Patterns Series)

    Robert Hanmer: Patterns for Fault Tolerant Software (Wiley Software Patterns Series)

  • Kerrie Holley: 100 SOA Questions: Asked and Answered

    Kerrie Holley: 100 SOA Questions: Asked and Answered

  • Haralambos Marmanis: Algorithms of the Intelligent Web

    Haralambos Marmanis: Algorithms of the Intelligent Web

  • John Hebeler: Semantic Web Programming

    John Hebeler: Semantic Web Programming

  • Steven Bird: Natural Language Processing with Python

    Steven Bird: Natural Language Processing with Python

Categories

  • Articles
  • Books
  • Food and Drink
  • Recipes
  • Tech Notes

July 2010

Sun Mon Tue Wed Thu Fri Sat
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

Twitter Updates

    follow me on Twitter