Help

Inactive Bloggers

Well, this post really brought out the crazies. Folks told me that I don't know what an object is, called me ignorant twice, quoted Alan Kay at me, and accused me of being a C programmer. :-)

(What is it about the Internet that makes it okay to call someone ignorant just because you happen to disagree with them?)

Best I can tell, what infuriated these (well-informed, intelligent, passionate) people was the following statement:

Objects are stateful, and one of the main purposes of the methods of an object is to export that state (data) to the world.

A typical objection was:

The fundamental tenet of Object Orientation is that the state of an object is not exported out through the public behavioral API.

The fundamental tenet. Got that? ;-)

Okay, so let's take this idea seriously, and see what kind of impact it would have upon the design of our system. Let's start with Order. According to these guys, this is the perfect object:

class Order {
        private Status status;
        private List<OrderLine> orderLines;
        private Customer customer;
}

This class obeys the fundamental tenet. It exposes no state to its clients. Unfortunately, it's also totally useless for anything except looking at and admiring its pure, beautiful objectyness. If we want to actually use it for something, we're going to need to be able to add new OrderLines.

class Order {
        ...
        private List<OrderLine> orderLines;
        ...
        void addOrderLine(OrderLine line) {
                orderLines.add(line);
        }
}

Does this violate the fundamental tenet? I'm not sure. It's not clear to me whether a mutator method exports the state of an object. I would say it does, but we've already established that I don't know what an object is.

Unfortunately, we're not quite done. We can only add new OrderLines if the Order is in a certain state. Let's fix this:

class Order {
        private Status status;
        private List<OrderLine> orderLines;
        ...
        void addOrderLine(OrderLine line) {
                if ( status.isSubmitted() ) {
                        throw new IllegalStateException();
                }
                orderLines.add(line);
        }
}

Nice! We obeyed the fundamental tenet!

But ... when we display an order to our user we really need to know in advance whether its okay to add new lines. It's not okay to let them find out when the addOrderLine() method blows up!

class Order {
        private Status status;
        private List<OrderLine> orderLines;
        ...
        boolean canAddNewOrderLines() {
                return !status.isSubmitted();
        }
}

Oooop! Wrong! We violated the fundamental tenet! We exposed the state of the object to its clients! What can we do to fix this? Well, we could try to make the object responsible for rendering itself to the user interface:

class Order {
        private Status status;
        private List<OrderLine> orderLines;
        ...
        public void render(Panel panel) {
                ...
                if ( !status.isSubmitted() ) {
                        panel.addButton( .... );
                }
        }
}

But ... doesn't this approach just expose the state of another object (the user interface for Order) to the Order class? Worse, it creates a dependency from the domain model to the user interface, a deep error in terms of architecture. But this is just the beginning of our problems! We really need to be able display the total price of the order to our users:

class Order {
        ...
        private List<OrderLine> orderLines;
        public Amount getTotal() {
               Amount amount = ZERO;
               for (OrderLine ol: orderLines)
                       amount.add( ol.getAmount() );
               }
               return amount;
        }
}

This method also exposes the state of the object; and so it also violates the fundamental tenet.

And, sometimes, the user interface needs to display information about what Customer an Order belongs to.

class Order {
        ...
        private Customer customer;
        
        public Customer getCustomer() {
                return customer;
        }
}

Clearly, this one of those evil getter methods we've heard about; it exports the internal state of Order directly to the world!

So, where do we go from here? How can we design our system so that we obey the fundamental tenet of Object Orientation? Well, one approach we could take is that we could just accept that this fundamental tenet is not so fundamental after all! Perhaps it is more of a recommendation, a guideline that we take into account along with many other conflicting constraints that apply when we design software. Some of these constraints are general principles of good design. Some are architectural practices. Some are special restrictions of the programming environment we are working in. Some are simply concessions to practicality!

Another possibility is that we've misunderstood this tenet. Perhaps what it is really saying is not that objects never expose their state, but rather that they expose it in a controlled fashion, via intermediating methods that abstract the internal data structure and control access to it.

Well, it's not for me to say which of these interpretations is the correct one, since, as we've already established, I don't know what an object is. Besides, this is not really what I want to write about today. The topic I really want to talk about is religion.

The folks who got upset over this issue displayed the classic symptoms of a religious mindset:

  • Appeal to authority: In the Bible, it says..., Alan Kay writes..., What would Jesus do?
  • Argument from overly broad principle: The fundamental tenet..., The Golden Rule...
  • Intolerance of dissenting opinion: Ignorant, Heathen, Infidel
  • Application of principle, without concern for consequence, and without sufficient understanding of the justification and motivation underlying the principle.

Worst of all, religions set up absurd laws that no adherant of the religion can possibly obey (do not covet thy neighbours wife, getter methods are evil), and then demand shame of those that breach the rule. On the other hand, the absurd law is taken, by adherants, as a license for denunciation of free-thinkers: those of us who believe it's perfectly okay to check out the bangin' ass on the chick next door, even as we're being faithful to our gorgeous wives and girlfriends. And those of us who think a getter method is a perfectly natural construct, the simplest and most natural solution to many problems. The great thing about denouncing free-thinkers is that the religious person gets to characterize their own opinions as the Word of God (or Alan Kay).

In general, the religious approach is very unhelpful in the field of technology. It blinds us to innovative new ideas and novel ways of viewing a problem. By contrast, the inquiring mindset is characterized by:

  • A tendency to argue from consequence: If we followed this approach....
  • Comfort with cost/benefit analysis: On balance, I think the advantages of this approach outweigh the disadvantages....
  • A willingness to search for the limits of applicability of general principles.
  • An openness to other paradigms and opposing points of view.

And so I'm back where I started: the ObjectMentor article. Why did I characterize this post as silly? Because it attempted to justify a new, unnecessary, architectural layer, without a single attempt at argument from consequence. Without even asking what the consequences of this horrible architecture would be! The ObjectMentor was in full religious mode, arguing from principle, without concern for practicality. And, as is often the case when we argue from principle alone, the ObjectMentor managed to forget some other principles along the way. More important principles. Principles like:

  • Simplicity
  • Don't Repeat Yourself
  • Ya Ain't Gunna Need It

The introduction of an extra layer would violate all these principles. But I suppose religions have always been big on unnecessary complexity and self-repetition. And religion is something that a person with a curious mind and self-confidence in his (her) own judgment and insight truly Ain't Gunna Need (in technology, or life).

I've recently read the book Domain Driven Design, which apparently is now the new bible for some folks who totally think in objects. I even mentioned it in HiA and JPwH - unfortunately I didn't read it before.

I now think that quite a few of the patterns promoted by this book are actually a step backwards. I also miss a list of Pros and Cons of each pattern (like in the GoF book). So readers have to guess why and when a pattern might be applicable and when not. Or, when the Cons bullet items would outweigh the Pros.

One example would be the /Repository/ pattern. If I understand it correctly, this is how it works (the DDD author says that this similar summary is correct):

  • Developers don't want to decide if they should call order.getLineItems() or rather lineItemDAO.findAllForOrderId(order.getId()) if they need a bunch of line items from the data store. (I completely agree that this is a typical and common issue - however, I don't agree with the proposed solution.)
  • We can restrict that and take away that decision by forcing access to always go through a repository. For example, there is only an OrderRepository and the only way to get line items would be OrderRepository.getLineItems(order). This repository thing uses DAOs internally to actually get the data. So we wrap DAOs in repositories, creating an additional layer. You are not supposed to call the DAO anymore.
  • Now, we generalize the OrderRepository into an interface and put the DAO access into OrderRepositoryImpl.
  • And finally: We then inject this concrete OrderRepository instance into the Order class, so that when you call order.getLineItems(), it will internally access the repository. This requires interception of domain model instance creation but that is easy enough to do these days with containers/factories/services everywhere. Nobody creates a /new/ instance anymore, right?

The advantages seem to be that repositories speak the language of the domain (eh, what? This seems to be related to passing IDs as DAO finder arguments...) and that, well, you no longer have to make these difficult choices when you want to access a data store, because there is only one way to get the stuff.

I think this pattern is a step backwards and should not be recommended:

  1. If you do not want to have to decide between order.getLineItems() and lineItemDAO.findAllForOrderId(order.getId()) - kick out one of these methods! Nobody forces you to map a persistent lineItems collection on your Order class. You did that because you like the features you get when you load data that way (in Hibernate: transparent pre-fetching of other lineItems collections with batches or subselects, can't do that nicely in DAO finders). If you don't need that, don't create it. The same is true for any other association in your domain model. Or, vice versa, if there is no difference between a DAO finder method and a domain model traversal, remove the DAO method.
  2. If there really is a difference between order.getLineItems() and lineItemDAO.findAllForOrderId(order.getId()) - for example, one returns more associated stuff, like the product for each line item - keep them both. I do that all the time. I document it properly, saying this finder method does eager fetching of the product for each line item and on the getter method I write this returns line items, the products are unloaded proxies. And of course I need them both. Actually, I rename the DAO finder to lineItemDAO.findAllForOrderIdWithProducts(order.getId()) or, if I want to speak the language of the domain nothing stops me from defining it as lineItemDAO.findAllForOrderWithProducts(order). Because I don't like repeating myself, I finally end up with lineItemDAO.findWithProducts(order). It's now quite easy to decide if I call this, or rather order.getLineItems() - they have a different fetch strategy and fetch plan.
  3. You could argue that it would be nice if everything would /look/ the same. That is, following this repository pattern I would end up with an API like order.getLineItems() and order.getLineItemsWithProducts(). But the price I'd have to pay is A) a completely new layer in my application that is at least as complex as the DAO layer (conceptually there really is not much difference between them) and B) coupling my domain model to these repositories. And because I think there is really no difference between a generic, interface-based DAO architecture and these repositories, it means injecting DAOs into my domain model instances at runtime. That means they don't run anymore without DAOs (mock or real). Wrapping the DAOs again and again does not change that.
  4. If you do not inject and call repositories in your domain model classes, you gained nothing. You created a layer on top of the DAOs that looks like the DAOs, albeit with funny new names.

My personal best practices, when you have to decide how the persistence layer and services are integrated with the rest of the system, would be these:

  • Optimize access paths and simplify data access by carefully designing the domain model associations and persistence layer API (the latter following some good DAO pattern and related best practices - yes, there are books about this). Use the features of your transparent persistence service to make sure that all these access paths do the right thing, depending on what you need.
  • Document the access paths properly, and when each should be used. I adopt some simple conventions, for example: Never map a persistent collection unless it is absolutely necessary - this already makes things a lot easier.
  • Keep the domain model implementation clean, testable, and reusable: no security checks, transaction demarcation, or explicit data store access in any of these classes.
09. Nov 2007, 07:29 CET, by Gavin King

Kinda tangentially related to this discussion, I'm often asked whether I believe in rich domain models or anemic domain models. I guess I'm pretty much ignorant as to what these terms really mean, since I've never seen a proper definition of either term.

If by anemic domain model, we mean /never/ writing any business logic on our object model, and if by rich domain model, we mean /writing as much business logic as possible/ on our domain model, then I certainly don't believe in either approach. But these seem to be caricatures; I don't think anyone follows either extreme.

So how do /I/ decide if method that implements business logic might belong on the domain model?

Well, here I'm guided by an understanding that the domain model (entity classes) are /the most reusable/ classes in my codebase. So I don't want to put any logic there that has dependencies to any state or collaborating classes /other than/:

  • state held in the domain model (the persistent attributes), and
  • other domain model classes.

In particular, I would never write code that calls out to external services, or accesses the database, or calls an EJB/Seam/Spring component in my entity class. I want my domain model to be /completely self-contained!/

So anytime you find yourself wishing that entities supported injection, or find yourself writing a JNDI lookup in a method of an entity, please consider that your domain model is no longer self-contained, and will be less reusable in different execution environments.

I'm not saying it's /wrong/ to disobey these rules. There's no right or wrong in design. But I think there's good value having a self-contained domain model, and I've never seen a situation where this idea was impractical.

08. Nov 2007, 16:59 CET, by Gavin King

Somehow, this silliness got linked by InfoQ. It's not really worth the effort of fisking this post, but I'm bored so I'll go ahead and do it anyway.

Active Record is a well known data persistence pattern. It has been adopted by Rails, Hibernate, and many other ORM tools.

Actually Hibernate does not implement the ActiveRecord pattern. If you really feel the need to classify it according to Fowler's taxonomy, Hibernate is a DataMapper.

There is a 1:1 correspondence between tables and classes, columns and fields. (Or very nearly so). It is this 1:1 correspondence that bothers me. Indeed, it bothers me about all ORM tools. Why? Because this mapping presumes that tables and objects are isomorphic.

Well, this may be the case with ActiveRecord, but Hibernate and most other ORM solutions are a good deal more flexible in this regard. Indeed, one of the primary goals of any ORM solution is to allow objects and tables to be non-isomorphic to the extent that this makes sense.

From the beginning of OO we learned that the data in an object should be hidden, and the public interface should be methods. In other words: objects export behavior, not data. An object has hidden data and exposed behavior.

Bizarre statement. Objects are stateful, and one of the main purposes of the methods of an object is to export that state (data) to the world.

Data structures, on the other hand, have exposed data, and no behavior. In languages like C++ and C# the struct keyword is used to describe a data structure with public fields. If there are any methods, they are typically navigational. They don’t contain business rules.

I don't believe that the word data structure implies anything at all about behavior. Certainly it does not imply no behavior.

Thus, data structures and objects are diametrically opposed. They are virtual opposites. One exposes behavior and hides data, the other exposes data and has no behavior. But that’s not the only thing that is opposite about them.

Whoah! Diametrically opposed! Really?

On the contrary, most people I know would view an object as a package of:

  1. a data structure, and
  2. functionality that operates upon that data structure.

The data is an intrinsic part of the object; not its diametric opposite.

Algorithms that deal with objects have the luxury of not needing to know the kind of object they are dealing with.

This is not true.

The old example: shape.draw(); makes the point. The caller has no idea what kind of shape is being drawn.

Correct; the old example makes the point perfectly: the caller knows very precisely that the type of thing it is drawing is a Shape.

algorithms that employ objects are immune to the addition of new types ... objects are not immune to the addition of new functions ... Algorithms that use data structures are immune to the addition of new functions ... algorithms that employ data structures are not immune to the addition of new types ... Those portions of the system that are likely to be subject to new types, should be oriented around objects. On the other hand, any part of the system that is likely to need new functions ought to be oriented around data structures.

This is all predicated upon a false dichotomy between Objects and Data structures. In truth, there is no need to orient ourselves toward one view or the other in any particular part of the system.

Rather, we take advantage of subtyping (inheritance/polymorphism) when we design our object model. By carefully design of the type hierarchy, we allow our system to accommodate the introduction of new types and new behaviors.

Again, note the almost diametrical opposition. Objects and Data structures convey nearly opposite immunities and vulnerabilities.

Repeatedly asserting a false dichotomy does not make it true.

The problem I have with Active Record is that it creates confusion about these two very different styles of programming.

There is only one style of programming.

A database table is a data structure. It has exposed data and no behavior.

Correct.

But an Active Record appears to be an object.

Correct. An ActiveRecord is an object.

It has "hidden data", and exposed behavior. I put the word "hidden" in quotes because the data is, in fact, not hidden. Almost all ActiveRecord derivatives export the database columns through accessors and mutators.

There appears to be a deep confusion here about exactly what is supposed to be hidden. It is not state, nor data, that must be hidden, it is implementation details. Not the same thing at all.

And products like Hibernate certainly do not require that database columns be exported via accessors and mutators. Persistent attributes may be private if appropriate. State (data) can be hidden or exposed depending upon what is required by client code.

Indeed, the Active Record is meant to be used like a data structure. On the other hand, many people put business rule methods in their Active Record classes; which makes them appear to be objects.

Again with the false dichotomy.

This leads to a dilemma. On which side of the line does the Active Record really fall? Is it an object? Or is it a data structure?

It is both. There is no line.

This dilemma is the basis for the oft-cited impedance mismatch between relational databases and object oriented languages. Tables are data structures, not classes. Objects are encapsulated behavior, not database rows.

The impedence mismatch is between the different modelling constructs available in the two paradigms.

The problem is that Active Records are data structures. Putting business rule methods in them doesn’t turn them into true objects.

On the contrary, a data structure, together with business rule methods is the very definition of an object.

In the end, the algorithms that employ Active Records are vulnerable to changes in schema, and changes in type. They are not immune to changes in type, the way algorithms that use objects are.

Any object-oriented code is vulnerable to changes in the type system. To argue that algorithms that use objects are invulnerable to changes in type is absurd in the extreme.

You can prove this to yourself by realizing how difficult it is to implement an polymorphic hierarchy in a relational database. It’s not impossible of course, but every trick for doing it is a hack. The end result is that few database schemae, and therefore few uses of Active Record, employ the kind of polymorphism that conveys the immunity of changes to type.

Nonsense. Traditional data modelling has powerful, elegant methodologies for modelling subtyping, and modern ORM solutions like Hibernate are easily able to map between the relational and object-oriented approaches to subtyping.

So applications built around ActiveRecord are applications built around data structures. And applications that are built around data structures are procedural—they are not object oriented. The opportunity we miss when we structure our applications around Active Record is the opportunity to use object oriented design.

Persistent classes embody inheritance relationships and subtyping. There are many opportunities to take advantage of object oriented design priniciples. If your ORM solution doesn't support inheritance, get one that does.

Applications should be designed and structured around objects, not data structures. Those objects should expose business behaviors, and hide any vestige of the database. The fact that we have Employee tables in the database, does not mean that we must have Employee classes in the application proper.

The fact that we have employees in the business domain, and a notion of Employee in our business domain model implies that we will almost certainly have an EMPLOYEE table and Employee class in the object-oriented and relational realizations of this model.

We may have Active Records that hold Employee rows in the database interface layer, but by the time that information gets to the application, it may be in very different kinds of objects.

This is extremely unlikely. Both the relational schema and the object model are representations of the same entities that exist in the business domain. These entities exist in all layers of the application, from the user interface, all the way back to the database.

I am not recommending against the use of Active Record. As I said in the first part of this blog I think the pattern is very useful. What I am advocating is a separation between the application and Active Record. Active Record belongs in the layer that separates the database from the application. It makes a very convenient halfway-house between the hard data structures of database tables, and the behavior exposing objects in the application.

Oh wonderful. This stuff was all just an excuse for more useless layerism? Please, enough layers already!

So, in the end, I am not against the use of Active Record. I just don’t want Active Record to be the organizing principle of the application. It makes a fine transport mechanism between the database and the application; but I don’t want the application knowing about Active Records. I want the application oriented around objects that expose behavior and hide data. I generally want the application immune to type changes; and I want to structure the application so that new features can be added by adding new types.

The application should be oriented around the business domain model. Objects are an implementation detail.

07. Nov 2007, 23:46 CET, by Christian Bauer

Two weeks ago I presented Seam at Grails eXchange in London. This presentation was recorded, unfortunately without the slides in the visible frame:

The attached slide deck[1] from September is almost the same as the one I used in the video. I guess the slides are actually more interesting than watching me walk around a table. Hm, I could find out how to cut a slide + audio version with the new iMovie...

I need to mention that I spent more time on JSF and EJB3 than usual because nobody in the room knew much about them (it was a Grails conference, after all). So if you just want to know something about Seam - and again, all quite basic - skip half an hour into the video.

Showing 1026 to 1030 of 1232 blog entries