The blog has moved

March 29, 2010

This blog is now located at http://techblog.bozho.net

On domain-driven design, anemic domain models, code generation, dependency injection and more…

March 25, 2010

Eric Evans has formulated what domain-driven design (DDD) is. Martin Fowler is a great supporter and advocate of DDD. These are remarkable names and it is almost certain they are supporting something worth. And I’m not here to argue with that. Maybe I’m trying to justify the way I’ve been writing software, or maybe I’m trying just to clear things and be constructive. Let’s see.

What is at the core of domain-driven design – the abstract notions of the domain, the domain model, the ubiquitous language. I’ll not go into details with that – for those interested there is wikipedia (with lots of references to read in the footer). This is all very good in theory, and the domain-driven way of building software should appeal to everyone – after all that software is being built for the benefit of that domain, not for the benefit of architects, developers or QAs.

But now comes the practical part – how to implement DDD? I’ll answer that question in its contemporary context – that is, using frameworks like spring and hibernate. And I’ll justify their usage. Spring is a non-invasive dependency-injection framework. DI is also strongly supported by Fowler, and is considered a good way to implement DDD. Hibernate is one way to use objects when working with a relational database. Another way is to use JDBC and construct the objects manually, but that is tedious. So hibernate doesn’t influence the architecture part – it is an utility (very powerful one, of course).

Throughout this post I’ll use hibernate and spring as “given”, although they may be changed with any DI framework and any ORM or other persistence mechanism that relies on objects.

The accepted way to implement DDD with spring and hibernate is:

  • use @Configurable to make the domain objects eligible for dependency injection (they are not instantiated by spring, so they need this special approach)
  • inject repository objects in the domain objects in order to allow the domain objects to do persistence-related operations
  • use a thin, stateless, transactional service layer (a facade) to coordinate the domain objects

Implementation and description of this approach is shown in this extensive article. Another example (without spring) is http://dddsample.sourceforge.net/. I’ll discuss both later.

The alternative to this approach is the anemic domain model. It is considered an anti-pattern, but at the same time is very common and often used. The features of the anemic data model are simple – the domain objects have no business logic inside them – they are only data holders. Instead, the business logic is placed in services.

The reason this is considered an anti-pattern is because, first, this seems like a procedural approach. It is breaking the encapsulation, because the internal state of the object is, well, not internal at all. Second, as the domain object is the center of the design, it is harder to change it if its operations don’t belong to it, but to a number of stateless service classes instead. And domain-driven design is aimed at medium-to-large scale applications, which change a lot and need an easy way to make changes fast, without breaking other functionality. Thus it is important to have all the functionality of the object within the object itself. This also makes sure that there is less duplication of code.

So, instead of having a service calculate the price: ProductServiceImpl.calculatePrice(complexProduct) we should simply have ComplexProduct.calculatePrice(). And so whenever the domain experts say that the price calculation mechanism changes, the place to change it is exactly one and is the most straightforward one.

When simple operations are regarded, this looks easy. However, when one domain objects needs another domain object to do its job, it becomes more complicated. With the anemic data model this is achieved by simply injecting another Service into the current one and calling its methods. With the proposed DDD it is achieved by passing domain objects as arguments.

In my view, the domain object, which is also the hibernate entity, has its dependencies already set. But not by spring, because spring can’t know which exactly domain object to inject. They are “injected” by hibernate, because it knows exactly which (identified by primary key) domain object should be placed in another domain object. So, a little odd example – if a Product has rotten and has to dispense smell in the warehouse, it has to call, for example, warehouse.increaseSmellLevel(getSmellCoeficient()). And it has its pricise Warehouse without any interference from spring.

Now, here comes another point where I disagree. Most sources (including the two linked above) state that repositories / DAOs should be injected in the domain objects. No, they shouldn’t. Simply calling “save” or “update” doesn’t require knowledge of the internal state of the object. Hibernate knows everything anyway. So we are just passing the whole object to the repository.

Let’s split this in two – business logic and infrastructure logic. The domain object should not know anything of the infrastructure. That might mean that it should not know it is being saved somewhere. Does a product care of how it is stored in the warehouse? No – it’s the warehouse that’s “interested”. And here are the practical disadvantages:

  • CRUD is implemented by simply wrapping repository calls in all domain objects – duplication of code
  • the domain object is transitively dependent on persistence – i.e. it is not a pure domain object, and if repositories change, it has to be changed as well. And in theory it should be changed only when the domain rules and attributes change
  • people will be tempted to include transaction, caching and other logic inside the domain object

I’ll open a bracket here about a proposed solution in one of the above articles for making duplication of code, and boilerplate code easier to handle. Code generation is suggested. And I think code-generation is a sin. It moves the inability to get rid of duplicated or very similar code and abstract it, to tools. The most striking example is generating ProductDAO, CategoryDAO, WarehouseDAO, etc, etc. Generated code is hard to manage, cannot be extended and relies heavily on external metadata, which is definitely not an object-oriented approach.

Speaking of the repository, in the proposed examples each domain object should have a repository, which in turn will call the persistence mechanism. What do we get then:

User presses “save” in the UI > UI calls save on the service (in order to have transaction support) > Service calls save on the domain object > domain object calls save on the repository > the repository calls save on the persistence mechanism > the persistence mechanism saves the object.

Is it just me, or calling the domain object is redundant here. It is a pass-through method that adds nothing. And since a lot of functionality is related to CRUD (yes, even in big business applications), this looks quite bad to me.

And finally, I find the @Configurable approach a hack. It does some magic in the background, which isn’t anything of the common language features (and is not a design pattern), and in order to understand how it happens you need a great deal of experience.

So, to summarize the big mess above

  • domain objects should not be spring (IoC) managed, they should not have DAOs or anything related to infrastructure injected in them
  • domain objects have the domain objects they depend on set by hibernate (or the persistence mechanism)
  • domain objects perform the business logic, as the core idea of DDD is, but these do not include database queries or CRUD – only operations on the internal state of the object
  • there is rarely need of DTOs – the domain objects are the DTOs themselves in most cases (which saves some boilerplate code)
  • services perform CRUD operations, send emails, coordinate the domain objects, generate reports based on multiple domain objects, executing queries, etc.
  • the service (application) layer isn’t that thin, but doesn’t include business rules that are intrinsic to the domain objects
  • code generation should be avoided, and abstraction, design patterns and DI should be use instead, to overcome the need of code generation

UI for managing PKI, instead of keytool or openssl

March 22, 2010

This blogpost shares a wonderful utility – portecle – GUI for managing PKI

The psychology of voting and choice (on Stackoverflow and in general)

February 24, 2010

Voting is at the center of http://stackoverflow.com (a programming Q&A site), and at the center of democracy (at least such are the claims). How and why do people vote? Today I have a fresh example:

There was this easy question on the |= operator in Java, and I was the first to provide an answer. That lead to a few initial upvotes, so at one point I had 7 and another answer had 2. Then the question author accepted the second-rated answer. An hour later the votes where 9 to 6. So:

  • while my answer was on the top (by virtue of being the first), I got voted up to a big margin
  • when the other answer got on the top (by virtue of being accepted), people started voting it up instead

It’s not who posted the answer (this time) – i.e. who the community trusts more. It is not a matter of quality – both answers give the same information because the question is really simple. It is the simple fact that one answer is the first to be seen.

(And these are intelligent people – they use the Internets and most of them are programmers)

Appeal to API designers

February 18, 2010

If a developer has used the Java security APIs he already knows what’s ahead. That’s not the only example, alas, but I’ll be using it to illustrate my point.

These APIs provide their configurable properties through singleton maps. Security.setProperty("ocsp.enable", "true"); for example

The documentation of these properties is not always in the most visible place, and instead of seeing them while using the API, you have to go though dozens of google results before (if lucky) get to them. And you don’t always know what exactly you are looking for.

Another very serious concern is thread-safety. For example if two threads want to check a revocation via ocsp, they have to set the ocsp.responderURL property in some cases. The “validate(..)” method is not thread-safe, so you should make a synchronization on the validation yourself. A synchronization (and hence potential blocking and waiting) that could have been avoided.

Some at least semi-valid reasons for such type-unsafe, thread-unsafe, Map design could be:

  • setting the properties from the command line – a simple transformer from command-line to default values in the classes suggested above would be trivial
  • allowing additional custom properties by different providers – they can have public Map getProviderProperties(), or even public Object ... with the casting to the custom provider class.

But since many properties are used by only one class (or just a couple), this can be made far more usable. The two potential steps for improvement are:

  • again singleton, but with getter and setter for each property
  • an object containing the properties relevant to the current context CertPathValidator.setValidatorProperties(..) (it already has a setter for PKIXParameters, which is a good start, but it does not include everything)

So the appeal to API designers is – don’t make properties configurable via static Maps.

Using multiple ELResolvers with CompositeELResolver in JSF

February 5, 2010

Imagine the case where you have a JSF application that’s already using some custom ELResolver, but you want to get all the benefits of spring and want to have the SpringBeanFacesELResolver. Well, it’s rather simple:

public class MyCompositeELResolver extends javax.el.CompositeELResolver 

    public class MyCompositeELREsolver() {
         add(new YourCustomELResolver());
         add(new SpringBeanFacesELResolver());
   }
}

Note that the resolvers are ‘consulted’ in the order they are added.

Now just define your newly created composite resolver as in faces-config.xml.

Tips for identifying and debugging problems

January 6, 2010

It seems that some/many developers haven’t developed (pun intended) a good set of techniques to identify and resolve problems. And problems always occur, even in simple programs. Recently I’ve been answering a lot of questions on StackOverflow and those questions confirmed my suspicions. Some of the advice here may sound like advice for newbies, but pactice shows they are needed. I’m a Java developer, but the tips below may be considered language-agnostic.

Note that the steps are often regarding Exceptions, but in case there is no exception – just an undesired behaviour, those steps are skipped.

  1. Exception stacktraces – these are so often ignored and even considered irrelevant. Stacktraces are the place to start looking for the problem. Not only the exception message, but the line of code at which the exception occurred (in your code, in the library code).
  2. The code in question – after seeing what line of code causes the exception, immediately go to that line and see if the problem won’t become obvious. Try understanding the behaviour of the code (even if it is your code!). In case there is no exception, but an undesired behaviour, identify the code that is relevant
  3. Google – if it doesn’t become obvious, or the exception/problem occurred somewhere in a framework you are using, rather than in your code, then google the exception message or the problem description. Google it for 15 minutes, trimming various parts of the exception message – most importantly your package and class names. Most of the common exceptions occurring in popular frameworks are explained many times (because people skipped this step)
  4. Read the documentation – this is not always applicable, but in cases when the problem/exception regards a concrete component of the framework used, read the documentation about it. As the saying goes – 5 hours debugging save 20 minutes reading documentation
  5. Debugger – if there isn’t an obvious solution from the previous steps, use the debugger of your IDE. Put breakpoints at relevant places and trace the flow of the program. This will help you understand how exactly the program functions (again, even if it is your code). You will be able to monitor variables and fields, and see if their values are not the ones you expect
  6. Decompiler / framework source code – I’m always having a decompiler plugin installed on my IDE. It extends the process of looking at your own code to looking at all the code that’s involved. Alternatively, you can download/check-out the sources of the framework you are using (if it’s open-source) and add them to your IDE. Debugging with either the decompiled sources or the real sources can provide even more beneficial information about the problem, if you look at the appropriate places
  7. Finally, if you haven’t solved the problem – ask a question. In the forums of the framework/tool, in general forums (JavaRanch, Sun forums, etc), or in dedicated Q & A sites like StackOverflow. State the question clearly, show what have you already done in order to find/fix it, and give the appropriate information (setup, version of the framework, the code in question, the whole stacktrace, etc). At the same time try not to make the question too long and try to emphasize the main points – people that aren’t paid to answer will be reading it after all
  8. It sometimes happens that you have discovered a bug. This is a rare case with popular and mature frameworks/tools (yes!), but if you are sure it is a bug, go to the issue tracker and file a detailed bug report. They will either instruct you how to use a workaround, or will fix it eventually

I’ve used words like “relevant” or “appropriate”. The degree of benefit from each step will depend on your experience, and each time you will get better at each of the steps.

Spring annotation-based vs xml-based transaction definitions precedence

January 2, 2010

I couldn’t find a definitive answer to this in the docs, and although there seems to be a logical answer, one can’t be sure. The scenario is this – you have a xml-based transaction definition, like:

<tx:advice id="txAdvice" transaction-manager="jpaTransactionManager">
    <tx:attributes>
        <tx:method name="*" propagation="REQUIRED" />
    </tx:attributes>
</tx:advice>

Which advises all service methods. But then you have @Transactional on a concrete class/method, where you want to override the propagation attribute.

It is clear that @Transactional at method-level overrides the same one at class-level, but does it override the <tx:advice> (and actually, the <aop:pointcut>)?

It turns out the behaviour is less than expected:

  1. Both <aop:advisor> and @Transactional (together with <tx:annotation-driven>) create a TransactionInterceptor around the target class (the one, whose methods are to be run in transaction).
  2. The advice with a lower order attribute overrides the other one. If no order attribute is specified, the order is undefined. But my tests showed that the one defined latest in the applicationContext.xml takes precedence, although this might not be the case always:

    When two pieces of advice defined in different aspects both need to run at the same join point, unless you specify otherwise the order of execution is undefined.

This is the behaviour for spring 2.5.6. Spring 3.0 might have redefined this.

Are tests of service methods that rely on database access unit tests?

December 29, 2009

It is often argued whether tests that need a database should be called “unit tests”. Most often the answer is “No, these are database integration tests”. My opinion is – “Yes”.

The whole problem is routed in the fact that service methods depend on data access. If an application is designed properly the data access is abstracted in the DAO layer, so the code is testable.

So why is it proper to call these tests “unit tests”. Because service methods (units) are tested. These methods have a dependency on the Data Access layer, which in turn depends on a database. Now, a purely unit-testing approach would be to mock the dependency – the DAO in this case. This mock should be fairly complex in order to behave as expected. So why creating a complex mock, if you can instead use an in-memory database (HSQLDB/Derby/JavaDB), which can be realized as a mock of the runtime setup.

Here’s why this is not a database integration testing – you are not testing whether your application integrates with a real database. You test the business operations that rely on database operations. But the way these operations are performed is practically mocked (though not in the standard sense)

In regard to build speed concerns – in-memory databases are (logically) very fast. This alone can reduce the amount of time for running the tests to levels low enough.

JAXB: javax.xml.bind.UnmarshalException: unexpected element

December 18, 2009

JAXB: [javax.xml.bind.UnmarshalException: unexpected element (uri:"http://mynamespace/", local:"entity"). Expected elements are ({}entity)]

The following exception broadly means that an element encountered during unmarshallization isn’t found in the JAXB Context.
The details, however point us elsewhere – the element IS in the context, but it exists there without a namespace.
The first thing to do is check whether our @XmlType / @XmlRootElement define a namespace. And they do.
Finally, there is @XmlSchema annotation that defines an attribute called elementFormDefault. In order to put the elements together with their namespaces, this atribute must be set to javax.xml.bind.annotation.XmlNsForm.QUALIFIED. This annotation should be defined in package-info.java


Follow

Get every new post delivered to your Inbox.