Monday, November 09, 2009

Why I don't like the Bowling Game kata

I am a big fan of Uncle Bob and I think he is a master of object-oriented programming and architecture. However, in my opinion his Bowling Game kata (solution for the bowling game scoring problem) it's not the right example to explain design via Test-Driven Development.
The kata consists in showing how to TDD a Game class which calculates the score for a bowling game basing on the pins rolled by the balls. It is a pure TDD exercise, accomplished by writing one test at the time, making it pass and refactor the Game class before adding a new one. This kata has circulated for long in the blogosphere.
Although it is indeed useful to see a perfect and practical example of testing-first for the naive programmer, I didn't enjoy reading the various slides.

For instance, these are the scoring rules for 10-pin bowling games, extracted from the Kata:
The game consists of 10 frames as shown above. In each frame the player has two opportunities to knock down 10 pins. The score for the frame is the total number of pins knocked down, plus bonuses for strikes and spares.A spare is when the player knocks down all 10 pins in two tries. The bonus for that frame is the number of pins knocked down by the next roll. So in frame 3 above, the score is 10 (the total number knocked down) plus a bonus of 5 (the number of pins knocked down on the next roll). A strike is when the player knocks down all 10 pins on his first try. The bonus for that frame is the value of the next two balls rolled [...].
These are fixed business rules. Once the last test in is place, there is nothing to add to the class since the bowling rules are considered standard. It is perfect now and forever. How many times did you write a class that never changed?
A design is considered good if it accomodates change to the business requirements, and I would have tried to implement different bowling scoring systems to see how the Game class can be modified to pass the new acceptance tests without breaking the existing ones. There is a total of five requirements expressed by the tests and while they are added the code is refined accordingly, but it is more an academic example than a real world situation.
When you propose TDD to fellow programmers it seems reasonable, but the first question that they ask you is How do I test my database application?, not in what order should I put my test helper methods? There are different priorities in learning TDD.

This kata is interesting in the sense that it implements a scientific method by changing one factor at the time in the TDD equation and analyzing the result. You find people that execute the same kata in different languages; with different frameworks; different programming paradigms; and so on.
When the majority of frameworks out there are still using static methods, executing katas sometimes crosses the border of overdesign/gold plating/endless polishing. I learned something from the kata, but it's not rocket science. Why not write a patch to some open source project that you use every day instead of investing time in doing the same thing again and again?

There are many math problems which are perfect for learning a new language: consider for instance writing a function which finds perfect numbers. If I were a computer science professor I would assign these problems to C beginners as they are very handy in having no external dependencies and in being easily solvable.
The limit in such learning methodolody is that only structured programming capabilities are exercised and there are many development patterns which are not necessary for solving math problems, and which will not be implemented by a beginner if not forced. Doing the simplest thing that could possibly work leads a beginner to create a function for calculating perfect numbers, not a class so well-tested in different scenarios. The same is true for calculating a bowling game score.
The kata is a very narrow case, recalled when you test a class with no dependencies, no lifecycle problems and with the smallest Api you will never encounter.
Before reading the kata I was excited because I was going to learn how Uncle Bob works. But the demonstration is in fact very basic. I would have preferred to see how he deals with interfaces design, legacy code refactoring, collaborators extraction when classes grow.

Saturday, November 07, 2009

Questions on controllers testing

A different kind of controllerDavid Weinraub has written to me asking some basic questions about my last post on dropping unit testing for controllers. I am glad to write a less technically advanced post to answer these questions for the readers that experience difficult in following the discussion in the previous post. I guess it can be helpful for other developers that have just started exploring the possibilities of good object-oriented programming.
Let's start with the questions.
On your recent post How to not test controllers, you have the following code in a controller:
$repository = $this->application->factory->getUserRepository();
Was this what you meant in our previous discussion by using a single app-wide factory for creating your service objects? The factory with approx 100 calls to "new"?
In my opinion pure factories should have nearly no logic: they only create objects and their responsibility resides here. Though, in my approach only the controllers know that a factory exists.
So you create this $factory at some early phase, bootstrap I guess, and then "store" it as an attribute on the $application object? Presumably the $application object is always accessible wherever I am in the app, so if I need some service, either to use directly or to pass as a collaborator to some other service (like a repository or a mailer), I can get it using code like the above.
The container which provides the factory is not important, but in this case is the Zend Framework bootstrap object or a Zend_Application instance, the only things that the infrastructure allows us to inject into controllers. It would be great, alternatively, to inject only necessary services in the controller, having also the controller object created by the factory (but it's not supported out of the box in zd).
Note that for easiness of decoupling and testing, this choice is bad: every time we break the Law of Demeter in a class its tests will increase in size and complexity. Normally I want to avoid these violations but since I decided to treat the controllers only as wiring code and not to unit test them it's not a problem. All my business logic is kept in the underlying domain layer if it is domain related or in action and view helpers if it is focused on data formats like html and json, or other cross-cutting concerns; these classes are then extensively tested and writed via TDD. I test controllers only in integration, and their responsibility is to act as a dumb bridge between requests/view variables and the Domain Model. Controllers are only very simple mediators in my applications: I would unit test them if I do not have to import third-party libraries to inject their collaborators, because their Api will improve.
Perhaps the factory itself calls it's own methods when it needs to create more complicated services using collaborator services?
I do this all the time. It's stupid to not reuse code :) However, it is usually simpler to expose only the narrow set of end-user services: for instance my Reflector, which gathers domain classes metadata, is used only by other services and so it is created in a protected method. Only the services which are requested directly by controllers earn a public method.
Does this factory maintain an internal registry of the objects it has created, so that subsequent calls to the factory do not produce duplicates of the objects? Or alternatively, is it is "dumb" factory, so that each call to, say, getUserRepository() creates a new one. I can't imagine you allow your factory to make duplicates like that.
If you want, you can cache them in the factory field references, and even unit test the factory by requesting the same service twice and executing assertSame() on the objects returned. In php it's not very useful: how many times a service is requested two times from the factory, by the same controller? It makes a lot of sense in Java where objects are not garbage-collected between http requests and can thus be shared. It is also necessary in php mainly when a collaborator must be shared between different services.
The nice caveat is that if you implement consistently this caching also the smaller factories (which create objects with shorter lifetimes like View Helpers) will be cached as they are instanced once in the main factory and then shared. This is true with every level of nested factories you reach and, without using singletons, you will never need to duplicate an object when not needed.

I guess I have clarifyied why I am abandoning unit testing for controllers and making them break the Law of Demeter, without feeling remorse or renouncing to a good design. Feel free to post comments to continue the discussion.
The image at the top is a photograph of a SNES controller. This is a pun and not the controller we are talking about.

Friday, November 06, 2009

How to not test controllers

Yesterday on twitter a discussion started about how to properly design Zend Framework action controllers to allow simplicity of testing, specifically how to inject collaborators in controllers and to avoid breaking the law of Demeter.
The example problem is how to get a reference to a MailService instance for executing this code inside a controller:
$user->sendWelcomeEmail($mailService);
where $user is an istance of the User entity class, thus having no injected services and requiring one to be passed as an argument to the function. This problem was proposed by @apinstein.
I can think of several solutions, and others have been proposed by @beberlei and @weierophinney.

1. Just inject the MailService in the controller: it should ask for the collaborator in the constructor (@mhevery)
This would be correct in Java and it is an example of pure design, but in Zend Framework constructor injection is not available for controllers. They are required to have a no-arguments constructor: this contract leads us to the next solution.

2. Controllers may not have constructors, but there are still ways to inject services/models (@weierophinney).
3. Yadif allows to inject #zf controllers.(@beberlei)
Yadif is a dependency injection framework for php that implements setter injection. Using Yadif in conjunction with setters prepared on the controllers let you unit test them as you can call the setters in test code to pass in stubs and fake objects.

4. Instance the collaborators as bootstrap resources and leave them hanging there waiting for the controllers to use them.
The bootstrap object acts as a service locator. If I understand this process, and we want to unit test the controllers, we should avoid a service locator as it involves breaking the Law of Demeter (getting the bootstrap object only to get the collaborators), and we would have to prepare the container only to put in services, without the Api of the controller telling us what collaborators a controller depends upon.
Also instancing services that might not be used during every request can be expensive. I don't know if there is a lazy loading capability for bootstrap resources. This option is the worst for testing and maintenance.

5. Push down the logic in the model layer (me)
Controllers in Zend Framework are meant as a thin layer over a large domain model one. There is no problem for me in not having easy injection in them because I would put in the controllers only wiring code, which receives the main factory from the bootstrap, request it to create the domain services which have to do the real work and pass request parameters to them, assigning view variables as a side-effect.
$repository = $this->application->factory->getUserRepository();
$user = new User(...); // with a factory if you prefer
$view->message = $repository->registerUser($user);
I know this is breaking the Law of Demeter, but the point here is that if the controller is a thin enough layer, which contains no logic, there is no need to unit test it, and experience the pain of preparing stubs that return stubs that return stubs. This code will be exercised in integration tests that have all the same bootstrap, stubbing the main factory to provide fake collaborators only where they are not practical (a fake MailService in this case).
Here are the reason why I like this approach to controllers:
  • reusability: controllers code is not reusable, to the point that it is suggested to move much of it in helper classes. I do not want to rewrite logic in different places, so it's better for me to keep business logic in the domain layer.
  • simplification: if the controllers are dumb and expose the underlying layers as-is, that would be no translation between the domain model and the end user mental model. The entities presented in the user interface will be the same that live in the domain layer.
  • testing: mocking an array of domain parameters is simpler than mocking request objects. Obviously unit testing is performed only in the domain layer.
  • abstraction: logic is not technology dependent. If you keep logic in the controllers, you are coupled to Zend Framework, while a domain model is agnostic on every other component of the application, isolated by interfaces. It's like using a DataMapper instead of an ActiveRecord.
I avoid so much smart controllers that I recently started to implement the Naked objects pattern, where controllers are generated and delegate all the work to the domain model.

In conclusion, I think you should consider all these five practices for improving your controllers design and make sure your business logic is well tested. Choose the solution that works for you.

Thursday, November 05, 2009

Unit testing and programming paradigms

Today there is a large movement that exalts unit testing, most of the time when it is applied to object-oriented applications. But what about different paradigms? Is unit testing limited to classes and objects? Or you can unit test also C code?
There are different popular fields where you can try to put into practice unit testing: think for instance that even electronic circuits are unit tested. Let's explore the most famous programming paradigms in respect to testing practicality.

Unstructured programming (aka Goto and assembly jumps)
If we are writing low-level code, I think we cannot test very much extensively. Defining subroutines can help to define pieces of functionality, but fighting accidental complexity is nearly impossible. I remember rewriting my nokia snake game in assembly and how I had to be very smart in coding, since once the work was finished debugging and manual testing were the only way to discover errors. The application is not isolated from the machine as much as we would want (as we will see in the C case).

Structured/procedural programming (if, loops, functions and data structures)
In the classic C realm, testing can be performed on the defined functions, as we can get as close as we want to them from the upper layers. The problem manifests when we want to do the equivalent of injecting stubs and mocks in higher-level functions: there are no seams where we can substitute collaborator functions with stubbed ones, useful for testing. If my function calls printf(), I cannot stub that out specifying a different implementation (unless maybe I recompile everytime and play a lot with the preprocessor). Normally I would insulate printf() calls in an object I can inject, but there are no objects here, only static functions.
C is the high-level language which is closest to the raw metal and voltage values: performance and flexibility are great but there are no abstractions we can exploit. Function memory addresses are commonly hardcoded and relocated at loading time, unless you use function pointers. I guess a table of function pointers would perform the job, but in this case you can simply port to C++ where virtual methods are automatically implemented with this trick.

Object-oriented programming
In this paradigm we can inject collaborators in the class constructors or via setters, allowing tests to link fake collaborators and isolating the system under test on the upper ports (since the test call its methods directly) and on the lower ports (since it specifies stubs).
Note that if we are using static methods, the case becomes equivalent to structured programming as there are no seams to specify different methods that should be called. The upper layers test suite would perform integration testing and not unit testing as it would be forced to incorporate and exercise the lower layers to work.

Functional programming
In this paradigm, functions are first-class objects and they can be the argument of other functions. So instead of injecting collaborators in the constructor we could provide them as arguments, earning the ability to pass in fake functions in tests. The upper layers can thus be insulated without problems (with this sort of dependency injection) and there are no side effects that we have to take care of in the tear down phase - it seems that unit testing would be simple but I'm not an expert on functional programming, that's only what I would try.

In conclusion, I think unit testing trascends the object-oriented programming paradigm and it is a general practice. Let me know if you have other thoughts.

Wednesday, November 04, 2009

Testing and constructors

During unit tests preparation you often have to modify your design to simplify the test code. Design for testability is one of the good things about Test-Driven Development and more in generally of unit testing (and with TDD you will not modify your code to allow easier testing but you will write it to do so). A testable design is decoupled and maintainable and in the long run you will get only advantages. With in the long run I intend next week.
One of the pillars of design for testability, which is listed also in the Google guide for code reviewers, is to have constructors that do not contain logic or method calls. I will explain the reasons behind this choice with an example, but let me say that to reduce dependencies it is natural for a class to avoid making assumptions on the external environment, performing things like creating new objects. Separating the business responsibility of a class from the one of wiring itself to other objects is necessary.

As always, the example is in php as there is a great need for good object-oriented programming in this particular field.
class NakedEntity
{
    protected $_entity;
    protected $_class;

    public function __construct($entity = null, NakedEntityClass $class = null)
    {
        $this->_entity = $entity;
        $this->_class = $class;
    }

    public function getState()
    {
        $state = array();
        foreach ($this->_class->getFields() as $name => $field) {
            $getter = 'get' . ucfirst($name);
            $state[$name] = $this->_wrapped->$getter();
        }
        return $state;
    }

    public function getMethods()
    {
        return $this->_class->getMethods();
    }

    // other methods...
}
I omitted docblocks as they are not relevant in this context.
This class purpose is to act as a container for a domain object and its class metadata. These metadata are kept in its $_class field which is a NakedClass object. The extraction process uses reflection and it is encapsulated in another component that returns instances of NakedClass and NakedEntity. Thus, creating a test-friendly NakedEntity object is simple:
$entity = new NakedEntity(new stdClass, new NakedClass('My_User', $methods));
This code snippet tricks my library classes in believing that a stdClass is a My_User istance, and makes unit tests very simple. For instance the classes that work on the methods metadata can try many different combinations of methods without requiring me to write many My_User and My_Group classes. I should thank my constructor: it does not perform work, but only accepts the collaborators and stores them in private fields. If the constructor of NakedEntity parsed the class code like this:
$user = new My_User();
$entity = new NakedEntity($user); // calling get_class() and then doing a lot of work
I would be stuck with My_User methods and I would have to write a new real class for every different test method and my tests would be slower.

Fortunately there is mocking, and I can substitute NakedEntity instances with mocks. But mocking won't always save me from the work in the constructor, as when testing the very NakedEntity class I will have to wait for all the parsing to finish in every test, while I just want to verify that, given a set of method metadata getMethod() and hasMethod() works well. Why should my classes parse docblocks and annotations to test ten lines of array-related code?
Unit testing also means that the code under test is contained in the NakedEntity class, and I can inject mocks or stubs via the constructor instead of a real entity or a real NakedEntityClass object. Keep in mind also that a stub can be the the real production class if a test-friendly instance can be built and it has not much logic: in other tests I often use the NakedEntity class, and I will continue at least until it grows to contain logic I want to take out of my other unit tests.
Focusing on the NakedEntityTest class instead, if the constructor created objects or did a lot of logic it would be difficult to inject the right stubs as they can get in the way during the costrunctor execution. Also a problem in the constructor would make all the tests fail, making more difficult to locate the problem.
One acceptable practice is to instance only newable objects in the constructor, with little behavior. In php an array is the obvious example of newable, since it is not even an object. Also I considered Spl classes newable as they do not slow down tests and cannot commonly break (at least you cannot break them while maintaining your code).

Note the null defaults that the arguments assume, that allow tests to pass in nulls instead of real objects or mocks. I think this is useful when sometimes a collaborator is not used in mediator objects:
$entity = new NakedEntity(null, $class); // emphasis that the test would
// use the NakedClass collaborator.
$methods = $entity->getMethods();
The contract in the code above says "getMethods() should not assume anything about the $this->_entity property". If getMethods() tries to call a method on a null, the code will explode and the test will fail.
It is responsibility of the factory class to create a valid object by passing in meaningful collaborators instead of nulls, and this responsibility would be exercised in an integration or functional test.

In my opinion this is the perfect constructor for my class:
  • it lets the tests inject collaborators, which could be real instances, mocks or stubs;
  • it does not perform work that should be repeated in every test; it only assigns variables to private or protected fields;
  • it lets the collaborators be null values if they should not be touched during a particular scenario.
I know someone will complain: but now how I can write new NakedEntity(...) to work with an instance? I will have to create all its collaborators. You should not do it. A factory should do it for you, and if you require to do it in the middle of a method, you should ask for a factory in the related constructor.
Do you have some example of constructor difficult to refactor in this way? Feel free to post it on pastebin.com and insert the link in the comments for discussing it.

Tuesday, November 03, 2009

Anti-patterns

If you work with object-oriented programming languages, you most certainly have come in contact with design patterns, reusable solutions to common problems which are composed by a set of roles that your objects and classes fulfill.
Nothing prevents a programmer from implementing a coupled and ineffective solution, maybe without even knowing it, and just like with the more famous design patterns recognizing what he has built only at completion. These counterproductive solutions can be identified as standard bad practices: they are called anti-patterns. Moreover, while design patterns usually are focused on design and coding, anti-patterns can be observed in many different fields of software engineering such as the organization and management levels.

Let's see an example focused on software design. Suppose you have a small application which a narrow set of features and you are in a rush to implement new ones. In the worst case, these features will be hacked in without respect for the design of the application, whose architecture is not even formally defined or cannot scale while the size increases. What you obtain is a large system composed of highly coupled parts you cannot change, with duplication in business logic spreaded troughout the classes and in which different components break after a change in unrelated ones. This is called a Big ball of mud.
The requirements for an anti-pattern to exist are simple: a repeated behavior that may appear beneficial in the short-term, but causes pain in the long run while a standard good solution exists. In the case of an object-oriented Big ball of mud, the solution is unit testing and dependency injection.
We are most interested in object-oriented and general programming anti-patterns, and they are the subject of this post. Here are listed the most important and (in)famous, and maybe you have already heard their names. You can consult the wikipedia category for more examples. I guess you will recognize also why most of these anti-patterns are considered bad practices.
Object-oriented anti-patterns:
  • Anemic Domain Model: use of a domain model layer where business logic is not incorporated with data, for instance a big group of entities without any method different from a getter or setter.
  • God object: an object from a class that have many responsibilities instead of a single one.
  • Sequential coupling: an object requires the client to call its methods in a particular order.
  • Circular dependency: mutual dependencies between classes, object or packages. A circular dependency makes two or more code entities inseparable, increasing coupling and killing reusability of both. Mutual dependencies should be break with interfaces, like in the Observer pattern.
  • Object orgy: free access to object properties by collaborators, also by setters and getters overusage. Encapsulation should be preferred to prevent changes in a component to affect the other ones.
Design and programming anti-patterns
  • Interface bloat: an interface that has grown so much and has to do so many things that it is too difficult to implement, resulting in only the first and official implementation being available. Small and focused interfaces should be preferred.
  • Magic pushbutton: inserting domain logic in the user interface only. The name derives from writing code in the generated event-handling routines of buttons. This practice should be replaced with delegation to the domain layer.
  • Action at a distance: unexpected interaction between different components. Global state and singletons are typically an example of this anti-pattern, which reveals its Api problems during unit testing.
There are even more anti-patterns than design patterns: it's easy to do something wrong. As I said, I listed the most famous anti-patterns related with design and implementation, but management and methodological anti-patterns have been recognized as well throughout the years (one for all: Silver Bullet).
I think learning from errors is fundamental in every profession, and I considered lucky who can learn from others' mistakes. If we learn what are the wrong choices, we feel confident to apply the best practices of this industry as we can see why they are valid.

Sorry for the late post but it's my ISP fault. Feel free to add anti-patterns that you perceive as diffused in the comments.

Saturday, October 31, 2009

Object-oriented roundup: Halloween edition

This blog has grown much during the last month and the newest readers may have missed some important articles in the posts archive, on one of the most interesting topics here: object-oriented programming. Specifically, these posts reflect my vision and are meant to discuss good and practical design of classes.
This page will stay here as a way to quickly find references to the key blog posts of the past for me and the readers, while working on new articles.

First, I made a roundup of the most crucial and popular oop posts. I guess you have already read The Repository pattern and Object-oriented terminology if you are here.
  • Domain model is everything discusses the differences between the domain and infrastructure layers and how to get the best from both. Typically an infrastructure layer is reusable and is provided to the programmer as a library or framework, while the domain layer is the core of an application and is commonly written from scratch.
  • Never write the same code twice: Dependency Injection is an introduction to DI techniques, which allow to produce reusable and testable code. For any non-trivial project at least considering Dependency Injection is fundamental.
  • When to inject: the distinction between newables and injectables expands on the previous article about DI and makes distinctions about which classes are really suitable for injection of collaborators and the cases when it is an overkill.
  • Factory for everything focuses on the object graph building aspect of injection and on how to implement the [Abstract] Factory pattern, presenting a refactoring example towards it.
  • Object-oriented myths deals with common legends about supposed futility of good object-oriented design, such as overuse of factories and getters&setters versus encapsulation.
  • The rest of the object-oriented myths is the second part of the previous article on myths, and talks about singletons, lazy loading and Utility classes.
Then, I listed the articles in the SOLID principle series, which comprehends posts about the five object-oriented design principles officially formulated by Robert Martin (though they are not the work of a single man). This set of principles strives for loose coupling and reusability of components like classes and interfaces.
I hope you find these resources useful. Anyway, happy Halloween!

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