Monday, November 16, 2009

Defaulting to private

While writing classes, which scope do you normally choose for your fields and methods? Do you consciously choose a visibility or just stick with what your IDE proposes?

Before dig in the philosophical discussion, let's summarize the different visibilities available in object-oriented languages:
  • Public: no limitations.
  • Package: scope level available in Java but not in C++ and php. The member can be accessed by code that resides in its own package.
  • Protected: the member can be accessed only by its own class and by subclasses. Similarly, Friend visibility in some languages is used to allow friend classes to access the field or method.
  • Private: the member can be accessed only by code of its own class.
Note that I said its own class, and not its own object, as private fields are usually accessible by other objects of the same class.
<?php
class ComplexNumber
{
    private $_real;
    private $_imaginary;

    /* constructor and other methods... */

    public function equals(ComplexNumber $another)
    {
        if ($another->_real == $this->_real 
        and $another->_imaginary == $this->_imaginary) {
            return true; 
        }
        return false;
    }
}
The reason behind this behavior is that encapsulation with limited visibility facilitates changing the code. If we are modifying the $_real and $_imaginary fields we are changing the class, so there is no problem in limiting visibility to the class code instead of a particular object (forcing an object to access only its own private fields and not its brothers' ones).

I am a proponent of test-first approaches to software development and this means I often implement in production code the simplest thing that could possibly work, and that makes my tests pass. Another limitation I follow during development is visibility: if there are no tests that access a property or a method, there is no reason for it to be public.
Whenever I create a new class member, being it a field or a method, I default to private or protected for its visibility. Only if a method is the subject of a test it becomes public, while it is very rare that I need a public field.
This rule of thumb gives the code the advantage of increased encapsulation, since public visibility is chosen only if mandatory. The distinction between private and protected is relevant only if you allow subclassing, an action that you usually control if your code is not part of a framework or public library.

In php 4 there were no visibility modifiers, and all members were public. This was one of the serious limitation of supporting php 4 for object-oriented applications, like CakePHP did. Apart from naming conventions, there was no way to tell apart methods which were in the Api and internal ones, which could change in any subsequent release. You can tell developers that private methods start with '_', but if there is no forced limitation of scope it is very simple for a developer to do the quick hack such as calling an internal method.
Thus, the advantage of greater encapsulation is to keep the Api small, reducing coupling and having less method signatures carved in stone. Any source file can call a public method, so you cannot simply change its parameters and side-effects. While renaming a method is often simple thanks to modern IDEs (or sed), if you change the behavior of the method you have to review every place in the codebase to make sure there are no incorrect assumptions.
On the other hand, if I decide to expose a method as public, I want a test that forces me to comply and that would be red if the visibility is different. This process explicates the contract of the class, and avoid breaking a method in the future.

Sometimes refactoring produces a private method worth of testing. However, a private method cannot be tested directly but only trough public methods of the same class. Still, it is covered indirectly because if it were not you would simply remove it as unreachable code.
If you feel like testing it independently, it is probably the sign this method carry out tasks out of the current class's responsibility, and you should move the private method in a collaborator (which may have to be created from scratch).
Encapsulation would be maintained since the collaborator would be stored as a private property of the SUT. If the method cannot be moved out and cannot be exposed, it should not be tested: you maintain the freedom to change it later as long as your public methods does not make the tests red.

So, whenever you are coding object-oriented applications, I suggest to keep as many methods as you can private, and expose public methods only for contracts between classes.

Sunday, November 15, 2009

Now on Facebook

I created an handy Facebook page for people who want to follow Invisible to the eye via this great social network. All new posts will be also referenced on its Wall to provide prompt notifications for you.


Saturday, November 14, 2009

How to eliminate singletons (part 2)

In the previous post I hacked-up a very small component for automating dependency injection of php classes, which mimic the behavior of the moltitude of dependency injection frameworks out there.
The question arised in the last part of the article was How can I construct objects with a shorter lifetime than the application-wide one? In Zend Framework's case there are many controllers and view helpers that we want to instantiate only if necessary and which proper instantiation should happen only after a bit of logic has been executed, for instance after the http request has been elaborated by the router to produce a controller name.

With manual dependency injection the solution would be straightforward: just inject a ControllerFactory in the Zend_Controller_Dispatcher_Standard, which is the object that currently creates the controller. But the Zend_Controller component manages userland controllers and we cannot code a factory in advance to cover the possible use cases in every domain, nor we want the end-user to write boilerplate code in the form of a factory for his controllers.
Since the only viable solution is automatic dependency injection, we should create a configurable factory instead:
$controllersConfig = array(
    'My_Controller' => array(
        'myClass' => 'My_Class'
    ),
    'My_Class' => array(
        // ...My_Class's collaborator names listed by key
    )
);
$frameworkConfig = array(
    'Zend_Controller_Dispatcher_Standard' => array(
        'controllerProvider' => 'Zend_Controller_Provider' 
    ),
    'Zend_Controller_Provider' => array(
        'config' => new Zend_Config($controllerConfig) 
    )
    // ...collaborator configuration of the router, the front controller, etc.
);
I use the name Provider since it was popularized by Guice, but it is in fact a configurable Abstract Factory. The Zend_Controller_Provider class can be decoupled with a small interface:
interface  Zend_Controller_Provider_Interface
{
    public function getController($name);
}
class Zend_Controller_Provider extends Injector 
      implements Zend_Controller_Provider_Interface
{
    public function __construct($options)
    {
        parent::__construct($options['config']);
    } 
 
    public function getController($name) 
    {
        return $this->newInstance($name);
    }
}
The provider subclasses the Injector from the previous example to keep the code example short, but using composition of an Injector instance would make no difference.
The Injector code has to be extended a little to allow specifying objects in the configuration:
<?php
class Injector
{
    // ... constructor and private members
    public function newInstance($class)
    {
        if (is_object($class)) {
            return $class;
        }
        // default flow
        if (!isset($this->_config[$class])) {
            // it's a literal value like 'mydbpassword';
            return $class;
        }
        $collaborators = array();
        foreach ($this->_config[$class] as $collaboratorName => $collaboratorClass) {
            $collaborators[$collaboratorName] = $this->newInstance($collaboratorClass);
        }
        return new $class($collaborators);
    }
}
Including objects in the configuration should be done only in the case we need collaborators which are really only Value Objects with no behavior, like Zend_Config. It would be more complicated to set up different Zend_Config objects for injection, while it is actually a newable class (and so should not be injected, like we would not inject an ArrayObject).

Let's list the advantages we have just gained:
  • Independent instantiation of controllers. The Dispatcher will new only the controller actually needed (but it is the injector that will call new). Another provider can be set up for view helpers and other short-lived classes.
  • Real unit testing for controllers and view helpers: it will be easy to inject stubs and mocks in a controller since now it is forced to have setters or a unified constructor.
  • Real unit testing for the dispatcher: we can inject easily a fake Zend_Controller_Provider_Interface implementation, and test that given the right parameters it requests the chosen controller class.
Note that it is correct for shorter-lived classes to have field references to longer-lived ones. For instance the Url view helper should be injected with the current instance of the router since it needs the collaboration of something that knows all the defined routes. So one more question arises: how the problem can be solved now, given that the Zend_Controller_Provider class is created only with a Zend_Config as a parameter?
The simplest thing that can work in this case is to implement a generic Provider interface with a setInjector(Injector $longLiveInjector) method, so that when the interface is detected the original injector can create a clone of itself (that still references the created objects) and pass it to the short-lived objects provider, in this example Zend_Controller_Provider. The Provider then can add to its Injector the controller configuration instead of extending it, even favoring composition over inheritance.

I'm sure production-ready DI frameworks solve all these problems and maybe other ones, since it took us only two days to figure out the theory of operations. Automated Dependency Injection is a must-have in Zend Framework 2.0 and this is a proof of concept of how it can be implemented.

Friday, November 13, 2009

How to eliminate singletons

There has already been a bit of discussion in the zf-contributors mailing list and in the wiki about the Zend Framework 2.0 roadmap, which will guide the Zend Framework's evolution in php 5.3 and the new classes' development.
One of the key point in the architectural discussion is singletons usage. Singletons are scheduled for termination and in my opinion they just have to go (unless they represent a global state which cannot be reset for real, such as autoloading).

It is actually very simple to eliminate singletons: just force the components to ask for what they need in the constructor or via setters or via inject*() methods, instead of looking up a singleton trough a static method only to obtain a reference.
Once this fundamental decoupling is achieved, the hard part is tackling the construction problem: Zend Framework has a big codebase and writing a factory (manual dependency injection) for every use case is not viable.
Thus, automatic dependency injection needs to be called upon. There are many xml-configured dependency injection frameworks for php to incorporate, but let's show a simple example of how they works.

Suppose we want a reference to an instance of My_Class in a controller, and we want to have its collaborators automatically injected by some component. As the requirements say, My_Class has a unified constructor which would pass the collaborators to the setters, but dependencies resolution is possible also with setter-based injection. I would really prefer a bunch of setters if there are many dependencies.
This code is based on Zend Framework 1.x classes as I do not want to counfound anyone.
<?php
class My_Class
{
    public function __construct($options)
    {
        // calling setters or having them called...
    }

    public function setAdapter(Zend_Db_Adapter $adapter)
    {
        if (isset($this->_adapter)) {
            throw new Exception('Adapter cannot be changed once set.');
        }
        $this->_adapter = $adapter;
    }
}
Since I want to show how to eliminate singletons, I have declared a dependency towards a Zend_Db_Adapter instance, which is commonly put in Zend_Db_Table::setDefaultAdapter() as a singleton. It does not matter that singletonitis is cared for by another class: in this case it is still mutable global state and the same problem is present for the front controller instance. I did not feel like including a Zend_Front_Controller instance in this example as it is often used only as a mean to access other objects, and the underlying problem (Law of Demeter breakage) is not resolved by injecting it.

Configuration has to be defined in a plain old array which will be used by the container:
<?php
$config = array(
    'My_Class' => array(
        'adapter' => 'Zend_Db_Adapter_Mysqli'
    ),
    'Zend_Db_Adapter_Mysqli' => array(
        'driver_options' => ...  // username and password here
    ),
    'My_Controller' => array(
        'my_class' => 'My_Class'
    )
);
Eventually, the controller can now ask for collaborators instead of grabbing them from other sources. This data structure is very basic but it will do the trick for now.
An automatic dependency injection component would simply recursively resolve dependencies:
<?php
class Injector
{
    private $_config;

    public function __construct($config) { // assigning config to private member.. }

    public function newInstance($class)
    {
        if (!isset($this->_config[$class])) {
            // it's a literal value like 'mydbpassword';
            return $class;
        }
        $collaborators = array();
        foreach ($this->_config[$class] as $collaboratorName => $collaboratorClass) {
            $collaborators[$collaboratorName] = $this->newInstance($collaboratorClass);
        }
        return new $class($collaborators);
    }
}
and the bootstrap would be very simple:
$injector = new Injector($config);
$application = $injector->newInstance('Zend_Application');
Of course Zend_Application might be refactored to become the injector itself, so the object really constructed could be an action or a front controller. This code is very basic and can be improved with objects caching (to prevent multiple connections from being instantiated) where appropriate, a list of "global" classes (which scope is however limited to a Zend_Application object and can be throwed away whenever you want) to prevent configuration to grow too much, and in another hundred ways.

The problem with this approach is that we have, for example, to instance all the controllers and all the view helpers because we don't know which will be used during this request, since the object graph construction process is completed before the request management: what did you expect from ten lines of not-TDDed code? :)
This paradigm of one-time instantiation is typical in Java applications, where nearly eveything is instanced in the bootstrap "just in case". Php has a shared-nothing architecture and instancing more than the necessary objects would be a waste.
In the next post I will solve this big issue using deferred istantiation and different injectors, and showing how nearly all singletons can be reduced to injected collaborators.

Thursday, November 12, 2009

Zend Framework 2.0

I just wrote in a comment that Zend Framework 2.x did not yet exist and, today, the lead developer Matthew Weier O'Phinney has posted the roadmap for the 2.0 version of the framework, invitating php developers to participate in the discussion by commenting on the wiki or via the zf-contributors mailing list.
I already posted some questions on the wiki, but I would like to expand my thoughts on the architectural changes from a testing and design point of views, that are what interest my readers.
Here's a list of the guidelines that have the greatest impact.

Unified constructor
Every injectable class will have a constructor which accepts an array or a Zend_Config (I guess it will become Zend\Config) instance whose elements are passed to setters. This is becoming more and more the most adopted injection paradigm also in the 1.x branch. A standard is necessary and in a dynamic language like php the unified constructor works well, while accessing type hinting via reflection like Dependency Injection frameworks do in static-typed languages is troublesome and I don't even now if it is possible.

Elimination of singletons
Eventually, singletons will be refactored and we will stop seeing Zend_Controller_Front::getInstance() calls scattered in all the codebase. The various reset operations accomplished by the Zend_Test component during tests teardown should have hinted that something was fundamentally problematic in the design.

Design by contract
Multiple implementations of interfaces should be allowed by injection hooks, and interfaces should be extracted where needed. The abstract base classes so diffused in the 1.x version of the framework do not make easier to favor composition over inheritance since they force our classes to choose them as the unique parent.

Exceptions without inheritance
An example of avoiding problematic inheritance is the elimination of deep inheritance trees for exceptions. Base exceptions of a component should be interfaces. This is a finess I appreciate.

Namespaces
Obviously php 5.3 namespaces will be adopted and the _ in class names will be substituted by the \ namespace separator.
A thing I downvote is the separate namespace for testing: I would rather have unit tests in a parallel tree like they were in java packages (library/Zend/Filter/Int.php and tests/Zend/Filter/IntTest.php). A parallel structure gives different advantages:
  • saves the developer from having to import classes he is writing tests for;
  • naming collision with the production code are impossible since the class and file names in the parallel tree all end with 'Test.php';
  • the unique use statements expose only the imports the code is performing from different namespaces, expressing the real coupling of the system under test. Coupling to classes which live in the same folder is often inevitable and is not interesting to keep it under control.
Mvc implementation
The Mvc implementation (Zend_Controller) will undergo some surgery to improve performance and simplicity. In my opinion many features can be dropped: for instance I stopped using the action stack to perform multiple operations because it was too slow. It is also not test-friendly since you cannot assert that different actions were performed: I prefer to simply keep my logic out of controllers, so I see no use for great features in request dispatching as long as controllers are proposed as thin classes.
The point of the design by contract paradigm is to gain freedom in setting up the Mvc stack and injecting different collaborators which adhere to the contract. I saw the Phly_Mvc reference implementation and the interfaces are already present; it also uses a publish/subscribe pattern to dispatch events. In Zend Framework 1 we were able to substitute parts of the Mvc machine only by subclassing, while in 2 the approach will be cleaner as code will only depend on an interface.

Zend_Session
The backward-compatibility break in 2.0 version is the right time for changing also Zend_Session and improving its Api and behavior. Testing that involves sessions is difficult and I think the right approach is not transforming Zend_Session in a singleton, but decoupling the controllers code with a session container, which implementation can be injected during bootstrap: it is something I would want to isolate just like a mail service.
The Zend_Session_Namespace objects in 1.x access directly the $_SESSION variable, mutating global state and becoming hard to test: a different solution could be placing them in a $_SESSION variable when they are constructed or reconstituted in their factory (which now does not exist). Anyway, the session namespace objects should do less work, particularly in the constructor.

The discussion is important as we are now shaping the future framework. Feel free to counterargue in the comments and in the wiki. :)

Wednesday, November 11, 2009

What's going on with php object-relational mappers

Every once in a while, in a post, I say:
The Domain Model should not depend on anything else; it is the core of an application. Classes should not extend or implement anything extraneous. I do not want User extends Doctrine_Record. I want User.
Sorry to stress you, but this is one of the points of DDD and the one that gives advantages even applied in other architectures. The persistence problem can be solved by generic object-relational mappers which will act as the bridge between entities and the database used for persistence. But where do we find a generic Orm?

In php, no real generic Orms existed until 2009, since Zend_Db, Doctrine 1, Propel etc. are all implementations of the Active Record (or similar data gateway) pattern, requiring for example all your User and Post classes to subclass a base record. The only way to obtain a persistence-agnostic model was manual implementation of all the mapper classes, which translate between database rows and object graphs. When you are managing more than a few different entity classes the problem become quickly intractable.
The Data Mapper pattern describes exactly a generic Orm, but it is an even more general concept in the sense that the mapping is not limited to a relational database like MySql or Sql Server. You can write a Data Mapper to store your objects in plain text files or document-oriented databases if you want.

In the last summer, I encountered two in-development solutions to solve the persistence agnosticism problem: Doctrine 2 and Zend_Entity. They are implementations of the Data Mapper pattern, with reference to the Jpa specification and a similar Api. I learned that the Java guys had implemented a real Data Mapper years ago: Hibernate. Jpa is only a specification extracted as a subset of Hibernate, and it is an additional layer abstraction that decouples your mapping code (annotations or xml files) from the particular Orm.
Anyway, I contributed to the lazy loading capabilities of Doctrine 2 with php code and to Zend_Entity with some small patches before its discontinuance. I am currently waiting for a stable version of Doctrine 2 to integrate it in NakedPhp, only because I am not worrying about persistence for now. It is the power of the Data Mapper approach that decouples my work from a specific storage such as a relational database.
Fast forward to today, and Doctrine 2 is in alpha for being thoroughly tested. Zend_Entity has been dropped instead, in favor of Doctrine 2 integration in the Zend Framework. It is not useful to maintain two different code bases, with the same Api transposed from Jpa, which do the same persistence-related dirty work and developed by the same people. It's just a waste of the contributor's time.

Thus, Doctrine 2 is going to become the first production-ready Orm for php and to be favored with seamless integration in both Zend Framework and Symfony. If you have not yet tried it, you may want to give it a shot.
If you feel like helping with the integration, which involves Zend_Tool components for generation and Zend_Application resources, join the zf-doctrine mailing list. The integration also comprehends Doctrine 1 since Doctrine 2 requires php 5.3 and its adoption by hosting companies will be gradual.
The adoption of the 2.x branch, when ready, would give your design the freedom from the database you want. Doctrine 2 is for php the greatest thing since sliced bread.

Tuesday, November 10, 2009

Mocking and template methods

As you probably know, stubbing or mocking is a practice used in unit testing where a class methods are substituted via subclassing with test-friendly versions of themselves. The difference between stubbing and mocking resides in the place where the assertions are made, but it is not the main topic of this post.
The need for small and cohesive interfaces is particularly perceived while mocking a class. We typically want to test in isolation a unit and write mocks for its collaborators without going mad.
Let's see an example of a class I may want to mock:
class NakedEntity
{
    public function getMethods()
    {
        return $this->_class->getMethods();
    }

    public function getMethod($name)
    {
        $methods = $this->_class->getMethods();
        return $methods[$name];
    }
    
    public function hasMethod($name)
    {
        $methods = $this->_class->getMethods();
        return isset($methods[$name]);
    }

    // other methods, constructor...
}
As I said earlier, mocking is effective if there is a small interface to mock. Note that every class defines an implicit interface: the set of its public methods. Sometimes the interface comprehends several methods that give access to the same data or behavior, and that have to be present to avoid abstraction inversion. In this particular case, if I defined only getMethods() to conserve a small and cohesive interface, every class that depends on NakedEntity would have to implement the other two missing methods.
Mocking all three methods of NakedEntity in phpunit means writing this:
$mock = $this->getMock('NakedEntity');
$mock->expects($this->any())
     ->method('getMethods')
     ->will($this->returnValue(array('doSomething' => ..., 'foo' => ...)));
$mock->expects($this->any())
     ->method('getMethod')
     ->will($this->returnValue(...));
$mock->expects($this->any())
     ->method('hasMethod')
     ->will($this->returnValue(true));
Compare this to the creation of a real NakedEntity. I should definitely create a real object to save test code, but the unit tests will then not be executed in isolation and I will have to define a mocked NakedClass object (the $this->_class property) and break the Law of Demeter.
Moreover, the mocking capabilities of phpunit are limited and for example we cannot define different return values based on the parameters (a real subclass is needed in that case) without a callback. I could mock only the methods effectively used from the SUT, but I don't really know which of them are really called (since they are more or less equivalent) and I want to refactor the SUT without changing the tests.
So I found a 2-step alternative solution.

Step 1: convenience methods become template methods
I started with refactoring the NakedEntity class:
class NakedEntity
{
    public function getMethods()
    {
        return $this->_class->getMethods();
    }

    public function getMethod($name)
    {
        $methods = $this->getMethods();
        return $methods[$name];
    }
    
    public function hasMethod($name)
    {
        $methods = $this->getMethods();
        return isset($methods[$name]);
    }

    // other methods, constructor...
}
The users of getMethods() are now template methods, and the base method (primitive operation in design patterns jargon) can be subclassed to provide alternative behavior. The subclass can be implemented as a real reusable class, which will include a setMethods() utility method (no pun intended), or via mocking.

Step 2: mock the base method
Now only getMethods() need to be substituted:

$mock = $this->getMock('NakedEntity', array('getMethods'));
$mock->expects($this->any())
     ->method('getMethods')
     ->will($this->returnValue(array('doSomething' => $myMethod, 'foo' => ...)));
$this->assertEquals($myMethod, $mock->getMethod('doSomething')); 
 
This approach works well because the contract of NakedEntity is already cohesive and the different methods provide different ways to do the same thing. The template methods contain nearly no logic and they are exercised in unit tests which are not their own: it is a very small trade-off because it is highly improbable that they will break and cause another class unit tests to fail without reasons. The template methods in this case are only glue code.
Don't use this testing pattern as an excuse to write many public methods: you should indeed break up a class in different units if its contract grows too much. You can implement a Decorator pattern if convenience template methods are implementing business logic on a public method, or it may be the case that your class is doing too much and the Api is too complicated. Another viable solution if you have an explicit interface instead of a concrete class is creating a reusable Fake implementation which will contain the convenience methods as well.
In conclusion, if you have a contract with many cohesive and dumb methods, which relies on a central one to provide data, you can create template methods and reuse them in other unit tests, via subclassing of the primitive operations.

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