Interfaces Should Reveal Intention

From WikiContent

Revision as of 09:20, 8 July 2009 by Elandre (Talk | contribs)
(diff) ←Older revision | Current revision (diff) | Newer revision→ (diff)
Jump to: navigation, search

Kristen Nygaard, father of object-oriented programming and the Simula programming language, focused in his lectures on how to use objects to model the behavior of the real world and on how objects interacted to get a piece of work done. His favorite example was Cafe Objecta, where waiter objects served the appetites of hungry customer objects by allocating seating at table objects, providing menu objects, and receiving order objects.

In this type of model we will find a restaurant object with a public interface offering methods such as reserveTable(numberOfSeats,customer,timePoint) and availableTables(numberOfSeats,timePoint), and waiter objects with methods such as serveTable(table) and provideMenu(customer,table) — object interfaces that reveal each object's intent and responsibility in terms of the domain at hand.

So, where are the setters and getters so often found dominating our object models? They are not here as they do not add value to the behavioral intention and expression of object responsibility.

Some might then argue that we need setters to support dependency injection (a.k.a. inversion of control design principle). Dependency injection has benefits as it reduces coupling and simplifies unit testing so that an object can be tested using a mock-up of a dependency. At the code level this mean that an resturant object that contain table objects, code such as Table table = new TableImpl(...); can be replaced with Table table; and then initialized from the outside at runtime by calling resturant.setTable(new Table());

The answer to that is that you do not necessarily need setters for that. Either you use the constructor or, even better, create an interface in an appropriate package called something like ExternalInjections with methods prefixed with initializeAttributeName(AttributeType). Again the intention of the interface has been made clear by being public and separate. An interface designed to support the use of a specific design principle or the intent of frameworks such as Spring.

So what about the getters? I think you are better off just referring to queried attributes by their name, using methods named price, name, and timePoint. Methods that are pure queries returning values are, by definition, functions and read better if they are direct: item.price() reads better than item.getPrice() because it make the concepts of the domain stand out clearly following the principles found in natural language.

The conclusion on this is that setters and getters are alien constructs that do not reveal the intention and responsibility of a behavior-centric interface. Therefore you should try to avoid using them; there are better alternatives.

By Einar Landre

This work is licensed under a Creative Commons Attribution 3

Back to 97 Things Every Programmer Should Know home page

Personal tools