This Month
| December 2006 |
| 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
|
|
Thursday, December 21

There's always room for 1 or uhhh 3 more!
by
Joseph Reddy
on Thu 21 Dec 2006 11:49 AM CST
Along with the fantastic OO heuristics found in Arthur J. Riel’s OO heuristics book and the many others scattered about in good OO analysis and design books, I will dare add 3 more to the list. I assume the list can go on and on as different environments that we work in and different application requirements can spawn new ones or variations on an existing theme.
I submit to you these three more heuristics…
- Do not allow invalid business objects to be instantiated
- Every method on an object should always work
- Be explicit in your naming when an optional property/attribute exists.
Do not allow invalid business objects
A constructor should set every property required for the object to be complete, or valid. Often by convention from years of building procedural code with structs, or working with classes without constructors this less-than-OO trait is carried on. Developers create classes and then provide gets and sets of the data. As always, this heuristic is clarified with the word “should” since we can always find exceptions. However, that’s what they should be, exceptions, not the norm.
Benefits
- Objects could never be accidentally used when incomplete.
- No business object has to check itself for validity before doing work (its most important job).
- Developers forced to think why they would need to expose an object’s data.
Drawbacks
- As long as there are Admin User Interfaces we often need to expose attributes(see footnote on this at end of blog entry)
- Developers forced to think
Side Note
I often carry this further and only allow one other class to call the constructor. I often employ the concept of a factory (this is not GOF’s Abstract Factory pattern) but rather a factory that knows the 10 ways the object is built and often knows about the data access layer. This layering further separates the class from things that have nothing to do with its business.
Every method on an object should always work
This should translate to the practical developer as “Try to make sure every method on an object always works.” Consider this example from Microsoft…
The old ADO Record Set object violated this heuristic. If you called MoveNext on the recordset when there were no more records, it bombed. The new ADO.Net Data Reader’s interface is better in that when you call the method to move to the next record it returns a boolean to let you know if it moved or not. This makes it clear that you need to deal with this fact without having to know about other properties of the object that need to be checked. This is a better design, harder to misuse, and creates less runtime errors.
I added the clarification that like many OO heuristics the concept is not black and white because we can end up jumping through too many hoops and over-complicate things if we try to apply this every single time. For example, in the ADO.Net data reader class if you call Read when the data reader is closed it will bomb and I think that’s OK. Calling Read after Close is much less likely than calling Read after the Data Reader reached the end of its records which it often does while reading. Another design may fix this, but may also make the object’s interface less obvious or clunky.
Benefits
- Harder to misuse the object thus creating less runtime errors
- Explicit design rather than implicit. In other words, the new data reader design explicitly lets you know that the reader did not and cannot go to the next record as opposed to just implying it might and bombing if you try it.
Drawbacks
- A coder can take this too far and design confusing interfaces
Be explicit in your naming when an optional property/attribute exists
In the fine book Domain Driven Design the author spends a whole chapter on this subject. It applies to programming in general, but I thought I would narrow it down and focus it right on our object designs. The other motivator for me was an article I read long ago about the original Hungarian who invented Hungarian Notation. According to this article he wished people would stop using it or associating him with it because it was misunderstood by those who turned it over to the masses. His original good idea was to preface variables with what was essentially their intent or purpose. The prefix would give readers of the code a little more information to clarify things and also see indicators of what would be bad code. For example, sticking an “s” in front of “Name” does not add much value 99% of the time. However, sticking an “m”, “c”, “_” or some other indicator of scope tells us something we probably could have not deduced on our own without looking elsewhere. However, I’m not going to claim I understand what his exact intent was either.
Oops, I digress.
Within my current development group we have talked about a few naming conventions that provide useful information in this way, however, I think the “Maybe” suffix is my favorite and easiest to sell. When we name an object’s attribute that is optional we add the suffix “Maybe” to the end of it. It nearly puts an end to the common Microsoft errors “System.NullReferenceException” or “Object variable or With block Variable not set.” When reading code on our own or in a code review it is easy to spot Person.AddressMaybe.ZipCode and it throws up a red flag to the reader. When we see the word “Maybe” stuck on the end then we should have code checking for its existence first before trying to reference it. It makes referencing a null object much harder to do on accident.
JoelOnSoftware – “Look for coding conventions that make wrong code look wrong. Getting the right information collocated all together in the same place on screen in your code lets you see certain types of problems and fix them right away.”
http://www.joelonsoftware.com/articles/Wrong.html
Benefits
- Helps eliminate run time errors when an object that has not been set is accessed
- Gives truly useful information to the coder working with the object
Drawbacks
- Creates for longer attribute names
- This is a poor excuse for a drawback but I had to try to think of something
Footnote
“As long as there are Admin User Interfaces we often need to expose attributes”
This is a common argument for why we end up exposing the data behind our objects. The problem I have with it is that people treat it like an excuse rather than an issue that is dealt with as needed. I will see another developer’s object model and see that every piece of data is public. When asked, this developer will claim to abide by one of the most basic tenets of object-oriented design: All data should be hidden within its class. But when asked why every property is public he will inevitably give the excuse that user interfaces always need to see the data. The only alternative they see is adding DisplayYourself methods for every user interface the business objects are exposed to. However, this breaks a standard application design heuristic that states that business objects should not be dependent or know anything about the user interfaces that use them. (It should be noted there is a large camp of good OO developers who do just this: DisplayViaHTML, DisplayInGivenTextBox, etc) However, there is middle ground here. For starters, I would suggest this rule-of-thumb: Attributes are private until required that they not be. In other words, the default scope of an object’s attribute should not be public.
As far as user interfaces go, I think you will find that 90% of the time we expose properties so an object can be identified as unique in a list. Most of the time this can be accommodated by providing a Display method that provides a name or other concatenated string that satisfies this need. In other cases, the object’s data is dynamic and admin users are often editing this data. In this case the object’s business probably is just the management of its data. This becomes an exception rather than a rule. The only kind of business application where this may be a rule rather than exception is one where the whole business of the application is managing data, like a Contact Management application. In this case the business of the application is to babysit data. I have written before about how a common mistake is to think every business application that has a database is just in the business of babysitting data. This mistake also leads to exposing object’s data and thus breaking what is often considered “rule one” of OO design.
Tuesday, December 12

2006: The year in books – Update
by
Joseph Reddy
on Tue 12 Dec 2006 02:26 PM CST
Stop! Don’t do it!
Do not go ordering the Streamlined Object Modeling book that I had not yet reviewed in my previous post. I know it sounds good, I know the reviews on Amazon look good, but please…just Stop!
This book is a mess. The book suggests many convoluted patterns or strategies that seem to contradict each other and with no mention of benefits or drawbacks. The stuff is just delivered like it is obviously wonderful. Well I don’t get it!
There are a few good points to be made about using an object model as your primary design document, and that the domain experts should help create that document. The book also reminds developers that although objects mimic the real world they are not the real world. A person turns a book’s page in the real world, but in the OO world a page may very well have a Turn method. We need to keep this in mind before we get sucked into creating procedural code that uses dumb objects.
However, it then gives an example of making an OO peanut and butter sandwich and asks the question, “What object is used to make the sandwich?” The bread, the sandwich, the ingredients, or a Sandwich Controller. The book says the obvious answer is the ingredients. Because if we personify the objects in the first person we would apply ingredients to the bread. An ingredient would say, “I get applied to bread.” Why is this correct? Because we should think of objects in the first person as to what they do. But wait, why do we do that? Because it helps us figure out where methods should go, helps us figure out how to divide system intelligence. But wait, that’s no better than saying distribute system intelligence alphabetically because that will help you figure out where logic should go.
To make matters worse, later in the book the authors’ suggest an example of distributing intelligence in regards to a Document that can be nominated for Publishing by a Team Member. OK, according to what I have learned so far I should think of the objects in the first person. I am a Team Member I nominate Documents. (I am an ingredient I apply myself to bread.) I am a Document, I get nominated, (I am bread I get ingredients applied to me). OK, I think I see it. Obviously the Team Member should have a method called Nominate that takes in a Document to be nominated. Wrong! Because in this chapter the book states that the object being acted upon should be the Director, the one with the system intelligence. So the Document should have a Nominate method and take in a Team Member as an argument…..obviously. The book then lays out a diagram that shows both objects having the method so they can both check their own business rules regarding the transaction…or something like that. I was having trouble seeing through my headache.
This book has been too frustrating. I crawled up to chapter five and then started skipping to the next chapters looking for justification and drawbacks (something every pattern should provide). I’m done with this book.
Monday, December 11

Project Autopsy: The Import Application - Part 3
by
Joseph Reddy
on Mon 11 Dec 2006 03:39 PM CST
18 months later
You may ask why I think our import application was over engineered if it is in production and seems to be working. Well besides the fact that I find it scary to open up for refactoring, consider this. It has been in production for 18 months now and the users have never imported anything other than an Excel spreadsheet. That’s right, so if I want to refactor the reading of data I have to deal with code that has never been used. I wasted time. It turns out that even if they get a CSV file they open it in Excel so they can read it and deal with it more easily anyway. Also, after 18 months, guess how many multi-tab Excel spreadsheets have been imported? You guessed it….zero. So what a waste it was to create two layers of data which doubled the number of classes and created looped processing, etc, etc, etc. Also, after 18 months, how many times has a user imported a partial sheet, exported the bad results and imported the data once it was fixed? You guessed it again….zero! In 18 months can you guess how many times we had to audit the result of an imported file, you know see if it was imported or had an error? I know it is hard to believe, but zero. Now granted, auditing data is like insurance, it sounds dumb until you need it. But we should clarify what we need. Do we need to know if a file was imported or had an error, or do we just need to know it was imported successfully? And what about our added subsystem for tracking system processes…has that been used? No. In fact, we found it was too much a hassle to redo the data tables to add another column for processing data or it required further design discussions that never happened. So the import stuff has still got this tangled up inside it though it is useless complexity. What a mess!
We often forget that aside from programming we do design and analysis. Further analysis of our requirements should have produced a much simpler design that imported Excel spreadsheets from a single tab. Updates to the system that have been suggested by the users in the past 18 months probably would have been completed by now as the system would be much simpler to deal with.
So what now? I’ll be thinking about that, and will get back to you in part 4 of this series. Right now I am leaning towards throwing excess code away so we can start from the place we should have started at 18 months ago… a much simpler design.
Tuesday, December 5

2006: The year in books
by
Joseph Reddy
on Tue 05 Dec 2006 08:28 AM CST
Like any other conscientious developer, I want to make a continual effort to make myself a better developer. To that end I make sure that I am always reading a book that can help in this never-ending pursuit. In an ideal world I read a few pages every morning, however, at best I tend to average one chapter every week. The end result is that I get in about 4 to 6 books a year. For what it’s worth, here’s the list of books I read this year with brief summaries and my recommendations.
The Pragmatic Programmer: from journeyman to master
Andrew Hunt
David Thomas
As you can imagine this book makes the argument that we need to be as pragmatic as possible when developing software. In other words, we need to be practical, realistic, sensible, etc. I spend a lot of time in my blog blogging about applying solid OO practices, but at the same time trying to be realistic and sensible in the application of these practices. Like many books, I thought the concept was taken a bit too far to where the practices suggested actually become impractical. I found this book to be full of good bits of advice though, some bits better than others. Some of my quick favorites include.
- Design and code in your user’s language
- Fix bad designs, don’t let them linger
- Use tracer bullets (you’ll have to read the book – essentially – grow your application instead of a big upfront design)
- You can’t write perfect code
- Don’t gather requirements, dig for them
I recommend this book
Expert C# Business Objects
Rockford Lhotka
This book is about a framework to support building business objects with a primary focus of data maintenance. In a nutshell, I don’t recommend this book, because I think too many developers build every common business application like its focus is data maintenance. Soon I hope to blog some more about discovering the focus or multiple focuses of a business application.
I do NOT recommend this book.
(I wrote a full book review in a previous blog entry).
Domain-Driven Design: Tackling Complexity in the Heart of Software
Eric Evans
This was a good book to read along with the Pragmatic Programmer. Notice above I said one of my favorite tidbits offered by the Pragmatic Programmer book was that we should design and code in our user’s language. Well this book is all about that. Domain-driven Design put a heavy influence on our business objects modeling the business and that our business experts we work with should be heavily involved in the design. I have always agreed with getting serious input from the user beyond just requirement gathering. However, I think this book made me even more aware of how involved the business experts and users should be. They should be designing the application; I just put it in technical terms so a computer can understand it. This book is the exact opposite of the Expert C# Business Objects book I read just prior to this one. However, it makes it clear that the authors are talking about business applications much like I defined earlier in my blog. Not database babysitting applications, not simple data entry applications, and not reporting applications, but a business application that requires an expert’s input so the business can be modeled correctly. The end of the book gets a bit carried away with what seems like editorial filler, but most of the book is very useful.
I recommend this book
OO Design Heuristics
Arthur J. Riel
This is a fantastic book which reads like a catalogue of Object Oriented guidelines. It was the main impetus of my blog entries about applying OO best practices to the common business application. I think this is a must-read, but it must be countered with a dose of realism. The author does a good job of pointing out that some of the heuristics contradict others and do not always make sense in a particular domain or situation.
I recommend this book
Object-Oriented Analysis and Design with Applications
Grady Booch
I had read parts out of this book a long while a go, but this year I gave it the full treatment. You see when I read technical books these days I take notes, so in effect I can review the book later by just reading the highlights later. Besides, I remember things better when I write them down anyway. Another reason this is a favorite of mine is that Mr. Booch drives home the inherent complexity of software design and the need for OO to alleviate that complexity. I wanted to stand up on my office chair and scream, “This is what I’m saying!!!” However, clearly Grady Booch does a better job of saying it.
I recommend this book
Streamlined Object Modeling: Patterns, Rules, and Implementation
Jill Nicola, Mark Mayfield, Mike Abney
A friend and I just split the cost of this book and are taking turns reading chapters so we can talk about what we agree and disagree on about the contents. It is making an attempt to define some basic core development patterns that can be used regardless of application domain. Sounds good….we’ll see.
Can’t say yet whether or not I’ll recommend this one
In the immortal words of Bono, “I still haven’t found what I’m looking for” when it comes to the OO best practices books. Most of the books provide example applications without reference to a database or even bi-products of processes that are often stored after transactions take place (results, stats, process information, etc.) I understand that the business objects should be divorced from the database, but in reality they still need to understand and deal with the real need of permanent storage. A lot of my current blog entries (Always in the middle) and upcoming ones seek to address that.
Friday, December 1

Project Autopsy: The Import Application - Part 2
by
Joseph Reddy
on Fri 01 Dec 2006 11:06 AM CST
Not only engineers over engineer things…
It is fun to design software, to dream up everything cool you can make a computer do in regards to a business. Sometimes developers get carried away and want to do a bunch of cool things…even things that are not needed, or at least not yet. We did the right thing and made sure our users were involved from the very beginning. We told them we want and value their input as they are just as much the designers of the application as we are. When we were done we had designed a system that could…
- Import Excel files, comma separated files and fixed width files
- Import data from multiple pages (tabs in Excel) in one file
- Log results for each page and file
- Started another subsystem for tracking system processes that can then be attached to records so we would know what processes created them. Great for undo and other auditing needs.
- When importing a file with some bad data the application can continue processing all the good data and save the bad data as a CSV file to be imported later as corrections are made.
When we were done designing we patted ourselves on the back and started to work on it. It took awhile but we were able to get it to import the 3 kinds of files correctly and run through the same code regardless of where the data originated from. Because we had multiple tabs to deal with in Excel we needed a concept of separate chunks of data in one import. However since we dealt with other format types other than Excel we wanted a more general term than “tabs.” So we created the concept of a Dataset and then DataTables. Similar to Microsoft speak for things like this. So one import has one dataset definition which then has one or more data table definitions.
We also decided we wanted to log that an import started, completed or stopped in error so we created a few more objects to handle these auditing concepts: ImportedFile, ImportedFilePage, ImportedFilePageResult, ImportedFileResult, ImportedFileResultType.
Someone pointed out that if we imported a file and it had incorrect data discovered after the fact that me might want to undo the import. We decided this was useful for all kinds of purposes so while we were building the import subsystem we would add some more auditing concepts: Process, Process Result, Process Type, Process Result Type). The thinking here is that an import would be associated with a process and every record written by the process would be tagged with a process ID. This way we could delete every record with a given process ID if we wanted thus undoing the import.
It was pretty tricky and added some complexity as you can imagine, but we did get the importer to continue right through bad data and then save a bad data file that can then be imported later on once the data was fixed in the file.
We’re done!
So does the application work? Yes, for the most part. Well, at least what the users use seems to work pretty well. This project suffered from what I preach against on many levels but still allowed to happen right in front of me. Now granted, this was more than a year ago and it definitely prompted me to be more vigilant, adamant and vocal about better OO design (hence my blog), but the truth is, I did it. I hope through my own constant reminders I do not do it again. What’s wrong with the design you ask? Nothing, all the ideas incorporated were essentially good ones. The problem is that we blatantly displayed signs of code writing hacks! Specifically, we exhibited “sign number 7 that you might be a code writing hack.” We designed the mother of all importing tools our application users could ever need…and then started writing code. Where was the lid on over engineering? It was OK to talk about the application and brainstorm on what it could do. But after that, someone needed to ask the hard questions and get the application down to its most basic necessities. I always advocate that applications should be grown by starting with the basic requirements and then letting it grow based on user input after they have been using it for awhile. What good is an advocate who doesn’t pay attention to himself?
So, this application has been in production for over 18 months now. The users have suggested some updates but frankly I rarely want to take the time to mess with all that code. It still has a pretty solid OO design, but I cringe when I start wrapping my head around it all again. There are so many aspects to the application that a user interface for managing the nuts and bolts of the imports is too big a task to ever get on my to-do list. So for now there is just a UI for importing, but not setting up a definition for an import or modifying one that exists. Granted, what is there is written pretty well, but adding the really useful stuff that we found out later was needed could have been done before our monster app was ever completed if we would have started simple.
Stay tuned for the next blog entry in this series: 18 months later…
|