Sunday, February 26, 2006

Protecting domain objects with protection proxies

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:
public interface ICustomer {

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


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

}

public class Customer implements ICustomer {

private String name;

private String password;

public String getName() {
return name;

}

public void setName(String name) {
this.name = name;

}

public String getPassword() {
return password;

}

public void setPassword(String password) {
this.password = password;

}
}

We want to forbid access to getPassword and setPassword.
Here is an InvocationHandler which will do the job:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class CustomerProtectionProxy
implements InvocationHandler {

private ICustomer student;


public CustomerProtectionProxy(ICustomer student) {
this.student = student;

}

public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {

if (method.getName().equals("getPassword") ||
method.getName().equals("setPassword")) {
throw new IllegalAccessException();
}

else {
return method.invoke(student, args);

}
}
}
Names of the methods to protect are hard coded: this is an example, and you can make a more flexible proxy.

Then, a simple factory for proxying domain objects:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class SimpleProxyFactory {

public static Object makeProxy(Object target,
InvocationHandler handler) {

return Proxy.newProxyInstance(target.getClass().getClassLoader(),

target.getClass().getInterfaces(),
handler);

}

}

And finally, a JUnit test case:
import junit.framework.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class SimpleProxyFactoryTest extends TestCase {
public SimpleProxyFactoryTest(String testName) {
super(testName);
}
public static Test suite() {
TestSuite suite = new TestSuite(SimpleProxyFactoryTest.class);
return suite;
}
public void testMakeProxy() {
ICustomer customer = new Customer();
customer.setName("Mark Red");
customer.setPassword("impossible");
ICustomer protectedCustomer =
(ICustomer) SimpleProxyFactory.makeProxy(customer,
new CustomerProtectionProxy(customer));
protectedCustomer.setName(protectedCustomer.getName());
try {
protectedCustomer.setPassword("new");
fail("You should not be able to call setPassword");
}
catch(Exception ex) {
}
try {
protectedCustomer.getPassword();
fail("You should not be able to call getPassword");
}
catch(Exception ex) {
}
}
}

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.

And I'd like to know your feedback.

SourceForge meets Subversion

From my SourceForge.net subscription update :
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

Toward a Semantic Blog

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!

Tuesday, February 21, 2006

Implementing Specifications with Apache Commons Collections

Some days ago I read a blog entry by Roni Burd, commenting on my A case for specifications post, where he mentioned the possible use of Apache Commons Collections facilities for implementing and combining Specifications.

I think this a very good idea.
Let us play a bit.

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:
import org.apache.commons.collections.Predicate;

public abstract class GBaseSpecification<T>
implements Predicate {


public boolean evaluate(Object object) {
return this.isSatisfiedBy((T) object);

}

public abstract boolean isSatisfiedBy(T object);
}

This class uses Java5 generics for letting concrete subclasses specifying the
right 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:
public class EnoughCreditsSpecification
extends GBaseSpecification<Student> {

private static final int min = 10;


public boolean isSatisfiedBy(Student s) {
if (s.getTotalCredits()>EnoughCreditsSpecification.min) {

return true;
}
else {
return false;

}
}
}


public class EnoughCoursesSpecification
extends GBaseSpecification<Student> {

private static final int min = 1;


public boolean isSatisfiedBy(Student s) {
if (s.getTotalCourses()>EnoughCoursesSpecification.min) {

return true;
}
else {
return false;

}
}
}

You can see that the two specifications meaningfully express the two domain concepts.

Next you'll have to implement Course (very trivial) and Student:
public class Course {

private int credits;

public int getCredits() {

return credits;
}

public void setCredits(int credits) {

this.credits = credits;
}
}


import java.util.List;
import org.apache.commons.collections.Predicate;

import org.apache.commons.collections.PredicateUtils;

public class Student {


private int totalCourses;
private int totalCredits;
private List<GBaseSpecification<Student>> graduationSpecs;


/**
* Register an exam related to a given course.
* This increases the student credits.
*/

public void registerExam(Course course) {
this.totalCredits += course.getCredits();

this.totalCourses++;
}

/**
* Return true if this student can request a graduation
* thesis, depending on a given list of specifications.
*/

public boolean requestGraduationThesis() {

Predicate p= PredicateUtils.allPredicate(graduationSpecs);
return p.evaluate(this);

}

public int getTotalCredits() {
return this.totalCredits;

}

public int getTotalCourses() {
return this.totalCourses;

}

/**
* 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.
*/

public void 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.

Now, a simple main for testing our classes:
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.PredicateUtils;

public class TestStarter {

public static void main(String[] args) {

Course c1 = new Course();
Course c2 = new Course();

c1.setCredits(5);
c2.setCredits(6);

Student s1 = new Student();

Student s2 = new Student();
List<GBaseSpecification<Student>> specs = new ArrayList();

specs.add(new EnoughCoursesSpecification());
specs.add(new EnoughCreditsSpecification());

s1.setGraduationSpecs(specs);
s2.setGraduationSpecs(specs);
s1.registerExam(c1);

s1.registerExam(c2);
s2.registerExam(c1);

System.out.println("Can s1 request a thesis? "
+ s1.requestGraduationThesis());

System.out.println("Can s2 request a thesis? "
+ s2.requestGraduationThesis());

}
}

You can obviously define a default set of specifications, set the specifications collection via dependency injection and so on ... this is only a simple use case.

Hope you've found this a simple and powerful way of implementing and combining specifications.

Take a look at the PredicateUtils javadoc ... and have fun!

Tuesday, February 14, 2006

Another case for Specifications

Yesterday I've started to hold my third week of courses, introducing people to Enterprise Application Design and Development using the wonderful Hibernate and Spring.

Using, as a reference, the well known Patterns Of Enterprise Application Architecture book, I've came across this sentences:
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.


Amazing!

Monday, February 13, 2006

SourceSense : Logo Challenge

My (should I say "ex", Gianugo?) colleague Gianugo Rabellino is starting a new, very promising, open source based company : SourceSense.

If you feel comfortable with graphics, you can submit a fancy logo for SourceSense here and try to win a new MacBook Pro laptop (if you are reading, Mario, you should REALLY REALLY try)!

So, good luck for your logo! ... and a shiny future for your company, Gianugo!

Wednesday, February 01, 2006

Rome JUG : First Meeting

Since December 2005, Rome has its first, official, Java User Group.



On 25th January 2006 there was its first meeting, with two interesting talks regarding:

  • Neural networks and the Joone framework, by Paolo Morrone.

  • Alternative persistence frameworks, by Ugo Landini (yes, the OO guru!).


If you crunch Italian language, you can download presentations and audio podcasts of the two talks here.


This is great for all us Java developers, and I'm waiting for a lot of cool events here in Rome!
Hope to see you in the next meeting!