Skip to main content
Ben Nadel at cf.Objective() 2014 (Bloomington, MN) with: Clark Valberg
Ben Nadel at cf.Objective() 2014 (Bloomington, MN) with: Clark Valberg ( @clarkvalberg )

Hal Helms Teaches Me Some Object Oriented Programming

By on
Tags:

For those of you who know noticed my blog silence last week or my extensively delayed responses on emails, it was because I was down in Florida doing some consulting work with Clark Valberg and Hal Helms. The days were long and productive, but unfortunately, left me very little time to check my email or read up on CF Bloggers. While down there, I got to spend a good deal of time with Hal Helms, who, until recently I had only known through community elements such as "Helms and Peters Out Loud" and his Occasional Newsletter. Hal Helms is insanely smart, so I tried to take advantage of the time by asking him all sorts of questions about Object Oriented Programming.

For months, I have been trying to break into the Object Oriented Programming (OOP) world; while I feel that I have come a long way, it is obvious that there are some huge mental barriers through which I've not been able to break. Hal helped break one of those babies down. During a conversation with Hal, he dropped a pretty awesome nugget of information in my lap - he stated that Domain Models are supposed to be "Idealized" versions of real word constructs. I was not familiar with the concept of "Idealized Objects", but basically what it means is that our domain models have behaviors that don't necessarily reflect what their real-word equivalents would have, but do reflect the behaviors that we sort of wish they had (if we lived in an ideal world).

As an example, we explored the idea of Dollar Bills that travel around the country. I am sure that most people have come across a Where's George dollar whose journey you can track online. I brought this up because to me, dollar bills are not intelligent objects; if I were to have a Domain Object that modelled the dollar bill in the Where's George system, my instinct would be to just have getter and setting methods for things like serial number and date printed. If I wanted to get an array or query of locations at which the bill had been tracked, I would have passed the dollar bill instance off to some DollarBillService that had a method like GetDollarLocations().

The problem with this, as Hal Helms pointed out, was that we are not getting any of the benefits of object oriented programming. By only having simple property getters and setters on the dollar bill object, we have nothing more than a bloated struct. Now, I've heard the whole speech about "anemic domain models" before and it never really affected me, but Hal also said, and here's where he really hit a chord, the dollar bill shouldn't be a dumb object as it is in the real world - it should be an "idealized" object; meaning, it should know about and be able to report on where it has been. As such, the idealized dollar bill itself would have a method like DollarBill.GetLocations() that would return an array or query of locations (most likely an array of "Location Objects").

I think the concept of Idealized objects is going to make things easier for me. For the longest time, I think I was so hung up on modelling the real world that I ended up creating object-oriented procedural code, which, as some of you probably know, has all the overhead of OOP and none of the benefits. I still have a long journey ahead of me, but I think Hal definitely got me a lot closer with the personification and idealization of objects. Thanks Hal!

While down there, I also got to sit in on an awesome pod cast in which Clark Valberg and Hal Helms discussed the design of beautiful things. Definitely an interesting conversation. But more on that to come, I am sure.

Reader Comments

20 Comments

Hal has a way of doing that. He just casually switches the way you think about things.

I took his Java For ColdFusion Programmers class and we spent most of the time on modeling. It totally changed the way I model applications.

15,674 Comments

@Matt,

Yeah, from the bit I experienced, and pretty much everything I have been told, Hal is a superb teacher. I almost went to take his FuseBox training, but the funding fell through.

153 Comments

It's funny you post this ... because I was just a few days ago realizing how I've moved in the exact opposite direction that you are describing. That is, I find that more and more of my code just passes around structs -- no methods or anything else intelligent, just data.

Interesting.

5 Comments

Ben, thank you for your kind words (and look for that check in the mail.)

I was speaking with Brian Kotek earlier today and I used a favorite quote: The greatest obstacle to knowledge is not ignorance, but the illusion of knowledge.

There's a shortcut to knowledge--not a shortcut, really, but an alternate path: learning the buzzwords. I admire greatly that you refuse to walk down this path that so many others have embarked on.

I've told the story many times of my beginnings as a woodworker. For a full year, my boss would not let me touch a power tool. I confess with shame that many times I was very angry with him: it was humiliating that others could use any power tool or machine appropriate while I was reduced (as I saw it then) to working solely with hand tools.

I couldn't then appreciate my good fortune. His actions caused me to learn about wood and about tools in a way that I never would have otherwise. Later, when I was able to add modern machines and tools to my repertoire, I never became dependent on them and I was able to make things that went far beyond the limits of my machines. But I first had to learn, through discipline, the value of real knowledge.

There's an old song with the line, "I can see by your outfit that you're a cowboy..." But clothes, regardless of what the design industry would tell us, do not make the man -- and learning buzzwords and how to use automated programs don't produce the kind of programmer who can build beautiful, robust systems.

I have retained a great deal of the "craftsman mentality" in programming. And when I teach others, I hope I can empart some of that sensibility to them so that they can (as you have) first learn deep knowledge before using automated tools that can accelerate (but never substitute for) the implementation of a good design.

167 Comments

What a ridiculously inspiring post.

I'm so glad I read it.

I imagine that someone well-grounded and foundationed in woodworking/programming would be exponentially-more qualified and capable of even REDESIGNING and REARCHITECTING those power tools / systems that they're so independent of in the first place.

Thank you guys.

9 Comments

Ben,

Thats exactly the road I went down with Transfer and decorators. The transfer object models my data very simply and handles all getters / setters, and the decorators perform actions in my 'ideal world'. So, my user object has a getInvoices() decorator that returns invoices, placeBid() that submits a bit as the user. Anything that the object which the Transfer config represents could do, I hook as decorators. I have found it quite effective and easy to manage like that!

Chris Peterson

15,674 Comments

@Hal,

It was a pleasure learning from you.

@Chris,

When you say Decorator, just so we are all on the same page, that is an object that wraps around another object, right?

66 Comments

@Rick: I think you're seeing the power of encapsulation, Rick. Structs/hash maps provide that. And there is an even greater level of power available when we begin to see objects not so much as storers of data, but as providers of services. In Java, when doing design, we start with interfaces, which provide method signatures but no variables, thereby encouraging us to answer the fundamental question: what should this object do?

9 Comments

Ben

Actually (not sure how much you know about Transfer, so I will give you the speil)

Transfer uses an XML definition of your database model to auto-generate a cfc for you with all methods (get / set, plus many more)

A decorator allow you to inject custom methods into this auto-generated object, or even override auto-gen'd methods with your own, while still accessing the underlying methods (a good use for this is a validator or setting a default, write a custom setUserName, check for profanity, and if none is found continue on with the autogenerated setUserName function)

The decorator is simply a CFC you refer too from your Transfer XML configuration, from which you can use all the built in functions that Transfer autogenerated for you.

Hopefully that made sense and was not too rambling?

Chris

66 Comments

@David: You're so right, David! Once I began to use power tools and machines, I was able to create both my own hand tools (such as a curved-bottom plane) and my own machines. The old apprentice system, by initially limiting the student, had the power to eventually create masters.

66 Comments

@Chris: Shudder...

I truly do not want or mean to be snarky, but that idea of dumb objects with decorators is anathema to my understanding of OO. The most basic question to ask (and it's rarely asked in my experience) is this: What is the essential nature of this object? The answer to that will guide you to craft a really robust system.

9 Comments

Hal

Well, the transfer claim to fame is the automated creation of those object from XML, its ability to work across many different databases, and the fact that you dont have to write a stitch of SQL for the majority of your get / set values (possibly a small amount in decorated functions, but for the most part I have made use of Transfer itself). It also provides programmable caching and other goodies I have not yet explored fully =)

Can you explain your comment any further? As far as Transfer is concerned, the object is returned as a single entity with all functions combined, which I have found very appealing and useful thus far and I thought this fit right in with what Ben was blogging about?

Sorry to be a pain!

Chris

15,674 Comments

@Chris,

I have heard of Transfer many times, but I have never used it. Sounds quite beefy, especially that you can access underlying functions even when other functions are overriding them. I guess that is a decorator. It would be cool to see how it wires all that stuff together. I will have to look into it sometime, after I get more comfortable with OOP in general.

66 Comments

@Chris
Sure, Chris. I have a couple of problems with this idea. First, there appears to be a forced tight correspondence between the object model and the data model. I know Ruby on Rails does this as well with the Active Record pattern. I think it's a fundamental mistake, stemming from the fact that in the procedural world, programmers look to the data schema to provide a structure for their application.

In the OO world, it's the object model that provides structure to an application. Databases exist solely for object persistence. In fact, in a perfect world, we wouldn't use relational databases at all; rather, we'd have OO databases (which do exist but are rarely used -- and yes, they rock).

Even in the hybrid OO/relational model (which we end up having to use), we provide a persistence layer to abstract the object from the object's data as represented in a relational database. That means that whether the data is stored as a cookie, in an LDAP environment, in a flat file, in a spreadsheet, in an OO database, in a relational database, or by some other mechanism, that mechanism has no bearing on objects. An object (even a non-aggregating object) might have its data spread across mulitple tables -- it might even get its data from something like a web service).

This is VERY important. Objects are NOT merely collections of data. That's what structs are -- and adding getters and setters to a struct still doesn't make it much of an object -- certainly nothing that will get us the kind of power that real OO can give us.

Matt can tell you that in the Java class, I refused to get into database storage of objects. DAOs and gateways work just fine, but their implementation is fairly boring stuff. I understand the desire to automate a bunch of boring work, but if that automation comes at the price of holding the object model hostage, that's just too high a price to pay, as far as I'm concerned.

As an aside, why do we need separate getters and setters for each instance variable? There's a story told about a consultant who did some work for an artillery unit of the U.S. Army. He observed that after each shell was fired, the soldiers waited several seconds before loading a new one. Was this because the gun overheated? No, he was told. He tried several other reasons, but no one seemed to know exactly why they did it: it was just part of their SOP.

Finally, the consultant found the answer: the SOP had been developed when artillery pieces were drawn by horses. The wait had been instituted to allow the horses to calm down after the firing.

Now, this is probably an apocryphal story (it sure sounds like it), but the point is a good one and, I believe, points to the common practice of having separate getters and setters for CFCs. This SOP came out of the Java world, where separate getters and setters are required because of the strongly typed nature of Java. But lacking deep knowledge, people imitated what was appropriate to Java, but made little sense in ColdFusion.

[more in a bit...]

54 Comments

I just thought I'd chime in for a quick comment to support Chris's argument on this stuff.

I agree with your points Hal, dumb objects are satan personified in a programming concept, and unfortunatly is somthing that a great deal of us fall victim too when we're first getting involved with OOP, however, I do feel that somtimes these sort of dumb objects are unavoidable but by creating a dumb object will always allow use to easily extend them in the future as the business needs grow.

Aside from that though, Chris isn't advocating dumb objects in any way, I think that ORM's and the Decorator pattern are very widely used in a whole bunch of languages and quite a common place thing.

The idea is that Transfer creates the dumb objects for you on the fly, saving the really borring task or writing them yourself, aswell as having all sorts of nice dependancy persistance functions in them too (no more writing DAO's wooooo!).

It then provides you with this great mechanism via the Decorator pattern to be able to add 'rich' functions to those base objects, so they are no longer 'dumb'. Transfer allows you to stop thinking about the dumb objects and just concentrate on making them 'idealized' without getting bogged down in the monotony of creating mutators or CRUD methods.

One of the key features of using an ORM is that it allows you to focus on making rich objects, building that really nice business logic which we all love being creative with.

Does that make sense? it just seemed from those last posts that you werent too keen on the whole decorator idea, for me it always seems to have made good sense.

Rob

66 Comments

OK, so on to the subject of decorators. The idea behind the Decorator pattern is that you can add functionality to a single object. They are helpful because you can add functionality at runtime rather than compile time (through subclassing or aggregation). My preference for this situation is to use mix-ins -- something I wrapped into my base "Object" class that all components (that don't extend something else) extend.

As I see it, the reason for the transfer object/decorator issue is to save grunt work -- and that's a noble goal. But, again, the part that saves work only works if I have a (too) tight correlation between object model and data model. That's something I just can't accept, personally.

I appreciate that not everyone shares these views. The part I find most distasteful is that this "pattern" is urged on so many programmers new to OO who perhaps don't know enough to realize the compromises they're making. It reminds me so much of those woodworkers I worked with who knew (only) how to do what their machines would allow them.

I'm sure there's a place for that kind of woodworking (and programming). I realize I'm a minority voice, but there are times when those of us in the minority need to warn the majority that what they imagine to be a light at the end of the tunnel may well be an oncoming train.

9 Comments

Hal

While I am by no means an OO guru, or even experienced on the subject (as CF is my first real language other than VB, Basic, and a bit of scripting / proprietary languages), I dont see the difference between a mixin (an extended base component) and a decorator (a specific extention for a given component), and honestly in my mind the decorator is easier to visualize and think through, as you have a single place to look for any functions attached to your object.

If you really wanted to have a base extended class, you could do that with decorators as well (then you would have a mixed-in decorator for all objects, that would have common mixed functions as well as specific Business Object functionality). I have all of my decorators currently extending a base class, with any company-specific logic in the higher level (extending) decorator as to override any base software packages.

I will be the 1st to tell you that much of what you said goes a bit over my head, and even through a lot of research online I still feel that a lot of what I do with Model-Glue and building good software design patterns is just monkey-see work on my part without any deep understanding. I often wish I had someone here who knew coldfusion more than I do, its hard to absorb some of the concepts you are trying to share via a blog post!

Thanks for your efforts thus far =)

Chris Peterson

66 Comments

Chris, I wasn't lobbying for a mix-in v. a decorator, but rather pointing out that both these solutions are for ways of dealing with a single object at runtime rather than with an entire class of objects at compile time. I think that having to resort to either of these solutions for ALL members of a class points out that something is wrong with the class itself.

And I agree: a blog post isn't a great way to really discuss something in depth. One thing that really impresses me about Ben is that he has gone against the tide of, as you say, monkey-see/monkey-do and insists on processing information into a deep understanding.

That's a harder place to stay in: there's no assurance that you'll ever "get" it (whatever "it" is); you may very well get it wrong and expose yourself to ridicule; and you don't have the support of lots of like-minded people all assuring you that you're right (whether one is is another matter). This last part shouldn't be underestimated in importance: we all like to have others approve of us and our ideas.

What I have seen (and I'm definitely not meaning to imply anyone on this comments list falls into this) is that the need for security through identification with others can short-circuit the sometimes slow, sometimes painful process of integrating all this "stuff" into a clear, consistent theory.

Then, we may get to the point where, like the young physicist whose work was being evaluated by the Nobel Prize-winning physicist, Neils Bohr, we can be told: "We all agree your ideas are crazy. The question is: are they crazy enough?"

;-)

9 Comments

Indeed!

I think for the most part, if your idea's and methods

a) make logical sense

b) are documented or methodical enough to be understood by others

c) are relatively easy to manipulate and agile, and

d) they work!

you could call it the *right* way to program. =)

If anyone with a 'deep understanding' of OO in relation to Coldfusion ever wants me to buy em a beer and are in the Grand Rapids / west Michigan area, give me a hollar at override11 at gmail dot com!

Thanks Hal and Ben, I love the discussions on here.

Chris Peterson

15,674 Comments

A most excellent discussion. It's a lot to absorb and I am not sure that I will understand all of the points anytime soon. But, what it reaffirms for me is the idea that I need to really understand OOP outside of frameworks; I think that trying to learn OOP through the use of a framework will not only give me a false sense of knowledge, but will potentially give me misinformation as to what is considered "best practices".... not to say the frameworks are bad, they are just not learning tools.

20 Comments

It would be a mistake to imply that Transfer's decorator facility creates or requires any coupling between the data model and the domain model. Under particular circumstances, where the two happen to be very closely aligned, you *can* use a transfer object or decorator as a domain object, but this can't be considered the general case.

In a basic CRUD application, the data model basically is the "domain" model, so the special case becomes very handy indeed. We just need to be aware that we may be unable to reuse that domain model if we need to build a more sophisticated app on top of the same data store.

32 Comments

whoa! Ben and Hal, you just blew my mind. I need to go to rethink OO. Glad I saw this before I got too deep. So, Hal, do you have some recommended reading for learning OO?

CoolJJ

66 Comments

A really good introduction to the subject is David Taylor's Object Technology: A Manager's Guide. David is a really smart guy with the unusual gift of making complicated things understandable. He reminds me of Bertrand Lord Russell as far as that goes.

And anything written by my friend, Meilir Page-Jones, is well worth reading. In addition to being super-bright, Meilir is very funny -- and that's saying something when writing about technical subjects. His book on Fundamentals of Object Oriented Design in UML is a book I keep returning to -- and keep learning from. I just saw another one of Meilir's on Amazon: What Every Programmer Should Know About Object Oriented Programming. I haven't read it yet, but I just ordered it!

Those are a great start. I think the biggest impact for me was studying at the Palo Alto Research Center (PARC). I was just learning about variables back then, so I was very open to their ideas that programming is very much a creative endeavor, similar to music composition.

I've said many times that OO programming might also be called Applied Philosophy. So, weird as it might sound, any books that help stimulate the critical mind can be very helpful. (Obviously, these books won't teach you about algorithms, but they can teach you to think deeply about various subjects.) The book, Goedel, Escher, Bach: An Eternal Golden Braid inspired me when I first read it and I've revisited it several times.

If I could only boil things down to a single bit of advice, it might be this: Don't Believe Everything You Think. Oh yeah, and one other: Don't Rush To Code.

Some of my designs suck at first. They feel clunky, they're not integrated, there's nothing "commensurable" about them, a trait much prized by philosophers. Yes, they will "work" in the sense of meeting the immediate needs, but I've done this long enough to know that a shallow design lays the groundwork for bad stuff in the future.

While it's never fun to find that I have to throw away hours of thought-work, the payoff comes when the design does cohere and there's that aesthetic appeal that, yes, this is a beautiful design.

But unless you're a Bertrand Russell (I'm not), that beauty is found only after a long, sometimes-frustrating, internal struggle guided by the desire for beauty.

I know this might sort a bit "artsy" for a programmer to speak thus, but it's what I've found to be true. So, I try to cultivate that inner sense for beauty by reading, talking to like-minded folks, and avoiding strident discussions about the "right" way to do something.

And one other thing: Clark Valberg and I often will pick a domain out of the air and think about how we'd model it -- very much the sort of thing Ben talked about with the Where's George problem.

That's a long answer to a short question! Hope it helps a little.

33 Comments

I'm currently (slowly) making my way through Domain Driven Design by Eric Evans. Forward is by Martin Fowler, auther of Patterns of Enterprise Architecture; another excellent book. DDD is a pretty intense book but I'm enjoying it so far. There's a 'diet' version available for free in infoQ.com if you're after the gist of it in a hurry.

George.

1 Comments

I agree with your points Hal, dumb objects are satan personified in a programming concept, and unfortunatly is somthing that a great deal of us fall victim too when we're first getting involved with OOP, however, I do feel that somtimes these sort of dumb objects are unavoidable but by creating a dumb object will always allow use to easily extend them in the future as the business needs grow.

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel