Friday, October 26, 2007

The Fail Fast Rule

Every time you're writing a piece of code and you have to deal with unknown corner cases ...
Every time you're implementing some kind of logic and you don't know what to do when things go bad ...
Every time you think: this can never happen, I don't have to check for it ...
Every time you don't know what to do or what would happen ...
Please ...

Fail fast.

This is the Fail Fast Rule, as I call it, a term borrowed from the Java Collections iterators behavior:

Every time your code might fail, and you don't know what to do, just make it fail abruptly.

That is: do not ignore it, do not (just) log it, but let your code throw an exception.

An example was how we computed a shopping cart total in one of my previous posts:

public class ShoppingCart {

private static final int MAX_TOTAL = 10000;

private List orders = new ArrayList();

public void addOrder(Order o) {
this.orders.add(o);
}

public double computeTotal() {
double total = 0;
Iterator it = this.orders.iterator();
while (it.hasNext()) {
Order current = (Order) it.next();
total += current.computeSubTotal();
if (total > MAX_TOTAL) {
throw new SomeException();
}

}
return total;
}
}

As soon as the total gets too high, an exception is thrown. Probably this will change later, because we may want to handle it more gracefully, but in the meantime: make it fail.

Why?

Because if an exception will pop up in front of you, you'll have found a bug, a corner case, something that you have not still properly implemented or that you have not thought of.

So remember: make it good, or fail fast.

Tuesday, October 23, 2007

JavaMail and GMail : it's all about configuration

Yesterday I spent a couple of hours trying to send emails with JavaMail APIs via my GMail account.

It wasn't easy: the standard JavaMail configuration didn't work, while Google gave me a lot of wrong and/or outdated information.
Moreover, JavaMail FAQs provide a sample about sending emails via GMail, but it has some problems too.

So I think these bits of information will be helpful to someone trying to accomplish the same task ...

The problem is that GMail uses TLS and the STARTTLS command.
The solution applies to JavaMail 1.4 and JDK 1.4 or higher and is just a matter of configuration.

First, and obviously, enable POP support for your GMail account.

Then, put the following configuration in your properties file:

mail.transport.protocol=smtp

mail.smtp.host=smtp.gmail.com

mail.smtp.starttls.enable=true

mail.smtp.auth=true

mail.user=<your_username>

mail.password=<your_password>

The key point is the part in bold: enabling the STARTTLS command.
That's the tricky part.
Once created the properties file above, just configure your JavaMail Session object and send your mail message as you'd always do:


Properties props = ...; // <-- Your properties above

Authenticator authenticator = new YourAuthenticator(...);

Session session = Session.getInstance(props, authenticator);

Transport t = session.getTransport();

t.send(yourMail);


That's all.
Feel free to comment on for any question.
Enjoy it!

Friday, October 19, 2007

Avoid your getters and setters, Part 2

More than one year ago we've talked about how to avoid getters and setters by using the most fundamental object oriented programming principle: programming to an interface.

Well, it was just the beginning ...

I know we're a bit late, but let's go now with the second part of my
How to avoid getters and setters series ... I hope you'll enjoy it!

Avoid your getters and setters : The Expert, the Aggregate and the Value Object.

Many people use getters and setters so extensively because don't really get the importance of correctly assigning object responsibilities and behaviors.

So, in this second part we'll mix together GRASP and
Domain Driven Design patterns, in particular:
We'll see how wrongly managing responsibilities and behaviors, while abusing getters and setters, can lead to a corrupted business domain, and how the patterns above will help you to correctly address these kind of problems.

The business domain.

Let's start our discussion by showing a simple business domain.
We're implementing yet another ugly e-commerce system, so we have a shopping cart holding a number of orders, each refer
ring to a given product.
Without going further on, let's restrict our domain model to three simple entities: ShoppingCart, Order and Product.









A
ShoppingCart can hold one or more Orders, and an Order refers just to a single Product.
Moreover, we have some simple business rules regarding these entities:
  1. The ShoppingCart total is the sum of all Order sub-totals.
  2. Each Order sub-total is the Product price times the ordered Product quantity.
  3. The ShoppingCart total cannot exceed the value of EUR 10000.
Pay particular attention to the latest point: it is an invariant, a rule that must be always kept valid.

That's all.
Very simple, isn't it?

Let's implement it : the wrong way.

The entities and rules above can be straightforwardly implemented as follows:

public class Product {

private String name;

// ...

private double price;

// ...

public double getPrice() {
return this.price;
}

public void setPrice(double price) {
this.price = price;
}
}

public class Order {

private Product product;
private int quantity;

public Product getProduct() {
return this.product;
}

public void setProduct(Product p) {
this.product = p;
}

public int getQuantity() {
return this.quantity;
}

public void setQuantity(int q) {
this.quantity = q;
}
}

public class ShoppingCart {

private List orders = new ArrayList();

public void addOrder(Order o) {
this.orders.add(o);
}

public List getOrders() {
return this.orders;
}
}
As you can see, all classes have the right properties and dependencies:
  1. A Product has a price.
  2. An Order refers a Product and has a product quantity.
  3. The ShoppingCart has more orders.
  4. The ShoppingCart total can be calculated by iterating all Orders and summing up each Product price times the ordered product quantity.
However, this design (and implementation) is seriously flawed:
  • There's no clear assignment of responsibilities and behaviors.
    • Hence, it is full of getters and setters.
      • Hence, there's no encapsulation.
        • Hence, all business logic is external.
          • Hence, it is easy to corrupt domain state and violate business rules.
How?

Given our design and implementation, the following code is absolutely legal:

Product p1 = new Product();
Product p2 = new Product();

p1.setPrice(1000);
p2.setPrice(2000);

Order o1 = new Order();
Order o2 = new Order();

o1.setProduct(p1);
o1.setQuantity(5);

o2.setProduct(p2);
o2.setQuantity(5);

ShoppingCart cart = new ShoppingCart();

cart.addOrder(o1);
cart.addOrder(o2);
But hey, wait!
The ShoppingCart total is now EUR 15000!
That's because the business logic is computed outside of the object that holds the information; so let's solve this problem by introducing the
Information Expert pattern.

Refactoring toward the Expert.

The Information Expert pattern is part of the
General Responsibility Assignment Software Patterns (GRASP), and states the following:
Assign a responsibility to the information expert: the class that has the information necessary to fulfill the responsibility.
We have two responsibilities to relocate:
  • The shopping cart total computation: here, the information expert is the ShoppingCart class.
  • The order sub-total computation: here, the information expert is the Order class.
By relocating the two responsibilities we'll improve our encapsulation and make our implementation more robust, because the ShoppingCart will be able to check that the total doesn't exceed EUR 10000.

public class Order {

private Product product;
private int quantity;

public void setProductWithQuantity(Product p, int q) {
this.product = p;
this.quantity = q;
}

public double computeSubTotal() {
return this.product.getPrice() * this.quantity;
}
}

public class ShoppingCart {

private List orders = new ArrayList();

public void addOrder(Order o) {
this.orders.add(o);
}

public double computeTotal() {
double total = 0;
Iterator it = this.orders.iterator();
while (it.hasNext()) {
Order current = (Order) it.next();
total += current.computeSubTotal();
if (total > MAX_TOTAL) {
throw new SomeException();
}
}
return total;
}
}
As you can see, the ShoppingCart computeTotal() method is now able to check against the maximum total, and throw an exception if there's something wrong, avoiding domain state corruption.

However, there's still something wrong; take a look at the following code:

Product p1 = new Product();
Product p2 = new Product();

p1.setPrice(1000);
p2.setPrice(2000);

Order o1 = new Order();
Order o2 = new Order();

o1.setProductWithQuantity(p1, 2);
o2.setProductWithQuantity(p2, 4);

ShoppingCart cart = new ShoppingCart();

cart.addOrder(o1);
cart.addOrder(o2);

cart.computeTotal();

// !!!!!!!!! DANGER !!!!!!!!!!
o1.setProductWithQuantity(p1, 3);
// !!!!!!!!! DANGER !!!!!!!!!!
The problem is that we can always change the Order product and quantity, changing so the shopping cart total without preventing it to enter in an invalid state!

Where's the
real problem?
How to solve it?

Refactoring toward the Aggregate and the Value Object.

The real problem is that we are interested in keeping the ShoppingCart state always correct, that is, in keeping its invariants: however in the current design and implementation we are not able to control everything happens inside the ShoppingCart, because we can directly modify its Orders without going through it!

The solution is to apply the Aggregate and Value Object patterns, part of the
Domain Driven Design.

An Aggregate is a set of related objects whose invariants must always be kept consistent, and an Aggregate Root is an object that acts like the main access point into the aggregate; all access must go through the root, and objects external to the aggregate cannot keep references to objects contained into the aggregate: they can keep a reference only to the aggregate root.

A Value Object is an object that has no identity and is immutable: it is equal to another value object of the same type if its properties are equal too, and must be discarded if its properties need to change.

How to turn this theory into practice, applying it to our domain?

First, our ShoppingCart and Order are part of an aggregate.
It's easy: the "EUR 10000" invariant involves both objects, so it must be kept consistent across the two.
Moreover, Orders make sense only if related to a ShoppingCart, so no one should access an Order without first going through a ShoppingCart: this means that the ShoppingCart is the root of the aggregate.

Second, the Order is a Value Object: it doesn't make sense to create an order and change its related product and quantity during its life cycle; an order always refers to the same product with the same quantity, and if something needs to be changed, it must be discarded and a new one must be created.

Now let's refactor our previous code:


public class Order {

private Product product;
private int quantity;
private double subTotal;

public Order(Product p, int q) {
this.product = p;
this.quantity = q;
this.subTotal = this.product.getPrice() * this.quantity;
}

public double computeSubTotal() {
return this.subTotal;
}
}

public class ShoppingCart {

private List orders = new ArrayList();

public void addOrder(Order o) {
this.orders.add(o);
}

public boolean removeOrder(Order o) {
return this.orders.remove(o);
}

public double computeTotal() {
double total = 0;
Iterator it = this.orders.iterator();
while (it.hasNext()) {
Order current = (Order) it.next();
total += current.computeSubTotal();
}
return total;
}
}

The Order class is now immutable and part of an aggregate together with the ShoppingCart.
The ShoppingCart is now the aggregate root, and every change to its Orders must go through it.

Now, you have no way of corrupting your domain.

Remember: the Expert, the Aggregate and the Value Object.
Who do you want to be?

Saturday, October 13, 2007

Alive

Hi all.

I'm not going to talk about the great Pearl Jam song.
I'm going to talk about me, because (very) long time has passed since my last post, and yes ... I'm still alive.

I don't want to bother you too much, just let me jumble a few bullet points about the most important things happened to me during these months:

  • I finished working at that big project for RAI, the Italian State Television, involving the design and development of its main portal. It was a very interesting experience and I think I'll write more about things I learned (because we always learn), in the future.
  • I became a committer of the Taconite Ajax Framework, improving my Javascript skills and working with CSS Selectors.
  • I've been at Spring One 2007 and it was nice, even if it didn't fulfill my high, maybe too high, expectations.
  • I bought a white MacBook and I'm really happy with it.
  • I've started working at (and I'm still doing) clustering a famous Open Source Enterprise product: I cannot say more right now, but I think more news will pop out soon.
  • Spring Modules approached the 0.8 release and will (hopefully?) soon approach the 0.9 one.
  • I've changed houses, and I'm really happy in the new one.
  • Radiohead released their new album, after about four years of silence ... and I suddenly bought it.
  • ... I've started blogging again ... seriously!
That's all.
Now let the thoughts flow again.
Now let the fragments burst in the air.