Sunday, February 26, 2006

I write this blog entry in response to this mail in the Domain-Driven Design discussion group, regarding how to protect access to certain properties of domain objects.Here is a snippet of the problem as described by the author of the mail, Pascal:

I'm in a situation where we are redesigning a large core business system using domain driven techniques (which we've come to love, BTW). The resulting domain model is to be used by several different applications on the internet and intranet, each with their own restrictions. For this we'll use application layers to disclose application-specific business operations. Along with that, we will need application specific views on the domain model. Now we're faced with the challenge to create these views efficiently.

I know some say: just have the application layer pass the domain model to the outside world. This seems the simplest, but doesn't work for several conceptual and practical reasons. The most important conceptual reason is that the data to be passed outside is to be restricted. For example, in the domain model a Customer can have a 1-to-1 relationship with an Address, but we don't want the internet application to have access to the Address. In that case we cannot expose a Customer domain class.

Let's elaborate a bit about this.

One straight solution is making a copy of the domain object, populating only desired properties, while setting null protected ones.This is a sort of workaround, and I will not go further.

Another solution is obviously the use of Data Transfer Objects.You can construct specialized DTOs containing only non-protected properties and use them in your views.Even if you don't think at DTOs as an anti-pattern, and even if you are not an OO purist, DTOs have at least two serious problems: they duplicate code and have big maintenance problems.

A third solution could be the use of the proxy pattern : specifically, a protection proxy.

A protection proxy is simply a proxy for controlling access to object methods.We'll use dynamic proxies, that are proxies created at runtime: specifically, we'll use Java dynamic proxy APIs.I assume that you already know ho to use Java dynamic proxies: if not so, take a look here.

Let us recall the problem to solve: we want to forbid access to some object methods, in particular some setter and getter methods.Using proxies, we could solve this in two ways:

Creating a proxy which implements the domain object interface and throws an exception for protected methods.

Creating an adapter proxy which implements a restricted interface without the protected methods.

Throwing an exception where clients expect normal behavior is not so good: it is like violating the interface contract.At a glance I would not choose this.However, after more thinking and crunching, this technique is widely used in Java APIs, and permit us to switch from the original domain object to the proxied one without changing client code, because they both implement the same interface: if the protection proxy is well documented, I think this is a good compromise.

So, let us implement our protection proxy which will throw an exception for protected methods.

First, a simple domain object with its interface:

publicinterface ICustomer {

public String getName();publicvoid setName(String name);

public String getPassword();publicvoid setPassword(String password);

}

publicclass Customer implements ICustomer {

private String name;

private String password;

public String getName(){return name;

}

publicvoid setName(String name){this.name = name;

}

public String getPassword(){return password;

}

publicvoid setPassword(String password){this.password = password;

}}

We want to forbid access to getPassword and setPassword.Here is an InvocationHandler which will do the job:

In this way, protecting a domain object is only a matter of writing a proxy and applying it through a simple factory.Note that writing a dynamic proxy is a lot less expensive than writing DTOs, because you don't have to duplicate every attribute and every getter/setter method: you only deal with protected methods.Moreover, you have the extra gain of being able to switch from the original domain object to the proxied one, and vice versa.

One final word: DTOs are an open debate and I'm not saying, in any way, that this is the best solution.There are surely a lot of scenarios where other solutions are more viable: I'm just saying that protection proxies are a good solution which can avoid hand made DTOs.

The SourceForge.net team is pleased to announce the General Availability of Subversion service to SourceForge.net-hosted projects, effective 2006-02-21. This service offering is in addition to our existing CVS service; as with all of our services, projects may select (and enable in the project admin pages) the portion of our offering that best meets their needs.

Now that they fulfill this great request, if only the SourceForge site were a bit faster ...

Thursday, February 23, 2006

As you can see in the sidebar, I've just added some blog links in the Links section and, that's more important, I've created a FOAF file of mine.

What is, in short, a FOAF file?

FOAF (Friend-Of-A-Friend) is an RDF vocabulary describing information about people, their interest and relationships.You could say that this is already done by a simple web page ... the answer is that FOAF, being an RDF application published as an XML document, describes people in a machine understandable way, letting computers automatically discover, elaborate and aggregate information.In other words, what RSS does with documents content, FOAF does with personal data.A good starting point for FOAF is here.

At the moment, my FOAF file contains only some information about me and a list of persons "I know" in the blog sphere, because I personally met them or simply read their blog.I'll keep updating and enriching it ...If you want to be linked by my FOAF file, or if you're simply interested in FOAF, let me know.

Moreover, this is my first (indeed second, if you consider the atom feeds) movement toward a Semantic Blog: as soon as I'll find some more free time, I'll add other semantic stuff ... so stay tuned!

First of all, we need to download Apache Commons Collections and put its jar in our classpath.

Then, we need a little domain for our example ...Say you have an university with a lot of courses: each Course is worth some credits.You have also a lot of students: each Student can register an exam, related to a given course, and can request a graduation thesis.At the moment, we know that the student can request the graduation thesis only if he/she has a minimum number of credits and if he/she has passed a minimum number of exams.

Perfect ... let's code our domain.

We surely have two entity objects: Course and Student.Moreover, we have two rules defining when a student can successfully request a graduation thesis.

We must make this rules explicit in our domain, implementing them as Specifications.We'll use the Predicate interface for implementing a Java generics based specification abstract base class:

This class uses Java5 generics for letting concrete subclasses specifying theright object type to use for evaluating the specification.So, the generics method isSatisfiedBy(...), together with a meaningful name for the concrete subclass, allows us to implement a specification which adopts the domain specific language, rather than using an unexpressive evaluate(Object ) method.Here are the two concrete specifications:

/** * Get the list of specifications defining in which case * a student can request a graduation thesis. */public List<GBaseSpecification<Student>> getGraduationSpecs(){

return graduationSpecs;}

/** * Set the list of specifications defining in which case * a student can request a graduation thesis. */publicvoid setGraduationSpecs( List<GBaseSpecification<Student>> graduationSpecs){

this.graduationSpecs = graduationSpecs;}}

Take a look at Student's comments.First, notice the getter and setter methods which permit us to define a collection of GBaseSpecification objects for specifying graduation thesis request rules.Next, notice how the requestGraduationThesis() is implemented: it uses the PredicateUtils class for combining Predicate objects, that is, our specifications!Recall: our specifications implement the evaluate(Object ) method of the Predicate interface, so they can be combined by PredicateUtils!In this example, with only one line of code we combine our specifications using the logical and operator.

One of the hardest parts of working with domain logic seems to be that people often find it difficult to recognize what is domain logic and what is other forms of logic....A good example of this is a system I was told about that contained a list of products in which all the products that sold over 10 percent more than they did the previous month were colored in red. To do this the developers placed logic in the presentation layer that compared this month's sales to last month's sales and if the difference was more than 10 percent, they set the color to red.

The trouble is that that's putting domain logic into the presentation.

Suddenly, I said : "Specifications, here, are at their best!"

Create a generic IncreasingSaleSpecification interface, implement it for your particular case and apply for determining the color of the product in your view!

Doing so:

Business logic remains in your domain (into your Specification).

Your view implements no business logic.

You can implement new increasing sale specifications and simply change on the fly the behaviour defining when your products should be displayed in red.