Halhelms
SIGN UP FOR MY NEWSLETTER

www.savorgold.com is top on wow gold and runescape gold and World of Warcraft gold provider list for trusted services. Their reputation seems to growing by the minute, which isn't surprising because they are one of the safest sellers of Gold. Delivery speed and customer service are very good. They aslo are giving some bonus items depending on the amount of gold you purchase.

 
 
Halhelms

Recent Comments

Recent Entries

RSS

Thoughts on Object Oriented "Purity"

Ben Nadel recently wrote a blog post on his disillusionment in his attempts to "get" OO. His conclusion was that he was going to have to give up on "object purity" and accept a more practical OO approach. Based on the comments on his post, a lot of people are feeling this.

Ben is a very smart guy and a great programmer, so what does it say that Ben is having such a tough time with OO? First, let me express my empathy with people who are trying to learn this stuff. Sean Corfield made the point that learning OO is hard. That's both very true -- and very unwelcome. And the point Ben is at is one that perhaps we all reach: I'm just going to do something that works.

Let me, though, offer an argument that the problem is not in either Ben or in OO, but in our perception of OO. I'm fond of asking the question, "What is an object?" I don't ask it to be deliberately philosophical or obscure, but because it's a very important question to find an answer to.

One very bad answer is that an object is the heart of a religion called "OOism" that promises its adherents technical salvation. Ben is finding out just how hollow an answer this is.

So what is an object? Let me offer a slightly unusual answer: an object is a data type. Just that. Similar to an array or a Boolean. The main difference between objects and other data types is that objects have more behavior associated with them than we're used to in more standard data types.

This answer is, I believe, important because it points to where we should -- and should not -- use objects. If your entity has significant behavior that should be associated with it, objects are a great solution.

In our world of technology, we're all familiar with the technology du jour. Remember how web services were going to "change everything"? Well, I don't know about you, but they haven't "changed everything". I use them when they're...useful.

The same is true for objects. Led (or, perhaps more accurately, misled) by false perceptions, some have tried to make objects the solution to all things. Need information about customers? Instantiate a bunch of customer objects, wrap them in a collection (an array will suffice, but a collection class preferably), then loop over them, calling the appropriate getters on the objects.

But if objects are data types, we must ask ourselves, "Is this the most appropriate data type?" We can force fit anything into an object, just as I once saw a developer who chose a decimal number for zip codes. The first five digits went to the left of the decimal point; nine-digit zips had their last four numbers as the decimal portion. He was not dissuaded from this scheme despite the fact that zips that begin in 0 are particularly ill-suited for numeric types.

So, what's the best data type for a information about customers? In many -- perhaps most -- cases, we have a data type that works very nicely: ColdFusion's query. It's concise and doesn't have the considerable expense of creation that objects have.

"But that's not real OO!" it will be argued by some. No, it's not. If that's what Ben (and others) mean by their decision to forgo "object purity", I applaud their decision to eschew objects. But, too often a poor compromise is made: the anemic data model. Here, entities are fashioned as objects, but they have little or no behavior (other than, perhaps, getters and setters). This really is the worst of both worlds: the expense and complexity of objects with none of the benefits objects can provide when they're the appropriate data type.

Some wit wrote that when you use regular expressions to solve a problem, you now have two problems. That same dictum might be applied to objects -- but multiplied. When we try to take data, stored nicely in relational databases and turn it into an object, we encounter the "data mismatch problem". Now, we need dependency injection mechanisms, data access objects, gateways, services -- ugh! That's a lot of work to display and possibly manipulate/massage plain old data. It's such a problem that people end up using frameworks like ColdSpring and Transfer or Reactor to try to cut down on the sheer drudgery. You had one problem; now, you have multiple problems.

I've related before that I'm privileged to work with my colleague, Maciej. Over the past couple of years, Maciej and I have tackled some pretty intense problems and found ourselves buried in complex code. And, repeatedly, one or the other of us will stop and say, "This is getting too complicated." And guided by this sense that we've made a misstep at some point, we'll rethink the problem. In every case I can think of, we found a cleaner, better, simpler solution. Our complex code certainly looked impressive, but its complexity was a result of our missing the essential simplicity of what we were dealing with. It may be simple, but it ain't easy.

In the case of objects, I hope Ben -- and others -- will persevere. Just as arrays aren't the solution to everything, objects aren't always appropriate, but where they are, they provide expressive power and simplicity that nothing else can match. The trick is getting to the heart of things. Then, there's no question of theory v. practice; it's a matter of what's appropriate for this situation.

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
Aaron Longnion's Gravatar Well put, and thank you for this.
# Posted By Aaron Longnion | 4/2/09 8:15 AM
Ryan Miller's Gravatar The ART and the SCIENCE
# Posted By Ryan Miller | 4/2/09 10:01 AM
Ben Nadel's Gravatar Back when I was systematically trying to learn OO by starting procedural and upgrading a bit at a time, the biggest "ah ha" moment was the one I had on the first step - creating a service layer. This layer acted as an API to the business logic, encapsulating the reading and persisting to the database using simple method calls:

GetContactByID( id )
SaveContact( id, firstname, lastname, email )

This made a huge difference; suddenly, my controller was much much cleaner and I had removed a lot of query duplication.

Perhaps applications of small size simply don't need objects at all? Perhaps they just need a simple API layer? After all, if they don't have behavior or real "logic" behind them, then maybe the primary goal is just to cut down on duplication and increase readability.

... I don't know. I just feel a bit lost in all of this. I certainly don't want to have "the worst of both worlds." That's why I have been so hesitant to implement many of the things I have experimented with.
# Posted By Ben Nadel | 4/2/09 10:19 AM
Steven Brownlee's Gravatar Great post, Hal. Wish more people understood, and spoke out, about how achieving object oriented programming purity is not a realistic goal.

When OO techniques (and I am, by no means, a purist, I'm a pragmatist) are the most useful is when the complexity of the project increases.

In my experiences, the complexity of a system and the complexity of the code tend to be inversely related.

On a simple project, code can be relatively complex as long as it solves the problem. Scalability really isn't an issue.

On a complex project, code must be simple, but elegantly architected. This is where OO techniques are most useful for me.
# Posted By Steven Brownlee | 4/2/09 10:21 AM
John Farrar's Gravatar @Hal, We spoke briefly about this at CFUnited and on another site. I am delighted that the Ben seems to have launched a 'coming out' movement on people who want to learn OO but don't thing that something not written in OO is evil. We have great leaders like you and Sean (and others for sure) who are seeking to inspire learning and getting the benefit of OO. Yet some seem to cast out custom tags as the evil twin sister. Yet they configure stuff with XML (which clearly is not an object). What that means is just a little bit of consideration tells us that there are few anywhere who are pure OO. OO is a means to an end. It may be the best means or it may not be. Your post highlights that point well.
(Oh, I am KNOWN for not being 'pure OO' but let me say this... 'If you avoid objects then your tool box is missing some great tools.')
# Posted By John Farrar | 4/2/09 10:35 AM
theguy's Gravatar I do not think OO is hard, but I often find it just doesn't fit well into web development. Objects make a lot more sense as things that are created and persist over a users session. Not as things that are created and destroyed after each request.
# Posted By theguy | 4/2/09 11:16 AM
Ryan Miller's Gravatar @theguy, what about loading the objects into session memory or the session scope so they do persist?
# Posted By Ryan Miller | 4/2/09 11:22 AM
Hal's Gravatar @Ben: "Perhaps applications of small size simply don't need objects at all?" You are correct, sir. Do all applications need arrays? Structures? We know they don't. When entities are about behavior to a large degree, objects make a great deal of sense, but for a lot of things -- even some big things -- they're just not the best fit.

The reason for focusing on OO with design patterns and all is that when you DO need to use objects, you need to know how best to use them. But objects that do nothing but have properties? Isn't that sort of the definition of a struct (or hash or map, depending on the language)?

Some folks were saying on your blog that the pain you're experiencing is because CF isn't an OO language. That's not really true, BUT it is true that object creation in CF is incredibly expensive and that has an effect on how we write code. With the cost involved, I need a good reason to use objects; they're no longer the default option as they would be in Java, say.

My best advice is to really ask yourself: do objects make sense in this context? Is this the most appropriate DATA TYPE. Because when you see the choice of objects as the choice of a certain data type and you see that you have options, I think a lot of the unease you're feeling will vanish.

Hang in there, Ben!
# Posted By Hal | 4/2/09 2:22 PM
Brian Kotek's Gravatar Something that I've been struggling to understand (and plan to touch on in my OO Design talk at the cf.Objective() conference) is whether there really is such a thing as a "data-centric application".

I've come to the conclusion that I don't believe there is. Well, there is, but it's limited to a small set of applications. If you have an app that is literally NOTHING but a data management app, where you list something like users, and let people add, edit, and delete them through simple forms, then I'd call that a "data-centric application".

In those cases, using CFCs at all is probably almost useless. Some queries, a few structures, and some handler templates is all that is needed. I can't really imagine that people struggle much with something like that because it is so simple and straightforward.

But are most applications like this? Not that I've ever seen. Sure, many apps have a data management element, but it is usually there to support something larger: a store, an intranet, etc.

Which means in the vast majority of cases, the application requires SOME kind of BEHAVIOR that goes beyond just some glorified database editor. Users DO things. They buy products. They get recommendations. They pay invoices. They build social networks. Whatever it is, SOMEWHERE in the code there is actual business logic running, rules being applied, etc. And if that logic is clumped into procedural blocks scattered around the system, whether in the controller, or view, or service layer, this is where I think people are missing out on the promise and power of OOP.

If one still has an anemic domain model in cases like this, on the premise that it is a "data-centric application", I would disagree. Most people seem to have plenty of behavior and business logic, they just aren't sure what to do with it. Which, of course, brings everything around full circle: OOP excels at handling this in an elegant and flexible way. The challenge is that using OOP to do this requires time and experience to understand.
# Posted By Brian Kotek | 4/2/09 2:56 PM
Ben Nadel's Gravatar @Brian, @Hal,

What about systems that do have some behavior but are mostly data-centric. I know its hard to imagine an app that is strictly data-centric. But, I think it might be easier to imagine an app that is 90% data centric and 10% behavior.

Take, for example, a REALLY DUMBED down ecommerce system where you have a cart. For sake of argument, let's say there are no discounts or inventory logic to be considered. I can see having a "shopping cart" object as it has behavior and manipulates its own items through an API. But, let's assume that products themselves have no behavior.... would you just pass a Product "struct" to the Cart:

Cart.AddProduct( productStruct )

... or would you turn Product into a domain object and use that (again, for sake of argument, considering it has NO behavior outside of data storage).

I am just curious what your take on a situation like that would be?
# Posted By Ben Nadel | 4/2/09 3:02 PM
Brian Kotek's Gravatar Ben, the problem with dumbed down examples is that OO doesn't make much sense there. OO doesn't really shine until you get into situations that are decidedly not dumbed down. :-)

Your example is a store that has limited behavior (no discounts, no inventory, etc.) But is that realistic? Would someone actually pay a developer to build that? Even if one didn't assume that more requirements would be coming down the line, there are tons of store applications that already exist that would do this for you, and more, with almost no effort.

You can see the Catch-22 here: it's hard to see the benefits of OO until things get complex, but when things get complex, newcomers to OO aren't sure what to do.

Which means the unfortunate reality is that the only way to get to an understanding of solving problems with OOP is time, trial, and error. Reading definitely helps, but experience is really the crucible.

It's similar to learning to play Jazz. Newcomers know up front that experts can create beautiful, complex music in a way that seems almost instinctual. And that they can incorporate their music into the larger composition of a band with seemingly equal ease. But that is an illusion. People don't just "know" how to do this. It takes years of practice, experiments, trial, and error.
# Posted By Brian Kotek | 4/2/09 3:26 PM
John Farrar's Gravatar @Ben, @Brian: Yes, there are data centric applications. My first employee job years ago as a programmer was soooo data
centric. We had a call center and took orders. The order system did not (and they did not want) the system to manage inventory.
We took orders and they printed on demand the order. The order was then passed to an existing accounting system. We took
on more and more print on demand customers with the order entry system. There are many shops that use Access for this
kind of app and that is bad unless they at least move to a SQL back end. There are other examples but these examples
are not typically what we call "Enterprise". These are the SOHO/SMB applications that pepper the landscape of 'real
business apps' the world over. Perhaps you are right that more time in code is spent on apps that are not data
centric, but Ben is right that we need to consider this type of application also.
# Posted By John Farrar | 4/2/09 3:35 PM
Ben Nadel's Gravatar @Brian,

Ok, take something like an Address object. Even within a large, complex application, you might have address objects that have no behavior. A customer might have 1-N addresses, a company might have an address. A shippment might have an address object. But, I think it's easy to imagine a system where the address itself doesn't have any behavior.

In a case like that, which I think is more realistic that my previous, would you store address information in an "object" or a struct?

I am just trying to see how situations get handled where we are dealing with "Data centric" portions of a "behavior rich" system.
# Posted By Ben Nadel | 4/2/09 3:39 PM
John Farrar's Gravatar P.S.
Could you turn the word wrap on in the comment tool? When a line is longer than a entry box it wraps but only after the typing goes off the right side of the screen. Sorry about that last post. Also the text of the posts are center aligned and it made that last issue even worse. Sorry again.
# Posted By John Farrar | 4/2/09 3:40 PM
John Farrar's Gravatar @Ben,
My suggestion is to make sure the application can grow. This means we still do the objects as a data interface... but we can do simpler data objects. If the interface is the same for scaling the application then it doesn't matter that much. I particularly enjoy DataMgr and how you can pass all the form data to the object as a structure. Then the data object takes care of tossing the information from the form to the database. For BIG applications this may not be pragmatic but in service to SOHO/SMB companies this type of approach can make applications build out faster and something that keeps the project in the black, the customer price down and the developer profit up. (And have not had any of these small apps come back on our company to date as bad design after the fact.)
# Posted By John Farrar | 4/2/09 3:46 PM
Steve Brownlee's Gravatar @Ben: Re: Address Object... These are the kinds of things you learn with practice, time, and making mistakes. A beginner, wanting to be pure OO, would make an Address object and inject it into the Customer object, and the Business object, and create all the corresponding overhead.

Over time, though, you learn that dependent information like that (which has no inherent behavior) is best left as a property of other objects.

So a developer might start off creating an instance of a Customer object, then inside the get() method, create another Address object (or multiple ones) and then inject it into the .address property of customer.

However, there is no need for this, when you can simply join in the address information in the SQL command and handle it inside the Customer/Shipment/Company object(s).

Well, at least that's how I'd do it....
# Posted By Steve Brownlee | 4/2/09 4:06 PM
Ben Nadel's Gravatar @Steve,

RE: "Over time, though, you learn that dependent information like that (which has no inherent behavior) is best left as a property of other objects."

... are you saying that in the context of a something like a contact, the city, state, zip, etc. fields would just be a property on the contact itself?

contact.city
contact.state

... etc?
# Posted By Ben Nadel | 4/2/09 4:32 PM
Brian Kotek's Gravatar @John - I really just mean that the issue of OO doesn't really enter the picture on a purely data-centric application. If I were building such an application, I'd just generate the whole thing from a DSL or using scaffolding. It's not like you need to worry about custom behavior or anything. So my point is that anyone with an app that is truly just a database management application shouldn't be worrying about OO design in the first place. The overhead and complexity just aren't worth the limited (at best) cost of applying OOP.

@Ben - On your Address example, I personally would model Address as a separate object and associate it with whatever objects that need it. I really wouldn't want to try "mixing and matching" CFCs with structures. That would make things even worse IMO.

There is a benefit to having it as it's own data type since it leaves the door open for polymorphism (you might have an InternationalAddress later that requires different properties), and also leaves the door open to add behavior later. So it's not necessary that *every* object have behavior. But on the other hand, if most of the objects *don't* have any behavior, I'd have to question whether using OO is the best option.

Also keep in mind that the question isn't so much whether the objects have behavior, but whether there is behavior in the system that is not in the object but should be. If someone has hundreds of lines of code in their controller, view, or service layer that "does things" with the objects, but the objects themselves have no behavior, it's indicative of the anemic domain model that Hal mentioned earlier.
# Posted By Brian Kotek | 4/2/09 6:41 PM
Brian Kotek's Gravatar That should say "The overhead and complexity just aren't worth the limited (at best) benefits of applying OOP."
# Posted By Brian Kotek | 4/2/09 6:42 PM
ABC's Gravatar >I do not think OO is hard, but I often find it just >doesn't fit well into web development.

Really? Just have a look at http://www.seaside.st
# Posted By ABC | 4/3/09 9:04 AM
Nando's Gravatar @Ben

Hal created a LOT of trouble for me by advocating that ColdFusion programmers learn OO years ago. Every time I see his picture or his name, something deep in my gut twinges a bit. He, or rather my choice to take his advice, put me through a lot of pain. I tried my best all alone here in the southern Swiss alps, before any of the OO frameworks were developed, to "get" OO. And I'm very glad I did, even tho' I'm still not very good at patterns, and would be a total dunce in any discussion about OO amongst many other programmers.

I like his take on viewing an object as a datatype. But to me, that's only a part of the story. Objects help open the possibility of messaging in an application and all that this implies: "Hey, can you do this for me?" rather than "I have to do everything myself". And that milieu creates a certain flexibility that you wouldn't otherwise have.

And it's in that milieu of messaging and encapsulation where I find I save time and effort with an OO approach. The problem with experiencing that benefit from the beginning is that you don't run across it much, if at all, in small test applications.

But you _do_ in the real world, where clients seem to be hardwired to ask for changes that effect the whole application.

In life, it's sometimes more work to tell someone else what to do rather than just doing it yourself. If you set up an organizational structure to provide such messaging, essentially to tell others what to do and get feedback, that effort in itself takes time and energy. But then you're set up to accomplish more than you would as a "do-it-yourselfer". You can handle more complex tasks, you can expand more easily, get more people involved, do more things at once, and hopefully you can adapt to change more readily, etc. Going from a do-it-yourselfer to setting up an organizational structure to allow your business to expand is tough.

I'm supposed to be moving forward with the application I'm currently working on, but in reality, there are so many requests for changes flooding in that the past 2 months and likely this month will simply be dedicated to adding in new capability, much of it interwoven with what already exists.

I'm not wincing when these requests come in. They are generally very easy to accommodate in the OO milieu I'm working in. In fact, I find it enjoyable, so enjoyable that I look forward to the next request. And again, I don't understand much about patterns or any of the sophisticated concepts that are bantered about.

Now I only wince, just a bit, when I see Hal's picture, remembering the tangled mess I made on my own trying to "get" OO with his Discovering CFCs book at my side. ;-) Maybe he's still trying to apologize to us with this "It's just a datatype" stance. If so, no apology needed! Even tho' I'm not very good at setting up the organizational structure needed to organize the messaging and layers of responsibility in an application on my own, my rudimentary understanding has proven to be very useful, primarily because of the milieu that OO creates.
# Posted By Nando | 4/3/09 11:01 AM
Ben Nadel's Gravatar @Nando,

When it comes to building applications, I try to find the best way to do so and a lot of times that comes as a response to pain. When I feel pain in development, I try to fix it.

There are plenty of things that I have not felt pain on which is why I haven't yet explored things like Dependency Injection frameworks, persistence frameworks, or even organizational frameworks - there hasn't really been any pain yet in those areas.

But, where I have felt the "pain" is in duplication of business logic. For example, having to create a "Contact" record from three different interfaces and duplicating the validation / processing in all three places.

This is the pain that I am trying to remove and I truly believe that some form of OOP *is* the answer to this pain. Now, whether that OOP is more just an API layer in some cases and more in-depth domain modeling in others... that I guess is an "it depends" kind of question (grrrrr!) :)

That said, I am determined to learn this stuff!!
# Posted By Ben Nadel | 4/3/09 11:35 AM
Nando's Gravatar @Ben

I'm sure you know more about OO on a theoretical level than I do. I also have a sense I understand your reluctance. Why set up that excess organizational structure (that goes along with OO)? Which one would be best, the most efficient, the least extra work?

Entrepreneurs don't know the answer to such questions in advance. Either they jump in and start making mistakes, or they remain on the sidelines with an idea to form a business. I think the same applies to OO. Any one of the organizational structures, frameworks, will do. The point isn't to get it right. I think the point is to give yourself a chance to start making mistakes.

With all the complexity and variables that go into either a business venture or an object oriented approach to tackle a complex problem, I don't think we have much choice except to jump in and start making mistakes. There are generally 2 types of mistakes, big ones and little ones. The difference is that little mistakes you can let ride. They don't significantly affect the overall end result enough to focus time and energy on.

As a programmer dealing with syntax, I think we get used to the lovely idea of perfection, syntax has to be perfect in order to work. Perhaps as a personality type, programmers are attracted to this aspect of programming.

I see OO as being in a different world more akin to entrepreneurship, and maybe that's why I'm drawing the parallel. There's no such thing as perfection there. It seems to me you learn it by being willing to live in a world of mistakes, and some of them are hard lessons. Invest $100,000 of your own money in a first business venture and fail at it. Do that one or 2 more times, each time getting a little closer to success. I think _that's_ the guy you want on your management team, not the one who got lucky the first time out.

He won't have all the answers, but he will know something about avoiding a lot of the big mistakes. In a similar way, OO cannot be pure. As I see it, OO is more about avoiding big mistakes and settling on compromises than finding the perfect solution, but that does not mean that it's not a good solution to employ in the "perfect" world of programming! I find rather the contrary, even tho', in fact in spite of the reality that I'm not very good at it!
# Posted By Nando | 4/3/09 12:42 PM
Hal's Gravatar @nando: It's a common occurrence for people to wince when they see my picture, but this is the first time it's ever been linked to OO!
# Posted By Hal | 4/3/09 1:20 PM
Nando's Gravatar @Hal: Honestly, I find you very generous and sincere, intelligent, witty. I only wince because I followed your advice! ;-)
# Posted By Nando | 4/3/09 3:10 PM
Ben Nadel's Gravatar @Nando,

I agree that you have to just start doing it or you will over analyze to death; however, I think *many* business go out of business because they were not thought through or managed as well as they could have been. The same with OO - I think I need to just start applying *something*... but, if I don't think it through as much as is needed, then I incur all of the overhead with none of the benefits.

But, I will never learn unless I try.
# Posted By Ben Nadel | 4/3/09 3:19 PM
John Farrar's Gravatar Perhaps it is another issue. OO is powerful and dangerous. OO can nest logic or hide complexity just as bad as include files but provides a better interface so typically it 'should be' less spaghetti. OO solutions are abstract and until you understand the problem and particular positive and negative patterns that apply to the task at hand it doesn't matter.

With that said you may not have all the benefits of better OO if you stay with foundational concepts... but you should still be far ahead of include files if you learn to do it well. They say to a carpenter everything can be built with a hammer. OO is powerful and unlike any other solution. It is easy to initially fall in love with it... and then go so far pushing everything into OO before you understand it enough to do that. So you end up creating more of a mess with OO than if you left it out.

Conclusion: Learn OO a step at a time. If you take a week class like Ben did... realize you have become a treasure house of more knowledge than you have understanding. You may be better prepared to win arguments. You are better prepared to build your understanding faster. Yet, you are still green. Don't let the rush of head knowledge replace the wisdom of walking by putting one piece of code after another. (even if it is objects) In the end you will not only understand how objects work... you might also understand how software works and how objects solve problems dealing with software vs how to pick a 'design pattern'. Design patterns are great... but in the end it's the right use of software not your ability to articulate which design pattern you use.
# Posted By John Farrar | 5/5/09 11:57 PM
 
   
Clicky Web Analytics