By Peter Bell

I Don't Care What An Object Is!

I enjoyed reading Ben's series on Hal Helms course on OO programming. I didn't attend the course, and I've never heard Hal to say anything except for very smart things that I've learnt greatly from, but I do want to make a bit of a counterpoint post. From a brief reading of Bens post (and I apologize in advance if I'm misrepresenting anything Ben or Hal said), it sounded to me like there was a focus on "what would the real world object do" as a way of determining the responsibilities for a given object. If you're coming from a procedural background, that might be a useful *exercise* to get you thinking about objects, but to me it simply isn't the primary concern when coming up with an OO design.

To me the purpose of an OO application design is not to accurately model or reflect the real world behavior or capabilities of an object. There is nothing wrong with playing with that as an approach and it may help with some designs, but I don't see it as an arbiter of a good design. A good OO design is one where behavior and data are appropriately encapsulated, where the reasoning behind design decisions is consistent and easy to understand, and where (most fundamentally) the application will be easy to maintain with good encapsulation of what is most likely to vary.

A good OO design for a given use case is highly dependent on the technical environment and the parts of the technical system that are most likely to change. To try to design ideal objects, to me is YAGNI. I'd rather suitably apportion functionality between class files based on heuristics like the single responsibility principle, maximizing cohesion and minimizing coupling and encapsulating that which is currently most likely to change. As such, I would argue that the "best" design for a given OO app is highly dependent on technical requirements and what's most likely to change in those technical requirements and to try to write an OO program that isn't technology aware is like trying to design a car that runs like a horse.

I am not saying that there is not value in the "ontological approach" of "what is my object". I *am* suggesting that while that may be useful, it is definitely not the final arbiter of good design. The final arbiter of good design is how elegantly and maintainably you've implemented the technical requirements. Object oriented programming is a tool to make your applications more maintainable, nothing more, nothing less.

Just my 2c.


Good reality check. The discussions around Ben's daily posts have been as illuminating as the posts themselves. I think that taking the real-world approach as an initial cut at modeling OO design can specifically hit this point from your post: "[A good OO design is one] where the reasoning behind design decisions is consistent and easy to understand". If a set of objects are modelled in way that at least somewhat closely resemble behaviors in the 'real world', then I think it becomes much easier to explain what they're doing, why they're doing it, and which object should logically do new stuff when it comes time to enhance the application.

So, not disagreeing at all, just noting that I think your point on the consitency and ease of understanding is certainly a key, and that one way it can be achieved is to couch design in terms that 'make sense', so to speak. Final implementation, as you note, must always also take into account the constraints of actual business need, schedule, cost, etc.

# Posted By Jason fisher | 10/27/08 10:16 AM
Peter, I think you are right on with this one. I was thinking the same thing when reading Ben's posts.

I find that many of these sort of high-minded abstractions tend to fall away once you start actually sitting down and writing code. As you say OO is all about code maintainability and ease of development, and if you find yourself getting away from that, to try and meet an abstraction, a second look is needed.

I find myself now coding for syntactic sugar more than anything else, i.e., creating methods based on how easy it is to tell what's going on from the resulting code.

For example I was working on a permissions system and decided I wanted the code to look like this:
<cfif person.can("create","person")>
<!--- if person has create permission for another person, run code --->

The person object will already have a permissions object as a dependency. The "can" method then negotiates the permissions and returns boolean based on the person's access levels to the given resource.

By starting from that point and working backwards, if you will, I was able to come up with a pretty nifty permissions system that is easily extensible as the application develops.
# Posted By Josh Nathanson | 10/27/08 2:01 PM
BlogCFC was created by Raymond Camden. This blog is running version 5.005.