Become a Better OO Architect: Thirteen Reasons for Creating a Class
I just wanted to post a little about the section on “reasons to create a class” (page 152 onwards). I think it provides some great heuristics when trying to decide how to break your application into classes as opposed to just coming up with a domain model (which are two separate tasks).
In addition to the obvious OO reason to create a class (to model a real world object like a customer, an invoice or a product – the domain modeling process), Steve suggested twelve (yes twelve) other reasons you might create a class.
The titles are his, the comments are mine.
- Model abstract objects - An abstract object allows you to improve the conceptual efficiency of your model and to simplify your code. Perhaps customer and vendor should both extend an abstract “company” handling the attributes and methods that are shared between both customers and vendors.
- Reduce complexity - One of the biggest benefits of a class it that it allows you to abstract complexity. One you have written a class with a well defined interface you can then stop worrying about how it is implemented and just use it. The quality of a class is in many way defined by how much it can simplify and separate concerns.
- Isolate complexity - Similar to the last point, if you have a complex algorithm, if you can abstract its workings within a class you don’t need to worry about the algorithm elsewhere and if there is an error or issue in the algorithm you’ll be able to work on that without affecting the rest of your code base (assuming your interface can stay the same).
- Hide implementation details - OK, so to get to twelve I think Steve is making some pretty subtle distinctions, but clearly a real benefit of a class is that it allows you to hide the implementation so you could vary HOW you access a database or file system (or whatever) without affecting the rest of your code base.
- Limit effects of change - A corollary of hiding implementation details is that should those implementation details change, the changes will only affect that class.
- Hide global data - An interesting point relating to some recent discussions in the CF world about session facades and best practices, if your global data is likely to change, you can encapsulate that change by wrapping it in a class so you can both make the interface more explicit by passing the class into the objects that require it and more maintainable by abstracting the process of getting and possibly setting the global data.
- Streamline parameter passing - One of the goals of OO design is to have cohesive objects combining functions and data. If you have a lot of parameters being passed around that is often a code smell suggesting that some refactoring might be in order to better define your objects in a way that keeps the functions and their associated data more cohesively structured.
- Make central point of control - A single file cfc, mail cfc or set of DAO cfcs make it much easier to handle changes in file system, email and persistence mechanism respectively by providing a central point of control for each system in a single class (or set of classes).
- Facilitate reusable code - Good class design is a necessary but not sufficient condition for creating reusable code. Most of the additional issues then come in defining more fully the preconditions, post conditions and invariants that complete the class specification (I’ll post more about the Design by contract approach down the line). Certainly good class design helps with reusability, but don’t think this is an easy problem to solve. Reusability is one of the best examples of a truly hard problem so there is no silver bullet.
- Plan for a family of programs - One of the most interesting and challenging areas of class design is in coming up with sufficiently flexible interfaces. On the one hand you don’t want to create unnecessary complexity (YAGNI), but on the other hand reusability is dependent upon understanding the variability you are likely to get across applications so you can create a class interface that is unlikely to need to vary across applications so your Shipping class can handle UPS, Fed-Ex or custom shipping rules and your Tax class can handle sales tax, VAT and GST without referencing any of them specifically.
- Package related operations - Packages are a higher level of organization and one of the reason why directory structure is an important architectural decision (as package methods are based on a shared directory for the class files). For example I put the business object, service method and DAO for each domain object into their own directory (user, product, invoice, etc.). In that way I can use package methods on the DAOs to keep them shy but still accessible.
- Accomplish a specific refactoring - Often the immediate driver for a new class is to accomplish a specific refactoring – usually driven by one or more of the other reasons listed above.
Just as interesting were his three types of class NOT to create:
- God classes - Classes that spend all of their time getting and setting low level properties of other classes are usually not a good idea. As with all OO designs, you should tell (the object to do something) not ask (the object for the data so you can do something).
- Irrelevant classes - Steve suggests that data only classes with no behavior might be just demoted to properties of other classes, but often such a transfer object is required – such as when speaking with a flex app.
- Classes named after verbs - Steve also suggests that classes with behavior but no data are generally “not really a class” but a routine or set of routines that could be added to other classes. Service classes are fine, but I do think you have to be very careful about creating UDF library style classes (although with not everything being an object in CF, sometimes it is hard to avoid this).
Anyone got any other suggestions – or disagreements with any of the advice above? All ideas gratefully received!



You can dip into this, Code Complete and loads of other great books at Oreilly Safari if you want to try before you buy: http://safari.oreilly.com/
I agree 100%. It is pithy, concise and full of great hints and tips. Code complete is still well worth reading, but the Pragmatic Programmer (of which I ended up getting two copies over the years and reading countless times) is my #1 programming book of all time!