Monday, September 14, 2009

Failed attempt to apply Tdd response

This is a response to the post "Why my attempt to apply tdd failed?" on the whyjava blog. I am a test-infected developer and I want to give some support to whoever had the courage to change and adopt new methodologies.

In the post the author makes a list of points which summarize the difficulties encountered while trying out Test-Driven Development. I have some comments on this list, but before analyzing it in depth I remind you that the TDD mantra is red-green-refactor. Keep in mind it every single minute since it's easy to drift away without noticing it.
  1. Time lost: this is a classic myth about TDD, but it's true that initially writing tests will require time that has to be subtracted from writing production code. But if you look at the overall picture, you will find out that tests will save you more time in the long run that the amount spent to write them. While debugging and maintaining an application having a safety net composed by good unit tests is an aid that I won't exchange even with source control. Tests also act as a documentation and this will save time for new developers who has to learn how the components works together. They also keep regression out of your project.
  2. Boring to write test cases: while practicing TDD, a developer has to find his own balance within test the obvious and not test anything. Experience at this game will make you not test getters and setters.
  3. Client support: the client does not want the developers to write tests. Besides the fact the working in this way the client is never going to know if the application works, I would find strange to tell my surgeon I don't want you to use that bistoury, I have my Miracle Blade at home.
  4. Writing exhaustive test cases: "I think tdd will make sense when you are able to cover most of the scenarios in your test class". You're right, but since in TDD you write the test cases before any production code, and only the absolutely necessary production code to make those tests pass, there's only covered scenarios. If you find a feature which is not covered by a unit test it means it has been developed before them, which is not TDD anymore.
  5. Patience: of course every technique has its learnign curve. TDD is no exception.
  6. Poor examples: if you think books are teaching you by simplicistic situations, simply download an open source software which is developed with TDD.
  7. Legacy code: it's hard to replace old (maybe procedural) code with a TDD approach, and this is a valid point. However, you should apply TDD for new features if the design allows this.
I hope to have inspired the reader to embrace Test-Driven Development, or to continue his journey in it. Becoming test-infected was like seeing the Light for me, and I think I'm becoming a better developer every day because testable code leads to decoupled and reusable code.

Pagination is dead

Pagination is the feature for displaying a long list of entities in a web application: a division of them per page and a list of link to the various pages. Today there are better solutions to this classical problem, and some of them were always available even in the first days of the web.

The typical scenario solved by pagination is to allow the search of a particular entity from a list, by displaying it a chunk at the time. Particularly in web applications, where page size is limited by bandwidth, the maximum amount of items contained in a page is fixed in less than an hundred:
The problem with pagination is how often do you look to page 2?
I google many times a day, so many that I now use the search bar of firefox instead of loading the homepage and entering the query in the input field. I usually found the first or the second result to be the most reliable resource for the query I entered since Google ranking is legendary: it's Google that decides how popular an article on this website will be and the only thing that competes in popularity with Google ranking is social network one.
Thus, I never went to the 2nd page of a Google search result. I bet you neither have done the same more than once or twice this month, and probably refining your search terms would have put the link you were looking for in the first position of the first page. Since the first link is almost always what you will be clicking some seconds later, Google main page even feature the I'm Feeling Lucky button which does this work for you.
In my opinion, Google pagination is rather useless.

In the early years of the web, pagination was the killer feature: LIMIT clauses for databases were everywhere and calculation of its argument were spread all over an application. This blog, hosted on the Blogger platform, also implements pagination: but do you prefer to scan my archives five posts at the time or to use the search box on the right?
Although all the content is available in a list of pages, a blog is not a book and it is not sequential: articles are often found by visiting a particular label or by a Google result. Honestly I sometimes look to the page 2 or 3 of a blog to form an idea on what content is posted there and decide whether to subscribe to the atom feed, but I think the author would rather have me look to a search on a tag, to a collection of popular posts or to its about page.

What about different kind of lists to paginate? Wikipedia lists are often very long: sometimes pagination is not adopted, like in the link, and the result is a unfocused and difficult to navigate page. But if you refuse to paginate there are other ways to manage this big pack of data:
  • showing results on demand a la Dzone: thanks to ajax requests, when an user reaches the end of the list or is at the last items, another chunk is lazy loaded to fill the empty space between the list and the end of the page.
  • better search system: as we have discussed earlier, Google does not need pagination since it is the best search system and you'll find your desired result in the first 10 links. Provide a mean to search a big list instead of spitting it all out, leaving the burden on the end-user.
  • real time filtering: a dojo grid presents a pagination similar to the Dzone one, but different filters can be attached to modify the query. The result is similar to google suggestion while typing in the text field, as when you add characters to your search string the filtering is performed instantly.
These are only examples of what can be done if you force yourself to not paginate. The question which I repeat here is always the same:
Who will have the patience to look at page 2?
If you keep in mind this problem, finding another user interface to substitute pagination will be at the top of your todo list.

The scroll at the top of the page shows you a continuos source of pages that reminds of pagination sliders where you can go only to the next and previous page. It was very inefficient, but ancient monks did not have Google search capabilities...

Friday, September 11, 2009

SOLID part 5: Dependency Inversion Principle

This is the fifth post in the SOLID principles series. You might want to checkout the previous entries.

High level classes should not depend on low level classes. Both should depend upon abstractions. Details should depend upon abstractions. Abstractions should not depend upon details.
The purpose of this principle is to enable decoupling of software modules. Managing dependencies is the key for isolate components to reuse later; decoupling is also important for maintenance and evolution since it stops changes in a cohesive piece of software from spreading all over an application.

The problem with dependency is the transitivity: a class depends not only on the other classes which uses directly, but also on these classes dependencies, and so on. It needs them to compile (in languages which require this process) and to work correctly; some kind of dependency between components is present in every software since object needs to work together and to know something about what methods they are going to invoke.
Let's see an example of what transitive dependency means. An object of the class Car depends on an GasEngine to move its passengers where they want to go. The GasEngine itself depends on a Gas class which models the fuel used.
The problem is that a Car should not have to use a forced fuel, like an object of the Gas class. In reality, we have electric cars or LPG ones. A Car depends upon a detail (GasEngine), while it should depend on abstraction. GasEngine is also on a lower level, so this dependency infringes both parts of the DIP.
A feasible refactoring is to introduce an interface (an abstraction) Engine which GasEngine implements and Car declares as a property. This is a powerful step since it break the dependency chain between the high level component (Car) and the low level one (GasEngine).

The Dependency Inversion in this example improves the software design since now Car and GasEngine, which are the details the principle is speaking of, depend on the abstraction Engine. Though, other issues arise when defining an abstraction: how should a Car have a reference to a GasEngine, which needs to work, while it only declares a field to contain an Engine?
There's more than one way to solve this construction problem:
  • Service Locator approach: classes like Car needs a singleton or a static registry where they pull the object they need. For instance, a method Registry::getEngine() returns an Engine whose concrete class needs to be chosen by configuration. This approach is
  • Dependency Injection: this more sophisticated, but simple at the same time, approach let Car declare its dependencies and have them injected by constructor or setters. This is the most widely used technique nowadays to achieve Inversion of Control.
Note that in the Service Locator case, Car would be totally insulated from the concrete GasEngine at compile time since the method invoked at construction includes an Engine in the signature and not a GasEngine. Though, nearly every class has a reference to a global object or static class, lying about its dependencies. Moreover, the Service Locator needs to be transported where the class are being reused.
Constructor Dependency Injection or Setter Dependency Injection is a cleaner choice since business classes have no idea of the framework or Factory which will construct the objects. Car simply declares its constructor:
public function __construct(Engine $engine);
In turn Engine will declars its needed collaborators in the constructor and the developer (or the DI framework) will learn from this signature what he must provide to build a complete object.

As always, let's do an analysis of testatiblity, confronting classes which respect or do not respect the DIP.
The initial Car class is not testable in isolation at all: it builds a GasEngine in its __construct() method and there's no way to replace it for testing purposes, expect reflection. The only thing we can test is a whole Car object, but imagine if tests were done this way in the real world... No one would know why a Car does not work when a problem arises.
The Car which uses a Service Locator is unit testable, since before running a test method we can configure the Service Locator to return a fake/mock Engine instance which follows a canned behavior. By the way, we have the hassle to configure it which can be a tedious work.
The Car which uses Dependency Injection is naturally testable: simply build a fake Engine and pass it in Car when the system under test is created. There is no need to configure other systems, which in this case get in the way instead of helping the developer.

I hope you have enjoyed this series on the five SOLID principles and that your perspective on designing a good application has shifted thanks to these pillars. New posts on object-oriented development will come in the future, you may want to subscribe to the feed to be informed of that.

The image at the top of the article is the hood open of a Ferrari F430 Spider. It depends on an Engine - a FerrariEngine maybe - and not on a GasEngine, since it can mount an ethanol one.

Thursday, September 10, 2009

SOLID part 4: Interface Segregation Principle

This is the fourth post in the SOLID principles series. You might want to subscribe to the feed to be notified of new posts.

Classes should not depend on interfaces that they not use.
The meaning of this phrase is to avoid tying a client class to a big interface if only a subset of this interface is really needed. Many times you see an interface which has lots of methods. This is a bad design choice since probably a class implementing it will infringe Single Responsibility Principle and for many other issues which arises when interfaces grow.

Let's see an example of a violation to Interface Segregation Principle. Since Car examples are becoming popular, we will continue with a vehicle example.
The class Car needs to have reference to its passengers: depending on the particular vehicle, it will transport 4 or more people and it must check during construction that it is not overloaded in weight and number of passengers since it would be not secure to drive over cartain limits. We have a class People ready who acts as a collection of Person objects; so, to load a car with People, the following method is used:
public function load(People $p);
We do not want to tie Car to People, which has in turn other dependencies, so we start with extracting an interface:
public function load(IPeople $p);
Hungarian notation is a smell that something. IPeople has many methods, the same of the People concrete class: getWeight(), remove($i), add(Person $p), and a bunch of other functions which Car will never call. What does Car need to know? This is the question that needs an answer: Car needs only a count() method to avoid being overloaded, and a getWeight() method to calculate acceleration and other physical variables. We put these two methods in an interface which will be implemented by People, deleting the awful IPeople component.
public function load(Passengers $p);
In this design, Car depends on the smallest possible interface, Passengers. An interface with a name that does not derive from its implementations is a sign that we are on a good path. Even if People has to be decoupled from Passengers interface, I strongly suggest to write an adapter implementing Passengers, which will wrap a People instance.
The important part is that Car is subjected only to variations to the method which really use, that is actually the minimum coupling introduced in the application. If such a small interface does not exist, it has to be created via extraction from the previous one.
Please note that the same issues are present in abstract base classes: although they cannot be broken down in tiny pieces since multiple inheritance is forbidden in most languages, providing every possible method in a base class can quickly transform it in a God object, and that's exaclt what we must avoid. Helpers and delegations can be used instead when not every subclass will actually need the parent's method.

Small interfaces respect the SRP, and can be combined in many ways. They can also be implemented by the same object, like many classes does in php with Countable and Iterator. Fortunately these two interfaces are separated and allow an Iterator who does not know its length to work.
The advantage of less polluted interfaces is also in simplicity of implementation: less methods result in less tests and less interaction which can cause bugs; also, the classes derived will be much more cohesive as they take only one responsibility to manage from the chosen interface.

The testing point of view results in a easy win for small interfaces. How do you know what to mock when a 20+ methods interface or base class is passed in the constructor of the system under test? When the interface has two or three methods, there is little choice in what can be called by the SUT and you can produce mocks without having to know the internals of it (which of the 20+ methods will be called at what time). Probably in such a case you will end up using a concrete class instead of a mock, transforming your unit tests in integration ones.
You will be satisfied of keeping methods to a minimum while producing a self-shunting also for testing purposes.

I think you are now at a good point in our journey in the principles of object-oriented development. Interfaces are a great decoupling tool and should be used at their full potential. Stay tuned for the next part, on Dependency Inversion (and not Injection).

The image at the top is a Swiss Army Knife. How would you define an interface for one and someone will implement it? Do you prefer a real toolbox?

Wednesday, September 09, 2009

SOLID part 3: Liskov Substitution Principle

This is the third part of the series about the SOLID principles, which governs good object-oriented development. You may want to subscribe to the feed to be updated on new issues of this series.
Check out the previous parts if you missed them.

Every function or method which expects an object parameter of class A must be able to accept a subclass of A as well, without knowing it.
The meaning of this principle is that every time you write a subclass, you have to make sure it is substitutable in every place where you use an instance of the original class. The subclass must respect the contract of the superclass, without changing a behavior in such a way that would be impossible to recognize the new instance as belonging also to the superclass.
The name of this principle came from Barbara Liskov, professor at MIT.

The principle is about bad use of inheritance: long chains of inheritance will probably break it as the leaves of the class tree will likely try to reuse code without being proper subclasses. Let's see an example.

In your application you are writing the (overused example) Car class, and suddenly you feel the need for a Motorcycle class to use along for urban traffic simulation. Since there is much in common in these two classes, like the Engine, Brakes and the correlated calculations and wiring in Car's code, you write Motorcycle as a subclass of Car, redefining the methods where its behavior obviously disagree with Car's one, such as getTires() since it has only two tires instead of four.
This redefinition is a violation of LSP: a feasible method checkUp(Car $c) will be broken if it expects four tires to blow up. The language will allow us to pass a Motorcycle instance since it is an instance of Car also, but it is not really a subtype of Car since its contract is less restrictive of Car's one.

A common rule to discover is the subclassing choice is right is the instanceof operator consistency, available in many object-oriented languages. This operator will return true if the variable under test is built from the chosen class or from a subclass ($a instanceof Car). This means in our example $yamaha instanceof Car will return true, which we know it's a bad behavior of the application since its domain model slides away from reality.
The refactoring choice to fix this design it's to abstract away the common behavior of Car and Motorcycle in a Vehicle base (and possibly abstract) class, or to stop using inheritance altogether. Inheritance is widely overrated in the object-oriented programming and composition should be favored in it.

Inheritance is the right choice when an Is-a relationship is present, and in the majority of design should be limited to two or three levels without harm. The original paper from Uncle Bob uses Square and Rectangle as examples. It's obvious that a Rectangle could not be subclassed from a Square, so the reverse is tried. But the contract of Rectangle say that we can change height and width independently (setHeight() and setWidth()), while even if we redefine the methods we cannot in a Square as changing a side will change the other to maintain Square's properties.
There are other designs which will solve this particular problem, like writing immutable objects, but my choice would be to write an helper class which contains common logic and do not chain Square and Rectangle in inheritance at all.
From a more theoretical point of view, preconditions of methods cannot be strenghtened by a subclass while postconditions cannot be weakened: the Square redefinition of setHeight() to modify also the width does not respect the stronger post conditions of Rectangle's method to leave width unchanged; thus, a subclassing is not feasible. This is a bit of design by contract which helps us to detect a bad inheritance strategy: in a particular sense, a Square is not a Rectangle, although it indeed is in a geometric definition; since a Rectangle is identified by an entity whose sides couples can vary indipendently, a Square that forces all four to remain equals is not an instanceof Rectangle.

I hope you're starting to grasp the principles and see the connections between them: to follow religiously one of these first three you're going to apply also the others.
Stay tuned for the next principle explanation, the Interface Segregation Principle.

The image on the top is a photograph of Loris Capirossi on the Ducati Desmosedici, during a MotoGp race. Is a RacingMotorcycle a Motorcycle?

Tuesday, September 08, 2009

SOLID part 2: Open/Closed Principle

The Open/Closed principle is the second of the SOLID principles which governs object-oriented development, formulated by Uncle Bob in the 90s*.
Check out the previous part if you missed Single Responsibility Principle.

Classes and methods should be open for extension but closed for modification.
The meaning of this principle is that when a requirement is added to your application, you should be able to handle it without modifying old source files (supposing you have one class per file), but only by adding subclasses and new implementations and changing the configuration.
Why it is important to be open for extension? Change is the keyword in software development and software components are inserted in new projects and environments every day. What makes them useful is the ability for a developer to write adapter and subclasses to get a job done without reinventing the wheel, but only by smoothing and tuning it.
Why it is important to be closed for modification? Because when a closed unit is fully tested and deployed, if it's not modified it can't break. This is a simple consequence of not changing what already works: it will continue to work.

These are some examples of patterns and techniques that help you follow the OCP:
  • programming to an interface, not an implementation: a oo interface is closed for modification, and multiple implementations can take new behavior and possibilities into the software system;
  • Template Method: some empty methods are called during an algorithm execution to allow overriding by a subclass, providing it hooks in the code flow;
  • Iterator Pattern: abstracts away the mechanics of an iteration to let other iterators substitute it in particular conditions.
Every good pattern resemble the OCP. The Iterator Pattern has been particularly developed in php: we have Iterator and IteratorAggregate instances which can be swapped in foreach construct; but we also have a bunch of subclasses that extends the core behavior: FilterIterator, CachingIterator, LimitIterator, RecursiveIteratorIterator...
The strategy of extending behavior without cluttering a base unit is one of object oriented pillars: subclassing, decorators and helpers are only strategies to keep responsibilities out of the base class, which can quickly became a God one if too much code fills it.

Let's take the Car example from part 1 and see if we are violating OCP: a Car is composed by an Engine, a Trasmission and the Brakes. What if we need to move the Car without using a gas or diesel engine? We can design a ElectricEngine subclass which will substitute the former Engine without breaking its contract. The same can be done with CarboniumBrakes or BremboBrakes.
What if the Engine has a method called injectGas()? This violates encapsulation and affects OCP also. An electric engine would not use gas as a combustible and thus the contract is not closed for modification: the problem is in the abstraction of an Engine which is in reality an abstraction for a gas engine. What can be done it's decoupling the Engine with an interface Propulsor which will contain a GasEngineElectronicBoard which translates to the Engine the commands from the driver.
Now if we want to put in an ElectricEngine, we will provide a Propulsor instance which governs the ElectricEngine in some way, with electronic or analogic circuits. Take the time to think about possible changes and how they affect your software systems: find a way to add features without have to resort to old classes modification.

Encapsulation is a checkpoint to achieve OCP: the more you keep private and hide from the public view, the less is assumed in the behavior an interface or an abstract base class. This leads you to write implementations which exposes very few methods and can perform work in unthinkable ways: the Propulsor interface can be implemented by a ElectricEngine but also from a ReactionEngine or a SteamEngine or a HyperDriveEngine if you are a science fiction passionate. The only requirement is that it manages to accelerate the Car and choosing this abstraction makes this parts totally interchangeable.
The Propulsor interface is an example of closure: not only it is not editable since clients expects determinate features, but we cannot add methods because they will break the implementors, especially if their code is not under our control.

Summarizing, Open/Closed Principle forces decoupled and extendable code: it's another milestone towards a maintainable and functional object-oriented application.

You may want to subscribe to the feed to be notified of new articles in this series. The picture at the top is the Usb symbol: nowadays every device that uses Usb and provide a proper driver can extend the behavior of a pc without having to open the case: webcams, printers, scanners...
*
Rogerio Liesenfeld points out in the comments that the original formulation of this principle comes from Bertrand Meyer.

Monday, September 07, 2009

SOLID part 1: Single Responsibility Principle

The Single Responsibility Principle (SRP) is the first of the five SOLID principles which governs the object-oriented design. They have been formulated by Robert Martin aka Uncle Bob and are universally recognized as good architecture.

This post is the first in a five-part series which will give an introduction to every principle. You may want to subscribe to Invisible to the eye feed if you want to stay tuned on new issues of this series.

There can be only one reason for a class to change.
This is the common formulation of SRP, the Divide et impera of software development. The meaning of this phrase is that when you're adding features to your application, two different, unrelated stories to implement should not affect the same class. What is implied by this principle is that every class you design should have only one responsibility, and often in software development change is the unit of measure: since your class Car have only one responsibility, only a change in the requirements of this responsibility should make you open the source file and modify the code of the class.

Here are some examples of classes which does not follow the SRP:
  • a Car which fills its fuel tank by itself
  • a CreditCard which knows how to charge itself (the classic Misko Hevery's example)
  • a CreditCardProcessor which knows how to do http requests
  • a Comment which sends mails
The scope of your application decides when responsibility should be splitted among more than one class: if braking and accelerating are complex processes, they should be factored out from the Car class, in two classes such as BrakeSystem and Engine respectively (or maybe Transmission, which will decouple Engine from the Car). Abstracting what is really complex is the point of this principle: if you need only to save the number of wheels in a Car you probably do not need to write a Wheel class whose instances will be placed in the Car one: it is a unuseful layer of indirection. If your wheels needed to know when they are totally consumed or are going to explode due to external solicitation, then they would become instanceof Wheels and would earn a class on their own: this is an example of refactoring. Until then, you are building a model of reality and you should not include a customer eye's color in their bank account information.

A rule of thumb to make this decision is to describe the behavior of a class with a single phrase. If you cannot formulate such a phrase or it contains the word and or other connectives, probably the behavior should be divided in more simple parts.
Particularly, entity classes (in respect to service ones) should have only the purpose to maintain state along with their business, inherent behavior. That's why a Comment instance contains name, text and mail fields but not a method warnAuthor(), which sends mails, to call on subsequent comments insertion.
The advantages of religiously following SRP are:
  • classes are more reusable, since you can pick only the one which implements a specific behavior without reusing a God class which can do everything and depends on everything.
  • classes are shorter and simpler to maintain.
  • design is more fine-grained, because every bit of behavior has its place in a small class. Knowing what you are going to modify it's half of the work in object-oriented development: with smaller classes, it will be obvious where a change belongs.
  • writing small and cohesive classes leads to testable code, while writing God classes leads to a non-testable ball of mud. A maintainable system is composed by a graph of object whose classes depends on each other for collaboration: this picture is obtained with dependency injection techniques.
Think of a complex object, like your computer: it composed by a moltitude of objects, but it respects the SRP; every component has its responsibility, from the resistor to the monitor, and complex components are built by wiring together smaller and cohesive ones.
Now that we are inspired by the principle, let's factor out some responsibilities from our example classes:
  • a GasStation or a GasPump will fuel a Car's tank
  • a CreditCardProcessor should take care of charging a CreditCard
  • a CreditService will insulate CreditCardProcessor from the Internet
  • a CommentRepository will call a Mailer or a CommentSubscriber whenever a new Comment instance is add to it
I hope you start to consider Single Responsibility Principle whenever you are designing a component of your application. It's a bit difficult to grasp at the exact level of detail, but if you find the right level of abstraction that is needed, the benefit will be beautiful and simple code; which, for a complex application, is a great result.

* The object in the image at the top of the post is Bicycle Wheel from Marcel Duchamp, a surrealist artist. It is an artwork, but to me is a perfect symbol of an object that does too much.

Featured post

A map metaphor for architectural diagrams

It is a (two-dimension) representation of a pipe. The map is not the territory , but in software engineering terms they are models of it....

Popular posts