Hello guys,
I'm finally back.
I've been very busy at work.
Then, I've been on vacations for three weeks.
Now?
Well ... what a question ... I'm busy, busy, busy!
I have, as usual, a lot of work, and I'm applying myself in fixing the last issues prior to the upcoming Spring Modules release.
However, I'll try to blog as much as possible, obviously trying to write something interesting ... at least by my point of view!
So stay tuned.
Cheers!
Wednesday, September 06, 2006
Friday, July 21, 2006
Constructing View objects with the Builder pattern
Domain-Driven Design gives us important concepts like Entities, Value objects, Factories, Repositories, Aggregates, Services, but doesn't talk about View objects and how to construct them.
View objects, as I see them, are a kind of DTOs without the burden of DTOs.
While DTOs represent and duplicate domain objects data, View objects simply represent data requested by a view and extracted from one or more domain objects.
What's more important, they cannot be used as replacements of domain objects, because they are immutable containers of simple data.
So, their use is (and must be) restricted to those scenarios where you need read only report-style views and fast performances.
What about View objects construction?
Like discussed in this post from the Domain-Driven Design group, there are different possibilities.
I think the best one is to use the Builder pattern:
You can use the Builder pattern for implementing build methods that directly access the data store for constructing different parts of the View object.
This gives you the following advantages:
This gives you better performances and higher flexibility.
Let us go now with a simple example.
Say we have two domain objects: Employee and Office (I'm not going to show interfaces here because they are of no interest in our context).
The two domain entities are annotated with EJB3 annotations, so they are persistent objects.
Now, your application needs some report-style view listing a few employees data, but you don't want to get the full Employee object graph: so you create a marker EmployeeView interface for representing employee related views, and an extended interface for showing just some simple data from an employee and its related office, the SimpleEmployeeView (with related implementation):
Please note: the view implementation has setters method, while the interface has not. This is because the view (hence its interface) has to be immutable, but setter methods must be used by the builder for constructing the View object.
Once you have some View object, you need a Builder!
So here is the generic Builder interface for constructing generic EmployeeView objects (EmployeeViewBuilder), and its concrete implementation (SimpleEmployeeViewBuilder):
As you can see, SimpleEmployeeViewBuilder builds each part of the View object directly using data access API (in our example, Hibernate API), retrieving only the data it needs.
And, if you have a different employee view page, just implement a different EmployeeView with related EmployeeViewBuilder!
Finally, your Builder objects will have to be used in the Service layer, into view specific methods:
I'd like to know your opinion, every feedback is welcome.
Happy building!
Updates
07/25/2006 : Improved example code (thanks to Christofer Jennings).
View objects, as I see them, are a kind of DTOs without the burden of DTOs.
While DTOs represent and duplicate domain objects data, View objects simply represent data requested by a view and extracted from one or more domain objects.
What's more important, they cannot be used as replacements of domain objects, because they are immutable containers of simple data.
So, their use is (and must be) restricted to those scenarios where you need read only report-style views and fast performances.
What about View objects construction?
Like discussed in this post from the Domain-Driven Design group, there are different possibilities.
I think the best one is to use the Builder pattern:
Separate the construction of a complex object from its representation so that the same construction process can create different representations.
You can use the Builder pattern for implementing build methods that directly access the data store for constructing different parts of the View object.
This gives you the following advantages:
- You can separate the process of building your View object in different steps, and use only the steps you need for a particular view page, without even having to construct the full View object.
- You can have a generic ObjectAViewBuilder with generic buildPartA() and buildPartB() steps, and then having subclasses specify what data you actually need for every given step, i.e. depending on a particular view page.
This gives you better performances and higher flexibility.
Let us go now with a simple example.
Say we have two domain objects: Employee and Office (I'm not going to show interfaces here because they are of no interest in our context).
@Entity()
@Table(name="Employee")
@Proxy(proxyClass=Employee.class)
public class EmployeeImpl implements Employee {
@Id()
private int id;
@Version()
private int version;
@Column(unique=true)
private String matriculationCode;
private String firstname;
private String surname;
@ManyToOne(targetEntity=OfficeImpl.class)
private Office office;
protected EmployeeImpl() {}
public EmployeeImpl(String matriculationCode) {
this.matriculationCode = matriculationCode;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getMatriculationCode() {
return matriculationCode;
}
public Office getOffice() {
return this.office;
}
public void setOffice(Office office) {
this.office = office;
}
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof Employee)) return false;
Employee other = (Employee) obj;
return new EqualsBuilder().append(this.getMatriculationCode(), other.getMatriculationCode()).isEquals();
}
public int hashCode() {
return new HashCodeBuilder().append(this.getMatriculationCode()).toHashCode();
}
}
@Entity()
@Table(name="Office")
@Proxy(proxyClass=Office.class)
public class OfficeImpl implements Office {
@Id()
private int id;
@Version()
private int version;
@Column(unique=true)
private String officeId;
private String name;
protected OfficeImpl() {}
public OfficeImpl(String officeId, String name) {
this.officeId = officeId;
this.name = name;
}
public String getName() {
return name;
}
public String getOfficeId() {
return officeId;
}
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof Office)) return false;
Office other = (Office) obj;
return new EqualsBuilder().append(this.getOfficeId(), other.getOfficeId()).isEquals();
}
public int hashCode() {
return new HashCodeBuilder().append(this.getOfficeId()).toHashCode();
}
}
The two domain entities are annotated with EJB3 annotations, so they are persistent objects.
Now, your application needs some report-style view listing a few employees data, but you don't want to get the full Employee object graph: so you create a marker EmployeeView interface for representing employee related views, and an extended interface for showing just some simple data from an employee and its related office, the SimpleEmployeeView (with related implementation):
public interface EmployeeView extends Serializable {
}
public interface SimpleEmployeeView extends EmployeeView {
public String getMatriculationCode();
public String getFirstname();
public String getSurname();
public String getOfficeName();
}
public class SimpleEmployeeViewImpl implements SimpleEmployeeView {
private String matriculationCode;
private String firstname;
private String surname;
private String officeName;
public String getMatriculationCode() {
return matriculationCode;
}
public void setMatriculationCode(String matriculationCode) {
this.matriculationCode = matriculationCode;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getOfficeName() {
return officeName;
}
public void setOfficeName(String officeName) {
this.officeName = officeName;
}
}
Please note: the view implementation has setters method, while the interface has not. This is because the view (hence its interface) has to be immutable, but setter methods must be used by the builder for constructing the View object.
Once you have some View object, you need a Builder!
So here is the generic Builder interface for constructing generic EmployeeView objects (EmployeeViewBuilder), and its concrete implementation (SimpleEmployeeViewBuilder):
public interface EmployeeViewBuilder {
public void buildEmployee(String matriculationCode);
public void buildEmployeeOffice();
public EmployeeView getEmployeeView();
}
public class SimpleEmployeeViewBuilder implements EmployeeViewBuilder {
private HibernateTemplate hibernateTemplate;
private SimpleEmployeeViewImpl view = new SimpleEmployeeViewImpl();
public void buildEmployee(String matriculationCode) {
List<Object[]> result = hibernateTemplate.find("select e.matriculationCode, e.firstname, e.surname from com.blogspot.sbtourist.domain.EmployeeImpl e where e.matriculationCode = ?", matriculationCode);
for (Object[] values : result) {
view.setMatriculationCode((String) values[0]);
view.setFirstname((String) values[1]);
view.setSurname((String) values[2]);
}
}
public void buildEmployeeOffice() {
if (view.getMatriculationCode() == null) {
throw new IllegalStateException("First call buildEmployee() method!");
}
List<String> result = hibernateTemplate.find("select e.office.name from com.blogspot.sbtourist.domain.EmployeeImpl e where e.matriculationCode = ?", view.getMatriculationCode());
for (String value : result) {
view.setOfficeName(value);
}
}
public SimpleEmployeeView getEmployeeView() {
return this.view;
}
public HibernateTemplate getHibernateTemplate() {
return hibernateTemplate;
}
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}
}
As you can see, SimpleEmployeeViewBuilder builds each part of the View object directly using data access API (in our example, Hibernate API), retrieving only the data it needs.
And, if you have a different employee view page, just implement a different EmployeeView with related EmployeeViewBuilder!
Finally, your Builder objects will have to be used in the Service layer, into view specific methods:
public EmployeeView getEmployeeWithOfficeView(String employeeMatriculationCode) {
EmployeeViewBuilder builder = new SimpleEmployeeViewBuilder();
builder.buildEmployee(employeeMatriculationCode);
builder.buildEmployeeOffice();
return builder.getEmployeeView();
}
I'd like to know your opinion, every feedback is welcome.
Happy building!
Updates
07/25/2006 : Improved example code (thanks to Christofer Jennings).
Labels:
Design-Patterns,
Java,
Object-Oriented-Programming
Friday, July 14, 2006
Spring Modules 0.5 and the XT Framework
Today, Spring Modules 0.5 has been released.
It contains a lot of improvements, as you can read from the announcement, among which you can find my main contribution to the project: the brand new Spring Modules XT Framework.
Born toward the end of the last year as SpringXT, you can find its old (never publicly announced) home page here, I'm proud and happy to say it is now a top level module of Spring Modules!
What is it?
Spring Modules XT, strongly influenced by modern Domain-Driven Design techniques and Ajax technologies, has a main aim: let you develop simple-to-complex business applications with your domain model in mind, and let you easily and powerfully construct the presentation layer of your domain model thanks to Spring MVC and Ajax techniques.
So, it provides an XT Modeling Framework, implementing Domain-Driven Design and AOP based techniques for enhancing your domain model, and XT Ajax Framework, an Ajax implemention which doesn't require you to learn any other framework or deeply change your application, because completely built on (and thought for) Spring MVC.
I invite you to take a look at its documentation and play with it.
It is just at its first stable release and it needs a lot of feedback!
Above all that, give the whole Spring Modules project a look, pick the module you need ... and let us know through its forum and mailing lists!
It contains a lot of improvements, as you can read from the announcement, among which you can find my main contribution to the project: the brand new Spring Modules XT Framework.
Born toward the end of the last year as SpringXT, you can find its old (never publicly announced) home page here, I'm proud and happy to say it is now a top level module of Spring Modules!
What is it?
Spring Modules XT, strongly influenced by modern Domain-Driven Design techniques and Ajax technologies, has a main aim: let you develop simple-to-complex business applications with your domain model in mind, and let you easily and powerfully construct the presentation layer of your domain model thanks to Spring MVC and Ajax techniques.
So, it provides an XT Modeling Framework, implementing Domain-Driven Design and AOP based techniques for enhancing your domain model, and XT Ajax Framework, an Ajax implemention which doesn't require you to learn any other framework or deeply change your application, because completely built on (and thought for) Spring MVC.
I invite you to take a look at its documentation and play with it.
It is just at its first stable release and it needs a lot of feedback!
Above all that, give the whole Spring Modules project a look, pick the module you need ... and let us know through its forum and mailing lists!
Tuesday, July 11, 2006
Avoid your getters and setters, Part 1
In the Java world, getters and setters are one of those things everyone says to hate but everyone actually uses.
I think this is mainly because:
In a series of blog posts called Avoid your getters and setters, I'll try to show you some ideas for avoiding getters and setters, by simply applying some fundamental Object Oriented and Domain Driven Design principles.
Any feedback will be highly appreciated.
Let's go!
Avoid your getters and setters: Programming to an Interface
From the GOF book:
This is probably the main Object Oriented principle: we could write words and words about it, but I prefer to remind you some good books like the one cited above, or like this one.
Programming to an interface is the first step toward good OO code.
Moreover, and here we come to our point, if you program to an interface, and think in terms of interfaces, you can better choose the getters and setters you need, while removing or hiding the unwanted ones.
First, thinking in terms of interfaces is thinking in terms of contracts.
Say you have a Customer entity in your domain model.
How does it interact with other entities?
What are its behaviours?
What its pre / post conditions and invariants?
That is: what is the contract defined by the Customer interface?
You may have an issue(Order ) method, and you may discover you need to know, for business reasons, the customer code.
So, here is our Customer interface:
Think always in terms of business contracts: all methods in your interfaces must have a business meaning.
Obviously, also getters and setters can have business meaning, which is the case of getCustomerCode().
All getters and setters without this meaning must be removed from the interface.
Here it comes your preferred ORM tool or Web Framework: it requires a lot of setters and getters for writing and reading properties, and you really don't want to do all that dirty job by hand!
What to do?
Too bad, we cannot actually avoid all those getters and setters, but we can hide them from your code simply declaring them in your concrete classes, and leaving them out from interfaces: your code, depending on interfaces, will never see all those unwanted methods!.
So you have a Customer concrete class:
What really hurts is the setSurname() method: in your business, once defined a customer's surname should never change!
But, hey: your code is written in terms of the Customer interface, so it will not be able to call unwanted methods!
Moreover, under the hood they actually are CustomerImpl objects, so your Web or ORM frameworks will be able to call all getters and setters thanks to Java reflection!

That's all.
And it's awful simple.
I hope to have explained well how you can hide getters and setters by simply programming to interfaces, while still using common frameworks.
In my next Avoid your getters and setters post we'll talk about the expert pattern ... in the meantime, let me know what do you think!
I think this is mainly because:
- They are procedural, heritage of C-style (or even older) programming.
- They are a practice embedded by JavaBeans conventions.
- Many ORM and Web frameworks heavily use getters and setters.
In a series of blog posts called Avoid your getters and setters, I'll try to show you some ideas for avoiding getters and setters, by simply applying some fundamental Object Oriented and Domain Driven Design principles.
Any feedback will be highly appreciated.
Let's go!
Avoid your getters and setters: Programming to an Interface
From the GOF book:
Don't declare variables to be instances of particular concrete classes. Instead, commit only to an interface
defined by an abstract class.
This is probably the main Object Oriented principle: we could write words and words about it, but I prefer to remind you some good books like the one cited above, or like this one.
Programming to an interface is the first step toward good OO code.
Moreover, and here we come to our point, if you program to an interface, and think in terms of interfaces, you can better choose the getters and setters you need, while removing or hiding the unwanted ones.
First, thinking in terms of interfaces is thinking in terms of contracts.
Say you have a Customer entity in your domain model.
How does it interact with other entities?
What are its behaviours?
What its pre / post conditions and invariants?
That is: what is the contract defined by the Customer interface?
You may have an issue(Order ) method, and you may discover you need to know, for business reasons, the customer code.
So, here is our Customer interface:
public interface Customer {
public String getCustomerCode();
public void issue(Order newOrder);
}
Think always in terms of business contracts: all methods in your interfaces must have a business meaning.
Obviously, also getters and setters can have business meaning, which is the case of getCustomerCode().
All getters and setters without this meaning must be removed from the interface.
Here it comes your preferred ORM tool or Web Framework: it requires a lot of setters and getters for writing and reading properties, and you really don't want to do all that dirty job by hand!
What to do?
Too bad, we cannot actually avoid all those getters and setters, but we can hide them from your code simply declaring them in your concrete classes, and leaving them out from interfaces: your code, depending on interfaces, will never see all those unwanted methods!.
So you have a Customer concrete class:
public class CustomerImpl implements Customer{
...
public String getCustomerCode() { ... }
public void issue(Order newOrder) { ... }
// Setters and getters not in the interface:
public void setSurname(String surname) { ... }
public String getSurname() { ... }
}
What really hurts is the setSurname() method: in your business, once defined a customer's surname should never change!
But, hey: your code is written in terms of the Customer interface, so it will not be able to call unwanted methods!
public class CustomerService {
public void register(Customer c) { ... }
}
public class CustomerDAO {
public void save(Customer c) { ... }
}
Moreover, under the hood they actually are CustomerImpl objects, so your Web or ORM frameworks will be able to call all getters and setters thanks to Java reflection!

That's all.
And it's awful simple.
I hope to have explained well how you can hide getters and setters by simply programming to interfaces, while still using common frameworks.
In my next Avoid your getters and setters post we'll talk about the expert pattern ... in the meantime, let me know what do you think!
Labels:
Design-Patterns,
Java,
Object-Oriented-Programming
Saturday, July 08, 2006
Java should provide interface level equality
While working to a business domain model in a pure Object Oriented approach, one thing I miss in Java is the concept, hence the implementation, of type equality, where for type I mean interface.
Let me explain with a simple example.
Say you have a Customer entity, that in your domain model is an interface, that is, a type:
You have different concrete Customer implementations, i.e. StandardCustomer and PremiumCustomer, but customer equality is the same for all customers, because defined by the customer code: so, you want to define equality for the Customer type.
Too bad, in Java the only way to go is to implement a base class for all customers, defining, among other methods, the equals() one:
However, this is not correct, nor safe, because you could implement another Customer directly implementing the interface, or even extending another base class: doing so, you would break the equals contract.
For example:
Now, a StandardCustomer is equal to a CustomerOfTheMonth, but a CustomerOfTheMonth is not equal to a StandardCustomer!
This is because BaseCustomer defines equality for all Customers, but CustomerOfTheMonth, while being a Customer, is not a base one!
So, the symmetry of the equals() method is broken!
The problem would be solved if we could implement the equals() method into the Customer interface, rather than into the BaseCustomer concrete class: if you had then to implement equality in a different way for some concrete class, you'd be also free to overwrite it later!
Here we come back to the beginning of my post: why doesn't Java provide interface level equality?
Let me explain with a simple example.
Say you have a Customer entity, that in your domain model is an interface, that is, a type:
public interface Customer {
public String getCustomerCode();
public String getSurname();
public Date getBirthdate();
}
You have different concrete Customer implementations, i.e. StandardCustomer and PremiumCustomer, but customer equality is the same for all customers, because defined by the customer code: so, you want to define equality for the Customer type.
Too bad, in Java the only way to go is to implement a base class for all customers, defining, among other methods, the equals() one:
public abstract class BaseCustomer implements Customer {
public String getCustomerCode() { ... }
public String getSurname() { ... }
public Date getBirthdate() { ... }
public boolean equals(Object obj) {
if ((obj == null) || (!(obj instanceof Customer))) return false;
Customer other = (Customer) obj;
return this.getCustomerCode().equals(other.getCustomerCode());
}
}
public class StandardCustomer extends BaseCustomer {
...
}
public class PremiumCustomer extends BaseCustomer {
...
}
However, this is not correct, nor safe, because you could implement another Customer directly implementing the interface, or even extending another base class: doing so, you would break the equals contract.
For example:
public class CustomerOfTheMonth implements Customer {
public String getCustomerCode() { ... }
public String getSurname() { ... }
public Date getBirthdate() { ... }
// You forget to implement equals(), or maybe implement a different one ....
}
Now, a StandardCustomer is equal to a CustomerOfTheMonth, but a CustomerOfTheMonth is not equal to a StandardCustomer!
This is because BaseCustomer defines equality for all Customers, but CustomerOfTheMonth, while being a Customer, is not a base one!
So, the symmetry of the equals() method is broken!
The problem would be solved if we could implement the equals() method into the Customer interface, rather than into the BaseCustomer concrete class: if you had then to implement equality in a different way for some concrete class, you'd be also free to overwrite it later!
Here we come back to the beginning of my post: why doesn't Java provide interface level equality?
Tuesday, July 04, 2006
A great day
About one month has passed since the last time I've made a post.
I'm very busy at the moment, but today is a great day.
I'd like to say I'm very proud of being, from now on, a Spring Modules committer!

Thank you very much to Costin Leau, the Spring Modules Lead, and the whole team: I'll try to do my best!
What will be my involvement in Spring Modules?
Stay tuned, I'll let you know in another post.
I'm very busy at the moment, but today is a great day.
I'd like to say I'm very proud of being, from now on, a Spring Modules committer!

Thank you very much to Costin Leau, the Spring Modules Lead, and the whole team: I'll try to do my best!
What will be my involvement in Spring Modules?
Stay tuned, I'll let you know in another post.
Sunday, June 11, 2006
Solving Method Contract Problems
In these last days an interesting discussion about the final Java keyword took place in many sites and blogs: take a look here and here.
I don't want to add my opinion about that because everything has been already discussed.
What caught my attention was the following statement in this very interesting blog post by Elliotte Rusty Harold:
I'm a huge fan of Design By Contract principles and agree with Elliotte in many points.
However, what I disagree with is how he solves the problem of maintaining the correct post-conditions on the getHours() method of Clock, that is, adding a getMilitaryHours() to MilitaryClock.
Why do I disagree?
Say you have a Display object for displaying time information through a Clock object, thanks to a displayTime(Clock c) method.
If Display.displayTime(Clock c) calls c.getHours() for obtaining the right hour time, it will not work with a 24 hours based MilitaryClock, because it will always display a 12 hours based Clock even if the actual Clock instance is a MilitaryClock!
Following Elliotte solution, Display should call getMilitaryHours(), but how?
Display doesn't know the actual type of Clock!
Moreover, adding a getMilitaryHours() method doesn't stop the client to use the standard getHours() method! Is this correct? Does the 12 hours based method make some sense for a MilitaryClock?
So, I see two solutions.
The first one: designing a Clock interface and two concrete implementations: StandardClock and MilitaryClock.
The Clock interface will have a getHours() method documenting the weaker applicable post-conditions, that is, an hour value between 0 and 23.
The StandardClock will strengthen the post-condition, outputting only values between 0 and 12.
The MilitaryClock will leave the post-condition as is.
This is safe and doesn't break any contract.
Elliotte could answer that interfaces are bad because don't let you verify conditions, forcing you to simply document them, and implementors to read your documentation.
I should write a whole blog post about this, but for now let me simply say that the value of interfaces is worth the price to pay. Surely.
The second solution: suppressing the getHours() method and implement a Clock.display() method, assigning to clock the responsability of displaying itself whatever time format it use, and let Display.displayTime(Clock c) call c.display().
Maybe Elliotte example was oversimplified, or his solution referred to a situation where you cannot change the base class (Clock), but simply saying that the solution to a "contract conditions problem" is adding another method, is IMHO a bit misleading.
My two euro cents.
What's your opinion about this?
I don't want to add my opinion about that because everything has been already discussed.
What caught my attention was the following statement in this very interesting blog post by Elliotte Rusty Harold:
It is a general principle of object oriented programming that an instance of the subclass can be used anywhere an instance of the superclass is expected. This is the very
definition of polymorphism. This means that the subclasses must maintain the class invariants and postconditions of their superclasses because client code might be depending
on those invariants and postconditions. Failure to do so is a contract violation. For example, if a Clock class promises that the getHours() method always returns a value
between 1 and 12, then this must still be true for a MilitaryClock subclass’s getHours() method. The MilitaryClock subclass can add a different getMilitaryHours() method that
returns a value between 0 and 23. However it must not violate the rule that getHours() always returns a number between 1 and 12.
I'm a huge fan of Design By Contract principles and agree with Elliotte in many points.
However, what I disagree with is how he solves the problem of maintaining the correct post-conditions on the getHours() method of Clock, that is, adding a getMilitaryHours() to MilitaryClock.
Why do I disagree?
Say you have a Display object for displaying time information through a Clock object, thanks to a displayTime(Clock c) method.
If Display.displayTime(Clock c) calls c.getHours() for obtaining the right hour time, it will not work with a 24 hours based MilitaryClock, because it will always display a 12 hours based Clock even if the actual Clock instance is a MilitaryClock!
Following Elliotte solution, Display should call getMilitaryHours(), but how?
Display doesn't know the actual type of Clock!
Moreover, adding a getMilitaryHours() method doesn't stop the client to use the standard getHours() method! Is this correct? Does the 12 hours based method make some sense for a MilitaryClock?
So, I see two solutions.
The first one: designing a Clock interface and two concrete implementations: StandardClock and MilitaryClock.
The Clock interface will have a getHours() method documenting the weaker applicable post-conditions, that is, an hour value between 0 and 23.
The StandardClock will strengthen the post-condition, outputting only values between 0 and 12.
The MilitaryClock will leave the post-condition as is.
This is safe and doesn't break any contract.
Elliotte could answer that interfaces are bad because don't let you verify conditions, forcing you to simply document them, and implementors to read your documentation.
I should write a whole blog post about this, but for now let me simply say that the value of interfaces is worth the price to pay. Surely.
The second solution: suppressing the getHours() method and implement a Clock.display() method, assigning to clock the responsability of displaying itself whatever time format it use, and let Display.displayTime(Clock c) call c.display().
Maybe Elliotte example was oversimplified, or his solution referred to a situation where you cannot change the base class (Clock), but simply saying that the solution to a "contract conditions problem" is adding another method, is IMHO a bit misleading.
My two euro cents.
What's your opinion about this?
Saturday, June 10, 2006
Spring Modules 0.4 released
The Spring Modules project has released today the 0.4 version: you can find the announcement here.
It is still under deep development and maybe not ready for certain production environments, but the modules I played with (or I read of) seem to be stable, and it contains a lot of interesting stuff.
In particular, I'm very interested in the Valang Validator, because writing Spring Validators in Java is often a very tedious and error-prone task: Valang is instead a simple, yet powerful, language for declaring validation rules and applying them to beans.
I think I'll write more about Valang in one of my next posts.
In the meantime, give it a try!
It is still under deep development and maybe not ready for certain production environments, but the modules I played with (or I read of) seem to be stable, and it contains a lot of interesting stuff.
In particular, I'm very interested in the Valang Validator, because writing Spring Validators in Java is often a very tedious and error-prone task: Valang is instead a simple, yet powerful, language for declaring validation rules and applying them to beans.
I think I'll write more about Valang in one of my next posts.
In the meantime, give it a try!
Monday, May 29, 2006
Caught by an iPod Nano
Ok, it finally happened some days ago: I bought a black Apple iPod Nano.
I don't generally fall in love with all those fashionable things (mmmhhhh ... maybe sometimes ...), but this time Apple caught me with its iPod Nano, and I have to say it's worth one's while.
You may know I'm a proud Linux user, so here are some tools you may want to use for making your iPod talking with your good Penguin:
If you have a modern Linux distribution, I strongly suggest you to give a try to amaroK 1.4.
Happy listening!
I don't generally fall in love with all those fashionable things (mmmhhhh ... maybe sometimes ...), but this time Apple caught me with its iPod Nano, and I have to say it's worth one's while.
You may know I'm a proud Linux user, so here are some tools you may want to use for making your iPod talking with your good Penguin:
- IPodSlave, an experimental KDE I/O slave for accessing your iPod from Konqueror and other applications supporting I/O slaves.
- GTKPod, a GTK application for managing your iPod, stable and fully working, but a bit ugly.
- amaroK, the best Linux media player, which in its latest 1.4 version comes with full iPod support, becoming a full replacement for Apple iTunes!
If you have a modern Linux distribution, I strongly suggest you to give a try to amaroK 1.4.
Happy listening!
Wednesday, May 24, 2006
Google Web Toolkit: The Next Big Hype
Let me say something about Google (I don't put links here because everyone knows).
I love Google Search Engine.
I love Google Mail.
I love Google Chat.
I think all those people at Google are great in creating advanced (and cool) applications.
This is what I think, and this is what a lot of people also think.
Now, too bad, thanks to this kind of leadership, everything Google produces gets acclaimed by the majority like the next big thing, without a small crumb of criticism.
This is the case of Google Web Toolkit (GWT).
GWT is the new born at Google: a framework for developing Ajax applications in Java.
Let me quote its web site:
GWT drove people literally crazy.
But before going to GWT web site and start playing with the new, acclaimed, next big thing, because everyone will do and you cannot be cut off, please think ...
Developers spend 90% of their time in developing and maintaining business components.
It is not true that you, as a developer, spend 90% of your time working around subtle incompatabilities between web browsers and platforms.
Developers should spend (and actually do) most of their time in developing the application domain model and all the business logic and components.
With GWT, developers will spend a lot of time in developing also the whole presentation layer. This is because ...
GWT makes Separation of Concerns absolutely unfeasible.
If Separation of Concerns is applied, developers can focus on business logic and only limited presentation logic, because talented web designers will do all the hard job with HTML and alike.
With GWT, developers must write every single web page like it was a SWING window, and if you think it will not be an hard job because you are a very talented Java developers, please consider ...
Writing SWING-like interfaces is a lot more difficult than writing HTML-like interfaces.
If you have ever developed a Java SWING application, you know what I'm talking about.
Moreover, consider a web application with dozens and dozens of web pages ... you'll end up with dozens and dozens of Java classes whose only job is constructing a web page.
Ooops.
Did I say that those Java classes construct your web pages?
I've been wrong: they are actually compiled into HTML+Javascript code, and it is that HTML+Javascript which makes up your web page.
Yes, because ...
GWT automatically generates HTML and Javascript code from your Java classes.
Just one thing: if the GWT compiler has one or more bugs, generating so wrong code, how difficult would be to debug and detect those bugs in the automatically generated JavaScript code?
Now, I'm not condemning GWT: it can be more than good for little to medium ui-centric web applications where developers can focus on presentation logic.
This is obviously my opinion: and I'm inviting you to be judgemental and have your opinion without taking as gold all Google gives to you.
I love Google Search Engine.
I love Google Mail.
I love Google Chat.
I think all those people at Google are great in creating advanced (and cool) applications.
This is what I think, and this is what a lot of people also think.
Now, too bad, thanks to this kind of leadership, everything Google produces gets acclaimed by the majority like the next big thing, without a small crumb of criticism.
This is the case of Google Web Toolkit (GWT).
GWT is the new born at Google: a framework for developing Ajax applications in Java.
Let me quote its web site:
Google Web Toolkit - Build AJAX apps in the Java language
Google Web Toolkit (GWT) is a Java software development framework that makes writing AJAX applications like Google Maps and Gmail easy for developers who don't speak browser quirks as a second language. Writing dynamic web applications today is a tedious and error-prone process; you spend 90% of your time working around subtle incompatabilities between web browsers and platforms, and JavaScript's lack of modularity makes sharing, testing, and reusing AJAX components difficult and fragile.
GWT lets you avoid many of these headaches while offering your users the same dynamic, standards-compliant experience. You write your front end in the Java programming language, and the GWT compiler converts your Java classes to browser-compliant JavaScript and HTML.
What is Google Web Toolkit?
Google Web Toolkit (GWT) is a Java development framework that lets you escape the matrix of technologies that make writing AJAX applications so difficult and error prone. With GWT, you can develop and debug AJAX applications in the Java language using the Java development tools of your choice. When you deploy your application to production, the GWT compiler to translates your Java application to browser-compliant JavaScript and HTML.
Here's the GWT development cycle:
- Use your favorite Java IDE to write and debug an application in the Java language, using as many (or as few) GWT libraries as you find useful.
- Use GWT's Java-to-JavaScript compiler to distill your application into a set of JavaScript and HTML files that you can serve with any web server.
- Confirm that your application works in each browser that you want to support, which usually takes no additional work.
GWT drove people literally crazy.
But before going to GWT web site and start playing with the new, acclaimed, next big thing, because everyone will do and you cannot be cut off, please think ...
Developers spend 90% of their time in developing and maintaining business components.
It is not true that you, as a developer, spend 90% of your time working around subtle incompatabilities between web browsers and platforms.
Developers should spend (and actually do) most of their time in developing the application domain model and all the business logic and components.
With GWT, developers will spend a lot of time in developing also the whole presentation layer. This is because ...
GWT makes Separation of Concerns absolutely unfeasible.
If Separation of Concerns is applied, developers can focus on business logic and only limited presentation logic, because talented web designers will do all the hard job with HTML and alike.
With GWT, developers must write every single web page like it was a SWING window, and if you think it will not be an hard job because you are a very talented Java developers, please consider ...
Writing SWING-like interfaces is a lot more difficult than writing HTML-like interfaces.
If you have ever developed a Java SWING application, you know what I'm talking about.
Moreover, consider a web application with dozens and dozens of web pages ... you'll end up with dozens and dozens of Java classes whose only job is constructing a web page.
Ooops.
Did I say that those Java classes construct your web pages?
I've been wrong: they are actually compiled into HTML+Javascript code, and it is that HTML+Javascript which makes up your web page.
Yes, because ...
GWT automatically generates HTML and Javascript code from your Java classes.
Just one thing: if the GWT compiler has one or more bugs, generating so wrong code, how difficult would be to debug and detect those bugs in the automatically generated JavaScript code?
Now, I'm not condemning GWT: it can be more than good for little to medium ui-centric web applications where developers can focus on presentation logic.
This is obviously my opinion: and I'm inviting you to be judgemental and have your opinion without taking as gold all Google gives to you.
Wednesday, May 17, 2006
Spring Hacks : Reflection Based Property Editors.
Property Editors are a J2SE feature used for editing JavaBeans properties from user interfaces, typically representing these properties as text values.
They are used in SpringMVC for similar purposes: representing and binding complex objects in web interfaces as they were simple, plain, properties.
A short example will clarify.
Say you have an Order owning a collection of Orders, each with its Product:
If you want to display Products in a web selection list, in order to assign a Product to a LineItem, you have to write in your JSP something like this:
For doing this, you have to write and configure a PropertyEditor for the Product object, in order to transform the Product object into a text value, specifically its code, and then directly bind the Product having its text representation.
The same applies if you want to bind a collection of LineItems to a Product:
You have to write a CustomCollectionEditor for the collection of LineItem objects, in order to convert the collection of line item codes to the corresponding collection of LineItems objects (take a look here for more info).
Writing PropertyEditors or CustomCollectionEditors is pretty simple: however, if you have to do a lot of bindings, each for a different object, you have to hand-write a lot of property editors, which is boring and error-prone.
Now, think a moment at how you usually transform objects to text values and vice-versa: you use an object property for obtaining a text representation (often an id), and use some kind of data access object for obtaining an object from a given text value (i.e., an object given its id).
So, let us write a generic property editor and a generic collection editor, using Java Reflection.
Here is the property editor:
And here the collection editor:
What they ask you to do is nothing more than configuring the following properties:
Then, Java Reflection will do all the boring job.
Moreover, those property editors are best configured in the Spring container:
Comments and suggestions are welcome.
Hope you'll find this useful!
They are used in SpringMVC for similar purposes: representing and binding complex objects in web interfaces as they were simple, plain, properties.
A short example will clarify.
Say you have an Order owning a collection of Orders, each with its Product:
public class Order {
public String getOrderCode() { ... }
public ListgetLineItems() { ... }
}
public class LineItem {
public String getItemCode() { ... }
public Product getProduct() { ... }
}
public class Product {
public String getCode() { ... }
public String getName() { ... }
}
If you want to display Products in a web selection list, in order to assign a Product to a LineItem, you have to write in your JSP something like this:
<spring:bind path="command.product">
<select name="${status.expression}">
<c:forEach items="${products}" var="p">
<spring:transform value="${p}" var="pCode"/>
<option value="${pCode}">${p.name}</option>
</c:forEach>
</spring:bind>
For doing this, you have to write and configure a PropertyEditor for the Product object, in order to transform the Product object into a text value, specifically its code, and then directly bind the Product having its text representation.
The same applies if you want to bind a collection of LineItems to a Product:
<spring:bind path="command.lineItems">
<c:forEach items="${items}" var="item">
<input type="checkbox" name="${status.expression}" value="${item.itemCode}"/>
.....
</c:forEach>
</spring:bind>
You have to write a CustomCollectionEditor for the collection of LineItem objects, in order to convert the collection of line item codes to the corresponding collection of LineItems objects (take a look here for more info).
Writing PropertyEditors or CustomCollectionEditors is pretty simple: however, if you have to do a lot of bindings, each for a different object, you have to hand-write a lot of property editors, which is boring and error-prone.
Now, think a moment at how you usually transform objects to text values and vice-versa: you use an object property for obtaining a text representation (often an id), and use some kind of data access object for obtaining an object from a given text value (i.e., an object given its id).
So, let us write a generic property editor and a generic collection editor, using Java Reflection.
Here is the property editor:
public class ReflectivePropertyEditor extends PropertyEditorSupport {
private Object dataAccessObject;
private String dataAccessMethod;
private String propertyName;
private PropertyEditor stringConvertor;
public String getAsText() {
if (this.getValue() == null) {
return null;
}
else {
Method method = null;
String result = null;
try {
BeanWrapperImpl wrapper = new BeanWrapperImpl(this.getValue());
result = wrapper.getPropertyValue(this.propertyName).toString();
}
catch(Exception ex) {
throw new ReflectiveCollectionEditorException("An error occurred while using: " + this.propertyName, ex);
}
return result;
}
}
public void setAsText(String textValue) {
try {
if (this.stringConvertor == null) {
Method method = this.dataAccessObject.getClass().getMethod(this.dataAccessMethod, new Class[]{String.class});
this.setValue(method.invoke(this.dataAccessObject, new Object[]{textValue}));
}
else {
this.stringConvertor.setAsText(textValue);
Object value = this.stringConvertor.getValue();
Method method = this.dataAccessObject.getClass().getMethod(this.dataAccessMethod, new Class[]{value.getClass()});
this.setValue(method.invoke(this.dataAccessObject, new Object[]{value}));
}
}
catch(Exception ex) {
throw new ReflectiveCollectionEditorException("An error occurred while executing: " + this.dataAccessMethod, ex);
}
}
public String getPropertyName() {
return this.propertyName;
}
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
public Object getDataAccessObject() {
return this.dataAccessObject;
}
public void setDataAccessObject(Object dataAccessObject) {
this.dataAccessObject = dataAccessObject;
}
public String getDataAccessMethod() {
return this.dataAccessMethod;
}
public void setDataAccessMethod(String dataAccessMethod) {
this.dataAccessMethod = dataAccessMethod;
}
public PropertyEditor getStringConvertor() {
return this.stringConvertor;
}
public void setStringConvertor(PropertyEditor stringConvertor) {
this.stringConvertor = stringConvertor;
}
}
And here the collection editor:
public class ReflectiveCollectionEditor extends CustomCollectionEditor {
private Object dataAccessObject;
private String dataAccessMethod;
private PropertyEditor stringConvertor;
public ReflectiveCollectionEditor(Class collection) {
super(collection);
}
public ReflectiveCollectionEditor(Class collection, boolean nullAsEmptyCollection) {
super(collection, nullAsEmptyCollection);
}
protected Object convertElement(Object element) {
if (!(element instanceof String)) {
new IllegalArgumentException("The element to convert must be of type java.lang.String");
}
String textValue = (String) element;
Object result = null;
try {
if (this.stringConvertor == null) {
Method method = this.dataAccessObject.getClass().getMethod(this.dataAccessMethod, new Class[]{String.class});
result = method.invoke(this.dataAccessObject, new Object[] {textValue});
}
else {
this.stringConvertor.setAsText(textValue);
Object value = this.stringConvertor.getValue();
Method method = this.dataAccessObject.getClass().getMethod(this.dataAccessMethod, new Class[]{value.getClass()});
result = method.invoke(this.dataAccessObject, new Object[] {value});
}
}
catch(Exception ex) {
throw new ReflectiveCollectionEditorException("An error occurred while executing: " + this.dataAccessMethod, ex);
}
return result;
}
public Object getDataAccessObject() {
return this.dataAccessObject;
}
public void setDataAccessObject(Object dataAccessObject) {
this.dataAccessObject = dataAccessObject;
}
public String getDataAccessMethod() {
return this.dataAccessMethod;
}
public void setDataAccessMethod(String dataAccessMethod) {
this.dataAccessMethod = dataAccessMethod;
}
public PropertyEditor getStringConvertor() {
return this.stringConvertor;
}
public void setStringConvertor(PropertyEditor stringConvertor) {
this.stringConvertor = stringConvertor;
}
}
What they ask you to do is nothing more than configuring the following properties:
- dataAccessObject : the object used for converting from a text value to the actual object; it could be a Factory, a DAO, or Repository.
- dataAccessMethod : the method, on the dataAccessObject, to call for converting from text to object.
- propertyName : the name of the property which will be used for the object text value (only in ReflectivePropertyEditor).
- stringConvertor : a PropertyEditor to use for converting the string value that will be passed as argument to the dataAccessMethod (required only if it takes as argument an object that is not a String).
Then, Java Reflection will do all the boring job.
Moreover, those property editors are best configured in the Spring container:
<bean id="productEditor" class="org.acme.ReflectivePropertyEditor">
<property name="dataAccessObject"><ref bean="productDAO"/></property>
<property name="dataAccessMethod"><value>getProduct</value></property>
<property name="propertyName"><value>code</value></property>
</bean>
<bean id="lineItemsCollectionEditor" class="org.acme.ReflectiveCollectionEditor">
<constructor-arg index="0"><value>java.util.Set</value></constructor-arg>
<property name="dataAccessObject"><ref bean="productDAO"/></property>
<property name="dataAccessMethod"><value>getLineItem</value></property>
</bean>
Comments and suggestions are welcome.
Hope you'll find this useful!
Thursday, May 11, 2006
Enhancing Composite Specifications with Message Notifications
In this blog entry we'll enhance our previous Composite Specifications implementation, in order to sending message notifications at evaluation time.
We'll take back some ideas from A notification strategy for business errors and related comments by Johannes Brodwall.
We'll use the same concept of Notification object, but intended as a carrier of generic messages (not only errors).
So, let's start with some code.
First, we need a simple Message class.
It is very simple and contains just the message code (intended to be resolved using i18n), and a default message string.
We need also the Notification class, for carrying messages all around.
The most important thing to note is that you can add generic messages and assign them a notification type: ERROR, WARNING or INFO.
This actually classify your messages and let clients do different actions based on the notification type.
How to integrate this with our CompositeSpecification?
First, let us modify the base Specification interface:
Now you have:
We've finally arrived to the new CompositeSpecification.
Here I'll show only the CompositeSpecification interface: I'm not going to show the complete code for managing Notifications because it would clutter all the blog entry.
All this stuff will be released soon as part of an Open Source project, so those interested will be able soon to take a look at the whole implementation.
Here is the refined CompositeSpecification interface:
The most important things are:
So, considering our example classes (defined here), you can now write something like this:
Here is how you can read the composite specification declaration: compose the specification defining the office id structure, with an error message notification to be fired when not satisfied, and the specification defining when the office is full, with a warning message notification to be fired when satisfied.
After evaluation, you'll have your notification object filled with all message notifications fired by the composite specification (obviously, if any).
Suggestions and every type of feedback are welcome!
We'll take back some ideas from A notification strategy for business errors and related comments by Johannes Brodwall.
We'll use the same concept of Notification object, but intended as a carrier of generic messages (not only errors).
So, let's start with some code.
First, we need a simple Message class.
public interface Message {
/**
* Set the message code.
* @param code The code to set.
*/
public void setCode(String code);
/**
* Get the message code.
* @return The message code.
*/
public String getCode();
/**
* Set the default message string of this message object.
* @param message The default message string.
*/
public void setDefaultMessage(String message);
/**
* Get the default message string of this message object.
* @return The default message string.
*/
public String getDefaultMessage();
}
It is very simple and contains just the message code (intended to be resolved using i18n), and a default message string.
We need also the Notification class, for carrying messages all around.
public interface Notification {
public enum Type { ERROR, WARNING, INFO };
/**
* Add a message.
* @param message The message to add.
* @param type The notification type of the message to add.
*/
public void addMessage(Message message, Notification.Type type);
/**
* Remove a message.
* @param message The message to remove.
* @param type The notification type of the message to remove.
* @return True if removed.
*/
public boolean removeMessage(Message message, Notification.Type type);
/**
* Get messages of the given type.
* @param type The type of messages to retrieve.
* @return An array of messages.
*/
public Message[] getMessages(Notification.Type type);
/**
* Check if this notification has messages of the given type.
* @param type The type of messages to look for.
* @return True if this notification has messages of the given type,
* false otherwise.
*/
public boolean hasMessages(Notification.Type type);
/**
* Get all messages contained in this notification.
* @return An array of messages.
*/
public Message[] getAllMessages();
/**
* Check if this notification has messages of whatever type.
* @return True if this notification has messages,
* false otherwise.
*/
public boolean hasMessages();
/**
* Add to this notification all the messages contained in the notification in argument.
* @param notification The notification whose messages must be added.
*/
public void addAllMessages(Notification notification);
}
The most important thing to note is that you can add generic messages and assign them a notification type: ERROR, WARNING or INFO.
This actually classify your messages and let clients do different actions based on the notification type.
How to integrate this with our CompositeSpecification?
First, let us modify the base Specification interface:
public interface Specification<O> {
/**
* Specification evaluation method.
*
* @param object The object to evaluate.
* @return True if satisfied, false otherwise.
*/
public boolean evaluate(O object);
/**
* Specification evaluation method, with a Notification object for collecting error messages.
*
* @param object The object to evaluate.
* @param notification A notification object where errors regarding specification evaluation will be put.<br>
* It can be left <code>null</code> if not used.
* @return True if satisfied, false otherwise.
*/
public boolean evaluate(O object, Notification notification);
/**
* Add a notification message to be notified by this specification.
*
* @param message The message to add.
* @param type The notification type of the message.
* @param whenSatisfied True if the message must be notified when the specification gets satisfied,
* false if notified when unsatisfied.
*/
public void addNotificationMessage(Message message, Notification.Type type, boolean whenSatisfied);
/**
* Remove a notification message.
*
* @param message The message to remove.
* @param type The notification type of the message.
* @param whenSatisfied True if the message was to be notified once satisfied,
* false otherwise.
* @return True if removed.
*/
public boolean removeNotificationMessage(Message message, Notification.Type type, boolean whenSatisfied);
}
Now you have:
- The old evaluate(Object o) method, to be used when you're not interested in notifications.
- A new evaluate(Object o, Notification n) method, where the Notification object in argument will collect message notifications fired by the specification.
- Te addNotificationMessage(Message message, Notification.Type type, boolean whenSatisfied); method: it is used not only to add the message notifications the specification can fire, but also to define their notification type and when to fire them.
Doing so, you can specify what (and what type of) message notifications to fire when the specification gets satisfied, and what to fire when not satisfied.
We've finally arrived to the new CompositeSpecification.
Here I'll show only the CompositeSpecification interface: I'm not going to show the complete code for managing Notifications because it would clutter all the blog entry.
All this stuff will be released soon as part of an Open Source project, so those interested will be able soon to take a look at the whole implementation.
Here is the refined CompositeSpecification interface:
public interface CompositeSpecification<S, O> extends Specification<O> {
/**
* Apply the logical <code>and</code> operator to this composite specification and another, supplied, composite specificaton.
* @param specification The other composite specification.
*/
public CompositeSpecification and(CompositeSpecification<S, O> specification);
/**
* Apply the logical <code>and</code> operator to this composite specification and the supplied one.
* @param specification The supplied specification to compose.
*/
public CompositeSpecification and(S specification);
/**
* Apply the logical, negated, <code>and</code> operator to this composite specification and another, supplied, composite specificaton.
* @param specification The other composite specification.
*/
public CompositeSpecification andNot(CompositeSpecification<S, O> specification);
/**
* Apply the logical, negated, <code>and</code> operator to this composite specification and the supplied one.
* @param specification The supplied specification to compose.
*/
public CompositeSpecification andNot(S specification);
/**
* Start composing the specification.<br>
* This is the first method to be called for composition.
*
* @param specification The actual specification to compose.
*/
public CompositeSpecification compose(S specification);
/**
* Add a notification message to the last composed specification.
* @param message The message to add.
* @param type The notification type of the message.
* @param whenSatisfied True if the message must be notified when the specification gets satisfied,
* false if notified when unsatisfied.
*/
public CompositeSpecification withMessage(Message message, Notification.Type type, boolean whenSatisfied);
/**
* Composite specification evaluation.
*
* @param object The object to evaluate.
*/
public boolean evaluate(O object);
/**
* Apply the logical <code>or</code> operator to this composite specification and another, supplied, composite specificaton.
* @param specification The other composite specification.
*/
public CompositeSpecification or(CompositeSpecification<S, O> specification);
/**
* Apply the logical <code>or</code> operator to this composite specification and the supplied one.
* @param specification The supplied specification to compose.
*/
public CompositeSpecification or(S specification);
/**
* Apply the logical, negated, <code>or</code> operator to this composite specification and another, supplied, composite specificaton.
* @param specification The other composite specification.
*/
public CompositeSpecification orNot(CompositeSpecification<S, O> specification);
/**
* Apply the logical, negated, <code>or</code> operator to this composite specification and the supplied one.
* @param specification The actual specification to compose.
*/
public CompositeSpecification orNot(S specification);
}
The most important things are:
- The evaluate(Object o, Notification n) method, inherited by the previously described Specification interface, to be used for collecting message notifications
from all the composed specifications. - The fluent-style CompositeSpecification withMessage(Message message, Notification.Type type, boolean whenSatisfied) method: it has to be used for defining a message notification fired by a composed specification (specifically, the last one added), its type and when it has to be fired.
So, considering our example classes (defined here), you can now write something like this:
CompositeSpecification<Example Specification> compositeSpecification = new CompositeSpecification<Specification>(ExampleSpecification.class, "isSatisfiedBy", IOffice.class);
OfficeIdSpecification spec1 = new OfficeIdSpecification();
FullOfficeSpecification spec2 = new FullOfficeSpecification();
IOffice office1 = new Office();
IEmployee emp1 = new Employee();
office1.setOfficeId("o1");
emp1.setMatriculationCode("1");
office1.addEmployee(emp1);
Notification notification = ...;
compositeSpecification.compose(spec1).withMessage(new Message(...), Notification.Type.ERROR, false)
.andNot(spec2).withMessage(new Message(...), Notification.Type.WARNING, true)
.evaluate(office1, notification);
Here is how you can read the composite specification declaration: compose the specification defining the office id structure, with an error message notification to be fired when not satisfied, and the specification defining when the office is full, with a warning message notification to be fired when satisfied.
After evaluation, you'll have your notification object filled with all message notifications fired by the composite specification (obviously, if any).
Suggestions and every type of feedback are welcome!
Monday, May 08, 2006
Implementing Composite Specifications
In my previous post, An idea for Composite Specifications, we took a look at how a composite specification could be structured and designed.
Now, we'll see how to concretely implement it, using (as always here in my blog, where not specified) the Java language.
Let us rewrite the composite specification interfaces:
Here are some main advantages of such an interface:
The CompositeSpecification let you compose custom specification with other CompositeSpecification: the first thing you need is an adapter for adapting custom types to the Specification interface:
This adapter encapsulate the object to adapt and use Java reflection to call the method that will actually evaluate the specification.
You may note the possibility to compose with the inverse of a specification, using the andNot and orNot operators: this is accomplished simply applying the following decorator:
It simply inverts the decorated specification.
Now we need to implement the logical operators.
I've made a first implementation using Apache Commons Predicate: it worked well, was very straightforward, but it was rather inefficient in terms of memory usage.
Due to the Commons Predicates implementation, you have to create a different Predicate object for every operator you use: so, considering a simple CompositeSpecification with just one logical and operator, used in one thousand different instances of a business object, you'll have one thousand of AndPredicate just for implementing an and operator which makes always the same task!
So, here is a shared implementation of logical operators, which uses the flyweight pattern; these are the involved classes:
You should note the following:
Last, but not least, the CompositeSpecification implementation:
The most important thing to note is how the composite specification is internally constructed and evaluated.
Each time a new specification is composed, the new specification and the operator used for composing are stored into two different lists acting as queues:
Then, when the evaluate() method gets called, each operator is applied to its corresponding specification, starting from the first one added:
Now, your CompositeSpecification is ready to be used:
Every feedback will be highly appreciated!
Updates:
09/05/2006 : Enhancements in explaining code snippets regarding logical operators.
Now, we'll see how to concretely implement it, using (as always here in my blog, where not specified) the Java language.
Let us rewrite the composite specification interfaces:
public interface Specification<O> {
public boolean evaluate(O o);
}
public interface CompositeSpecification<S, O> extends Specification<O> {
public CompositeSpecification compose(S specification);
public CompositeSpecification and(CompositeSpecification<S, O> specification);
public CompositeSpecification and(S specification);
public CompositeSpecification andNot(CompositeSpecification<S, O> specification);
public CompositeSpecification andNot(S specification);
public CompositeSpecification or(CompositeSpecification<S, O> specification);
public CompositeSpecification or(S specification);
public CompositeSpecification orNot(CompositeSpecification<S, O> specification);
public CompositeSpecification orNot(S specification);
public boolean evaluate(O object);
}
Here are some main advantages of such an interface:
- Composition using well known logical operators.
- Composition of custom specification types, without requiring to implement any particular interface.
- Highly declarative style of composition, thanks to a fluent interface.
The CompositeSpecification let you compose custom specification with other CompositeSpecification: the first thing you need is an adapter for adapting custom types to the Specification interface:
public class SpecificationGenericAdapter implements Specification {
private Object specification;
private Method specificationMethod;
public SpecificationGenericAdapter(Object specification, Method specificationMethod) {
this.specification = specification;
this.specificationMethod = specificationMethod;
}
public boolean evaluate(Object object) {
boolean result = false;
try {
Object tmp = this.specificationMethod.invoke(specification, object);
result = (Boolean) tmp;
}
catch(Exception ex) {
throw new SpecificationAdapterException("...", ex);
}
return result;
}
}
This adapter encapsulate the object to adapt and use Java reflection to call the method that will actually evaluate the specification.
You may note the possibility to compose with the inverse of a specification, using the andNot and orNot operators: this is accomplished simply applying the following decorator:
public class InverseSpecification implements Specification {
private Specification specification;
public InverseSpecification(Specification specification) {
this.specification = specification;
}
public boolean evaluate(Object o) {
return !this.specification.evaluate(o);
}
}
It simply inverts the decorated specification.
Now we need to implement the logical operators.
I've made a first implementation using Apache Commons Predicate: it worked well, was very straightforward, but it was rather inefficient in terms of memory usage.
Due to the Commons Predicates implementation, you have to create a different Predicate object for every operator you use: so, considering a simple CompositeSpecification with just one logical and operator, used in one thousand different instances of a business object, you'll have one thousand of AndPredicate just for implementing an and operator which makes always the same task!
So, here is a shared implementation of logical operators, which uses the flyweight pattern; these are the involved classes:
public interface BinaryOperator {
public boolean evaluate(Specification a, Specification b, Object o);
public boolean evaluate(Specification a, boolean b, Object o);
}
public class AndOperator implements BinaryOperator {
public boolean evaluate(Specification a, Specification b, Object o) {
return a.evaluate(o) && b.evaluate(o);
}
public boolean evaluate(Specification a, boolean b, Object o) {
return a.evaluate(o) && b;
}
}
public class OrOperator implements BinaryOperator {
public boolean evaluate(Specification a, Specification b, Object o) {
return a.evaluate(o) || b.evaluate(o);
}
public boolean evaluate(Specification a, boolean b, Object o) {
return a.evaluate(o) || b;
}
}
public class OperatorFactory {
private static final OperatorFactory factory = new OperatorFactory();
private BinaryOperator andOperator = new AndOperator();
private BinaryOperator orOperator = new OrOperator();
private OperatorFactory() {}
public static OperatorFactory getInstance() {
return factory;
}
public BinaryOperator getAndOperator() {
return this.andOperator;
}
public BinaryOperator getOrOperator() {
return this.orOperator;
}
}
You should note the following:
- The BinaryOperator evaluate() method takes as arguments not only the object to evaluate, but also the two specifications to apply (or a specification and an already computed boolean value): this is the so called extrinsic state, that is, state that cannot be shared because context dependent.
- The singleton OperatorFactory must be used in order to obtain shared operator instances: so, you don't have to directly construct operators.
Last, but not least, the CompositeSpecification implementation:
public class CompositeSpecificationImpl<S, O>
implements CompositeSpecification<S, O> {
private Class<S> specificationClass;
private Method specificationMethod;
private OperatorFactory operatorFactory = OperatorFactory.getInstance();
private List<Specification> specificationsList = new LinkedList<Specification>();
private List<BinaryOperator> operatorsList = new LinkedList<BinaryOperator>();
public CompositeSpecificationImpl(Class<S> specificationClass, String specificationMethod) {
this.specificationClass = specificationClass;
try {
Method[] methods = this.specificationClass.getDeclaredMethods();
for (Method m : methods) {
if (m.getName().equals(specificationMethod)) {
this.specificationMethod = m;
break;
}
}
if (this.specificationMethod == null) {
throw new SpecificationDescriptionException("...");
}
}
catch(SecurityException ex) {
throw new SpecificationDescriptionException("...");
}
}
public CompositeSpecification compose(S specification) {
this.specificationsList.clear();
this.operatorsList.clear();
this.specificationsList.add(this.adaptSpecification(specification));
return this;
}
public CompositeSpecification and(S specification) {
if (this.specificationsList.isEmpty()) {
throw new SpecificationNotComposedException("...");
}
this.operatorsList.add(this.operatorFactory.getAndOperator());
this.specificationsList.add(this.adaptSpecification(specification));
return this;
}
public CompositeSpecification or(S specification) {
if (this.specificationsList.isEmpty()) {
throw new SpecificationNotComposedException("...");
}
this.operatorsList.add(this.operatorFactory.getOrOperator());
this.specificationsList.add(this.adaptSpecification(specification));
return this;
}
public CompositeSpecification and(CompositeSpecification<S, O> specification) {
if (!specification.equals(this)) {
throw new IllegalArgumentException("...");
}
if (this.specificationsList.isEmpty()) {
throw new SpecificationNotComposedException("...");
}
this.operatorsList.add(this.operatorFactory.getAndOperator());
this.specificationsList.add(specification);
return this;
}
public CompositeSpecification or(CompositeSpecification<S, O> specification) {
if (!specification.equals(this)) {
throw new IllegalArgumentException("...");
}
if (this.specificationsList.isEmpty()) {
throw new SpecificationNotComposedException("...");
}
this.operatorsList.add(this.operatorFactory.getOrOperator());
this.specificationsList.add(specification);
return this;
}
public CompositeSpecification andNot(S specification) {
if (this.specificationsList.isEmpty()) {
throw new SpecificationNotComposedException("...");
}
this.operatorsList.add(this.operatorFactory.getAndOperator());
this.specificationsList.add(new InverseSpecification(this.adaptSpecification(specification)));
return this;
}
public CompositeSpecification orNot(S specification) {
if (this.specificationsList.isEmpty()) {
throw new SpecificationNotComposedException("...");
}
this.operatorsList.add(this.operatorFactory.getOrOperator());
this.specificationsList.add(new InverseSpecification(this.adaptSpecification(specification)));
return this;
}
public CompositeSpecification andNot(CompositeSpecification<S, O> specification) {
if (!specification.equals(this)) {
throw new IllegalArgumentException("...");
}
if (this.specificationsList.isEmpty()) {
throw new SpecificationNotComposedException("...");
}
this.operatorsList.add(this.operatorFactory.getAndOperator());
this.specificationsList.add(new InverseSpecification(specification));
return this;
}
public CompositeSpecification orNot(CompositeSpecification<S, O> specification) {
if (!specification.equals(this)) {...");
}
if (this.specificationsList.isEmpty()) {
throw new SpecificationNotComposedException("...");
}
this.operatorsList.add(this.operatorFactory.getOrOperator());
this.specificationsList.add(new InverseSpecification(specification));
return this;
}
public boolean evaluate(O object) {
if (this.specificationsList.isEmpty()) {
throw new SpecificationNotComposedException("...");
}
Iterator<Specification> specificationsIt = this.specificationsList.iterator();
boolean result = specificationsIt.next().evaluate(object);
for (BinaryOperator op : operatorsList) {
result = op.evaluate(specificationsIt.next(), result, object);
}
return result;
}
public boolean equals(Object obj) {
if (obj == null) return false;
if (! (obj instanceof CompositeSpecificationImpl)) {
return false;
}
else {
CompositeSpecificationImpl otherSpec = (CompositeSpecificationImpl) obj;
EqualsBuilder builder = new EqualsBuilder();
return builder.append(this.specificationClass,
otherSpec.specificationClass)
.append(this.specificationMethod,
otherSpec.specificationMethod)
.isEquals();
}
}
public int hashCode() {
HashCodeBuilder builder = new HashCodeBuilder();
return builder.append(this.specificationClass)
.append(this.specificationMethod)
.toHashCode();
}
private Specification adaptSpecification(S specification) {
return new SpecificationGenericAdapter(specification, this.specificationMethod);
}
}
The most important thing to note is how the composite specification is internally constructed and evaluated.
Each time a new specification is composed, the new specification and the operator used for composing are stored into two different lists acting as queues:
private List<Specification> specificationsList = new LinkedList<Specification>();
private List<BinaryOperator> operatorsList = new LinkedList<BinaryOperator>();
Then, when the evaluate() method gets called, each operator is applied to its corresponding specification, starting from the first one added:
Iterator<Specification> specificationsIt = this.specificationsList.iterator();
boolean result = specificationsIt.next().evaluate(object);
for (BinaryOperator op : operatorsList) {
result = op.evaluate(specificationsIt.next(), result, object);
}
return result;
Now, your CompositeSpecification is ready to be used:
compositeSpecification.compose(simpleSpecification1).and(simpleSpecification2).evaluate(objectToEvaluate);
Every feedback will be highly appreciated!
Updates:
09/05/2006 : Enhancements in explaining code snippets regarding logical operators.
Tuesday, May 02, 2006
An idea for Composite Specifications
Several days ago I've written some blog posts about how to work with and implement Specifications.
In particular, I've written one article about how to implement Specifications with Apache Commons Collections.
For a short recalling, we implemented Specifications using Commons Predicate as base interface, which let us combine those specifications using Commons PredicateUtils class.
This approach has two main disadvantages:
What about using a generic composite specification, capable of combining general specifications using logical operators, with a fluent-style interface?
Let us suddenly go with a simple example.
Take one office interface:
Take one employee interface:
You can create offices and add employees to them, but your boss said you have some business rules:
Say you want to implement those rules as Specifications (remember, this is an oversimplified example).
Here are your specifications:
And ... here is how would be our composite specification:
I intentionally omitted implementation details because at the moment I'd like to point you out:
Here is an example about how to use such a class:
I'll discuss implementation details in another post.
But for now, what do you think about this approach?
Updates:
04/05/2006 : Fixes in code.
In particular, I've written one article about how to implement Specifications with Apache Commons Collections.
For a short recalling, we implemented Specifications using Commons Predicate as base interface, which let us combine those specifications using Commons PredicateUtils class.
This approach has two main disadvantages:
- Force you to use the Commons Predicate interface which, for example, is not generics-enabled
- Give you a flexibility limited by Commons PredicateUtils capabilities.
What about using a generic composite specification, capable of combining general specifications using logical operators, with a fluent-style interface?
Let us suddenly go with a simple example.
Take one office interface:
public interface IOffice {
void setOfficeId(String officeId);
String getOfficeId();
void addEmployee(IEmployee e);
SetgetEmployees();
}
Take one employee interface:
public interface IEmployee extends Serializable {
void setMatriculationCode(String matriculationCode);
String getMatriculationCode();
}
You can create offices and add employees to them, but your boss said you have some business rules:
- Every office id must begin with the "o" letter, and follow with numbers.
- You cannot have an office with more than three employees.
Say you want to implement those rules as Specifications (remember, this is an oversimplified example).
Here are your specifications:
/**
* A generics-enabled specification interface.
*/
public interface Specification<T> {
public Boolean isSatisfiedBy(T object);
}
/**
* A specification for the office id.
*/
public class OfficeIdSpecification
implements Specification<IOffice> {
public Boolean isSatisfiedBy(IOffice o) {
return o.getOfficeId().matches("o\\d+");
}
}
/**
* A specification for the office room availability, determining
* if an office is full.
*/
public class FullOfficeSpecification
implements Specification<IOffice> {
private int limit = 3;
public Boolean isSatisfiedBy(IOffice o) {
return o.getEmployees().size() > this.limit;
}
}
And ... here is how would be our composite specification:
public class CompositeSpecification<T> {
public CompositeSpecification(Class<T> specificationClass,
String specificationMethod,
Class specificationObjectClass) {
// ...
}
public CompositeSpecification compose(T specification) {
// ...
}
public CompositeSpecification and(T specification) {
// ...
}
public CompositeSpecification or(T specification) {
// ...
}
public CompositeSpecification and(CompositeSpecification<T> specification) {
// ...
}
public CompositeSpecification or(CompositeSpecification<T> specification) {
// ...
}
public CompositeSpecification andNot(T specification) {
// ...
}
public CompositeSpecification orNot(T specification) {
// ...
}
public CompositeSpecification andNot(CompositeSpecification<T> specification) {
// ...
}
public CompositeSpecification orNot(CompositeSpecification<T> specification) {
// ...
}
public CompositeSpecification not() {
// ...
}
public boolean evaluate(Object object) {
// ...
}
}
I intentionally omitted implementation details because at the moment I'd like to point you out:
- The generics-enabled interface, which let you specify your own specification to combine.
- The constructor, where you have to describe the actual specification you'll combine, specifying its class, its specification method (isSatisfiedBy in our example) and the class of the specification object (IOffice in our example).
- The fluent-style interface methods for applying logical operators to actual specifications or other composite specifications.
Here is an example about how to use such a class:
CompositeSpecification<Specification> compositeSpecification =
new CompositeSpecification<Specification>(Specification.class,
"isSatisfiedBy",
IOffice.class);
OfficeIdSpecification spec1 = new OfficeIdSpecification();
FullOfficeSpecification spec2 = new FullOfficeSpecification();
IOffice office1 = new Office();
IEmployee emp1 = new Employee();
office1.setOfficeId("o1");
emp1.setMatriculationCode("1");
office1.addEmployee(emp1);
// The office has a valid id and is not full:
assertTrue(compositeSpecification.compose(spec1).andNot(spec2).evaluate(office1));
I'll discuss implementation details in another post.
But for now, what do you think about this approach?
Updates:
04/05/2006 : Fixes in code.
Sunday, April 23, 2006
Code that is worth reading
I must suggest you to read the following blog entry by Gregor Hohpe: March is Not a Number.
It well emphasises the importance of a well written, expressive, code, showing also another example of how fluent interfaces can help you write such a code.
Obviously, it is also related to Domain Driven Design!
Have a nice reading!
It well emphasises the importance of a well written, expressive, code, showing also another example of how fluent interfaces can help you write such a code.
Obviously, it is also related to Domain Driven Design!
Have a nice reading!
Tuesday, April 11, 2006
Is there some hope in Italy?
My blog friend Roni Burd recently blogged about his difficulties in founding money funds for going in United States and attending a Master in Software Engineering in the Carnegie Mellon college.
Roni comes from Argentina: its recent economic collapse left people savings very devaluated, and lowered people salaries to a mean, as Roni said, of about $ 18.000 per year for a good salary.
Italy situation is different in many aspects, but I have to say, Roni, that its economic situation is a disaster, and you are definitely not alone.
I know a lot of people here in Italy who studied/worked hard for years, and whose salary is near $ 18.000 per year, even lower.
Thanks, Mr. Silvio, thanks to you and all your cronies.
Now that Left seems to have won elections, maybe something will change.
Maybe.
I don't believe at all in our government, either Left or Right or whatever.
I don't believe in politicians ... maybe because I don't believe in humans ...
But I strongly know what is right and what is bad.
And Mr. Silvio Berlusconi is definitely bad for my country.
Good bye Mr. Silvio.
Good bye to you, your lies, your horses, your ghost horses.
Good bye.
Roni comes from Argentina: its recent economic collapse left people savings very devaluated, and lowered people salaries to a mean, as Roni said, of about $ 18.000 per year for a good salary.
Italy situation is different in many aspects, but I have to say, Roni, that its economic situation is a disaster, and you are definitely not alone.
I know a lot of people here in Italy who studied/worked hard for years, and whose salary is near $ 18.000 per year, even lower.
Thanks, Mr. Silvio, thanks to you and all your cronies.
Now that Left seems to have won elections, maybe something will change.
Maybe.
I don't believe at all in our government, either Left or Right or whatever.
I don't believe in politicians ... maybe because I don't believe in humans ...
But I strongly know what is right and what is bad.
And Mr. Silvio Berlusconi is definitely bad for my country.
Good bye Mr. Silvio.
Good bye to you, your lies, your horses, your ghost horses.
Good bye.
Saturday, April 08, 2006
New look, again
As you can notice, I've changed my blog look again.
I hope this new layout and colours will enhance your reading, in particular making it more relaxing ...
I must admit old colours were not so eye-relaxing, in particular for long posts ... but now they are a lot more readable and I also love this new look and feel!
The only thing I have to define is how to write long code snippets in a reasonable way and with a good layout ... I've played with PrettyPrinter and CodeColorizer ... I hope to find soon a good way of writing code snippets.
In the meanwhile, I'd be glad of knowing your opinion about this new look and feel, if you care to spend some words about it.
And again, have a nice reading!
I hope this new layout and colours will enhance your reading, in particular making it more relaxing ...
I must admit old colours were not so eye-relaxing, in particular for long posts ... but now they are a lot more readable and I also love this new look and feel!
The only thing I have to define is how to write long code snippets in a reasonable way and with a good layout ... I've played with PrettyPrinter and CodeColorizer ... I hope to find soon a good way of writing code snippets.
In the meanwhile, I'd be glad of knowing your opinion about this new look and feel, if you care to spend some words about it.
And again, have a nice reading!
Friday, April 07, 2006
Very busy ...
Hello all,
too bad, in these past weeks I've been very busy and I wasn't able to post anything.
I spent most of my time in refactoring a legacy corporate banking application, in order to make its core components using the Spring Framework for configuration and dependencies management.
However, I also spent a lot of time working on a brand new open source project aimed at extending the beautiful Spring Framework.
Born during the training on the job sessions about Spring I'm holding, backed by discussions with the Domain Driven Design community, after a lot of deep development, it will be ready soon for its first source release ...
Stay tuned!
too bad, in these past weeks I've been very busy and I wasn't able to post anything.
I spent most of my time in refactoring a legacy corporate banking application, in order to make its core components using the Spring Framework for configuration and dependencies management.
However, I also spent a lot of time working on a brand new open source project aimed at extending the beautiful Spring Framework.
Born during the training on the job sessions about Spring I'm holding, backed by discussions with the Domain Driven Design community, after a lot of deep development, it will be ready soon for its first source release ...
Stay tuned!
Wednesday, March 15, 2006
A notification strategy for business errors
In one of my past posts we talked about implementing specifications with Apache Commons Collections.
Recall: we used specifications for validating a requestGraduationThesis method of a Student object.
One common need, as emerged here, is to communicate the result of this validation in case something goes wrong.
That is, we need to transfer errors resulted from business methods to the layers above, the service or presentation layers.
Here, I propose an approach using a Notification object and a "business oriented" exception as a means of transporting.
A Notification object is a container of Error objects, carrying information about errors.
Here is a simple implementation:
Then, we need an exception for transporting our notification in the layers above, up till the layer interested in managing it:
Here, I used a checked exception because I think business errors should always be explicit, but if you think checked exception are too cluttering or invasive, you can safely use an unchecked one: I just suggest you to always declare your exceptions in javadocs.
Finally, we need to link together Errors with Specifications, and Notifications with Students:
Here is a simple main method for showing all this stuff:
Doing so, we still use wonderful specifications, avoiding the hard-to-manage validate() method, even if we need multiple error notifications to superior layers, and we do not write additional code for transporting them because we use existent language features.
An alternative implementation, as suggested by Martin Fowler, is to use event notification patterns.
We could explore this in another post.
In the meanwhile, what do you think about this?
Recall: we used specifications for validating a requestGraduationThesis method of a Student object.
One common need, as emerged here, is to communicate the result of this validation in case something goes wrong.
That is, we need to transfer errors resulted from business methods to the layers above, the service or presentation layers.
Here, I propose an approach using a Notification object and a "business oriented" exception as a means of transporting.
A Notification object is a container of Error objects, carrying information about errors.
Here is a simple implementation:
public class Notification {
private List errors = new LinkedList();
public List getErrors() {
return this.errors;
}
public boolean hasErrors() {
return errors.isEmpty();
}
public void addError(Error error) {
this.errors.add(error);
}
}
public class Error {
private String message;
public Error() {}
public Error(String message) {
this.message = message;
}
public String getMessage() {
return this.message;
}
public void setMessage(String message) {
this.message = message;
}
}
Then, we need an exception for transporting our notification in the layers above, up till the layer interested in managing it:
public class StudentException extends Exception {
private Notification notification;
public StudentException(Notification notification) {
this.notification = notification;
}
public Notification getNotification() {
return this.notification;
}
}
Here, I used a checked exception because I think business errors should always be explicit, but if you think checked exception are too cluttering or invasive, you can safely use an unchecked one: I just suggest you to always declare your exceptions in javadocs.
Finally, we need to link together Errors with Specifications, and Notifications with Students:
public class EnoughCreditsSpecification extends BaseSpecification {
private static final int min = 10;
private static final String errorMessage = "credits.error";
private Error error;
public boolean isSatisfiedBy(Student s) {
if (s.getTotalCredits() >= EnoughCreditsSpecification.min) {
return true;
}
else {
error = new Error(EnoughCreditsSpecification.errorMessage);
return false;
}
}
public Error getError() {
return this.error;
}
}
public class EnoughCoursesSpecification extends BaseSpecification {
private static final int min = 3;
private static final String errorMessage = "courses.error";
private Error error;
public boolean isSatisfiedBy(Student s) {
if (s.getTotalCourses() >= EnoughCoursesSpecification.min) {
return true;
}
else {
error = new Error(EnoughCoursesSpecification.errorMessage);
return false;
}
}
public Error getError() {
return this.error;
}
}
public class Student {
private int totalCourses;
private int totalCredits;
private boolean thesisRequested;
private List> 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.
*
* @throws StudentException If something with this student
* business method goes wrong ...
*/
public void requestGraduationThesis()
throws StudentException {
if (this.applyAllSpecs() == false) {
Notification n = new Notification();
for (BaseSpecification spec : this.graduationSpecs) {
if (spec.getError() != null) {
n.addError(spec.getError());
}
}
throw new StudentException(n);
}
else {
this.thesisRequested = true;
}
}
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> getGraduationSpecs() {
return graduationSpecs;
}
/**
* Set the list of specifications defining in which case a student can
* request a graduation thesis.
*/
public void setGraduationSpecs(List> graduationSpecs) {
this.graduationSpecs = graduationSpecs;
}
private boolean applyAllSpecs() {
boolean result = true;
for (BaseSpecification spec : this.graduationSpecs) {
if (!spec.isSatisfiedBy(this)) {
result = false;
}
}
return result;
}
}
Here is a simple main method for showing all this stuff:
public class TestStarter {
public static void main(String[] args) {
List<basespecification><student>> specs1 = new ArrayList();
specs1.add(new EnoughCoursesSpecification());
specs1.add(new EnoughCreditsSpecification());
Course c1 = new Course();
Course c2 = new Course();
c1.setCredits(5);
c2.setCredits(4);
Student s1 = new Student();
s1.setGraduationSpecs(specs1);
s1.registerExam(c1);
s1.registerExam(c2);
try {
s1.requestGraduationThesis();
}
catch(StudentException ex) {
Notification n = ex.getNotification();
List<error> errors = n.getErrors();
for (Error e : errors) {
System.out.println(e.getMessage());
}
}
}
}
Doing so, we still use wonderful specifications, avoiding the hard-to-manage validate() method, even if we need multiple error notifications to superior layers, and we do not write additional code for transporting them because we use existent language features.
An alternative implementation, as suggested by Martin Fowler, is to use event notification patterns.
We could explore this in another post.
In the meanwhile, what do you think about this?
Subscribe to:
Posts (Atom)