9/11/2004

Assigning Responsibilities Duh!

In object design a big dilemma is where to assign responsibilities, thumb rule is to keep behavior with data i.e. to define methods in the class that has the data. This rule has is always not correct even when data is in the class. Look at this simple example, An application need to store Order object(s) containing set of Order Items, Customer who ordered it. These objects need to be saved to a database. Order, OrderLineItem and Customer classes and relation ship among them are identified. Dilemma is where should save responsibility(methods) live and why it need to be there. To be specific, Is there a need to have a new class like DataStore, or have save method be part of Order object (it is the object that has data).

public class Order
{
void save();
}
// or
class DataStore
{
void save(Order anOrder);
}

If it is a method in order, then
  • Order object needs knowledge of api like JDBC. It is not a real part of Order object.
  • Similarly save method should be in each domain object.
  • If need be, How to handle bulk saves(saving a collections of Orders) in a single transaction?
All the above are valid objections even in a medium level complex application. So (If they are) it is better make other datastore abstraction to handle these db related operations.

In this application Order need to be priced also. Price of an Order is sum of it’s OrderLineItem’s price. Where does price responsibility belong?

public class Order
{
double price();
}
// or
class Pricer
{
double price(Order anOrder);
}

Here Order's price does not depend on any external data, keeping price calculation in Order makes more sense. (there may be a method in OrderLineItem also to calculate its individual price). What if price of a order is dependent on current interest rates (external data), and need to price set of orders with same set of interest rates, then clearly in other Pricer class.

When adding a responsibility to a class, ask why not move it to it's new (or other) class. Questions like
  • can the same responsibility/behavior be applied to collection of objects in single operation? (transaction, data set etc).
  • is same/similar responsibility need to be there in classes?
  • is needed data (to fulfill responsibility) noisy?
  • Is needed data (to fulfill responsibility) external?

can help in idenitifying the responsibility's location. If all things equal, add it to class with data - its the norm.

Duh!.


9/08/2004

Facade Notes

Generally façades are implemented as concrete classes or as singletons or as helper static methods. Even design patterns workbook says “A facade provides an interface, but it does not use a Java interface. Rather, a facade is a class with methods that make it easy to use the classes in a subsystem”. Implementing facades as concrete classes should not be a qualification, in fact interface based facade implementations are better.

  • Concrete façade/singleton classes make testing client code difficult, e.g., client using a concrete facade that hides remote calls. We can’t test client code unless remote services needed by façade are running.
  • If implemented as interfaces, we can easily change implementations (even intent change to a bridge).
Are helper utility classes facades? Helpers and utilities simplify complex API usage by wrapping commonly used code. If helpers can abstract complete client needs to facaded API, then helpers are façades.

Do we need facades to standard APIs? Standard APIs are well documented, well understood and well designed. By standard APIs I mean subsystems like swing, jms etc. Wrapping rich APIs for your needs is difficult. Our facades tend to hide well needed APIs richness. Why do we need facades to well known standard APIs? Except for temporary advantage of hiding some of the (noisy) classes from client they are not really helpful. In the long run our facades to such apis tend to be maintenance headaches. So letting user deal with the standard apis is better. If needed we can have some helper classes to simplify some parts of it.

Does it mean data access objects, Object Relational Mapping tools, aren’t needed, aren’t they facades to standard APIs? Data access objects are not treated JDBC facades, they are helper classes to abstract a client modules persistence needs. ORM tools are defining new set of APIs with intent of providing persistence features for objects, their primary intent is not to hide JDBC layers.

Core J2EE's Session Façade, Fowler's Gateway, Business Service, Remote Façade are they facades? They certainly are, their specialized (overloaded) intent is to hide low level (remote/ session handling/ integration) abstractions by providing a high level user/application friendly interface. They hide noise (convert application requests to low level requests, convert low level exceptions to business exceptions etc.)

In the end Facade’s intent is to provide a consolidated complete unified cool API to a complex/noisy abstractions.

9/04/2004

cool pictures



A thumbnail is worth thousand words. especially evolution charts, are n't they.

9/01/2004

Quotable “Design Patterns" Quotes

“A solution to a problem in a context.”

ChristopherAlexander


“Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice.”

ChristopherAlexander

“A pattern is a way of doing something, a way of pursuing an intent. ”

Rebecca Wirfs-Brock