Wednesday, October 14, 2009

Php dependencies, require_once() and namespaces

Before the introduction of autoloading, every php class had to be explicitly included before being available, referencing its physical file. Autoloading has decimated this approach but there is also an advantage in using require_once(), the principal construct for inclusion of php class sourcefiles. This pro is pointing out dependencies to other classes and interfaces instead of sweeping them under the carpet.

Back in 2002 and php 4, you could not do things like this:
<?php
$db = new Zend_Db();
When the class Zend_Db is requested, for example to instantiate an object, its name is passed to an autoload function or method and its file included to give the class a chance to be defined before using it. If the autoloading process does not find a class, a fatal error is raised so it's not a little problem you can ignore by tuning the error_reporting level.
However, if you are not using autoloading the following code will be familiar:
<?php
require_once 'Zend/Db.php';
$db = new Zend_Db();
The require_once() call performs a manual inclusion of the Zend_Db class definition file, making Zend_Db available in all scopes. require_once() arguments are tipically relative paths from the list of directories defined in the include_path. Note that require_once() will not include the same physical file more than one time and that it will throw a fatal error too if it does not find the file. Since it is a language construct and not a function, parentheses are not needed.
In a typical project which does not rely on autoloading (such as Zend Framework and PHPUnit), every class file contains a list of require_once() calls at the top:
<?php
/* [license...] */
/** Zend_Filter */
require_once 'Zend/Filter.php';

/** Zend_Validate_Interface */
require_once 'Zend/Validate/Interface.php';

/**
 * Zend_Form_Element
 * [docblock annotations...]
 */
class Zend_Form_Element implements Zend_Validate_Interface
{
    ...
This can be annoying: every time you reference a class you have to write its name, slightly modifying it to form the file name, and put a require_once() call at the top of the file you're working on. I'm sure there are automated tools for this process that scan the file and write require_once()s by themselves, but why adding more lines of code? Isn't maintaining less code better?
Of course it's better, unless the value the code adds to the application is worth the time for writing and maintain it. Otherwise there will never be new features in applications since no one would want to write new code.
The value provided here is declaration of dependencies. From the first part of Zend_Form_Element class file, I instantly learned that it has a dependency on Zend_Validate_Interface (obviously because this class implements it) and on Zend_Filter.
For example, these dependencies lists have been used for automatic generation of packages: you pick for example Zend_Form and a script packs all its dependencies in a zip you can download and decompress in your library folder. It would be great if it has no dependencies, but for a component to be useful a little coupling is mandatory.
During development, is always useful for current maintainers and for new programmers to learn the dependencies a class has. There is no need for static analysis tools in Zend Framework: simply open the file and see what is being included.
The problem is this methodology does not feature transitivity: Zend_Filter can be dependent on other classes and interfaces without them being listed in Zend/Form/Element.php; the inclusion of their files is placed in Zend/Filter.php and it's not a strange choice. Though, to test or develop a class you probably only need to know its direct dependencies (that's the usefulness of encapsulation) as they are classes which it communicates with by method calls and composition. In unit tests, for example, I'll mock out Zend_Filter and I won't care what it depends on.

Another problem is require_once() ties the dependencies to physical files. Unlike Java import statements, which references only a fully qualified class name such as Zend_Filter, we are including Zend/Filter.php; it is unlikely that this location will change in the future if the include_path is set correctly, but why saying something we do not intend? I really care only to state there is a dependency.
Php 5.3 can help us.
In an hypothetical version of Zend Framework with namespaces, the code of Zend\Form\Element will be as simple as:
<?php
namespace Zend\Form;
use Zend\Validate\ValidateInterface;
use Zend\Filter;
This form of collateral dependencies declaration was created to avoid name clashing. Its advantages are clear:
  • it does not say anything on the file containing the referred class or interface;
  • it is not needed for classes contained in the same namespace (like it was a Java package). Classes often depend on siblings and with require_once() statements we would be cluttering the list of external, important dependencies with the internal and obvious ones.
  • it also shorts the names available for the collaborators: you can refer to Filter and ValidateInterface in the source file.
  • it also declares what namespace/package the class belongs to, without recurring to docblock annotations.
I hope you now do not find so boring to write and encounter use statements (or require_once() calls), backed by autoloading. Their purpose is not only to help the php interpreter, which would not work otherwise. You can take advantage of them also to declare dependencies to other developers and automated tools: the next person that will start reading your code from scratch will be grateful.

Tuesday, October 13, 2009

The rest of the object-oriented myths

This is the second part of the post Object-oriented myths. You may want to read the first part before going forward.

In the last post we were talking about the advantages of encapsulation, Dependency Injection and factories. Let's dig in other legends about object-oriented programming and how it makes you write boring and difficult to understand code (clue: it is not true).

''But I will need a Factory for every object. What a pain to write all these classes.''
No, this is not true, you will often need at most two or three factories. I have seen Misko Hevery answers this question multiple times in his blog and talks.
First, simple classes like entities, without collaborators, do not need factories. Second, the same factory which builds the application (at every http request if you are using a shared-nothing architecture such as php's one), builds everything with a lifetime equal to the request one. All these objects such as front controllers, loaders and so on are built from the same factory and injected as collaborators when you call MainFactory::createApplication().
Maybe you need other objects with a shorter lifetime: for instance consider view helpers for web applications, which are used for creating html code that would be boring to write by hand. Their creation can be encapsulated in a ViewHelperFactory class since it's a waste to create 50 helpers at every request when only a handful of them may be used. So an instance of ViewHelperFactory is built in MainFactory and then injected into the view object that renders the page. Helpers are thus created as needed.
This identical multiple-lifetime pattern is reflected in Java when dealing with Session-wide objects and Request-wide objects, the formers being built at the startup and the latters with a RequestFactory. You can have how many levels you want, for instance a MainFactory/SessionFactory (the principal one of the application) can create a RequestFactory which can in turn create a ViewHelperFactory, all these creations at different moments in execution. In php, though, everything is garbage collected at the end of the request so there's one less level.

''I should use a Singleton and implementing in it lazy loading, so that I make sure there is only one instance of my database connection, and only if it's used.''
What is the responsibility of your PDO/Zend_Db/My_Db_Adapter/Connection instance? Bridging your code with the database. It probably needs a QueryFactory if you create query objects by calling it, but it's not the point of this paragraph. So the responsibility of the db object is not to control that there is only one instance of it and nor it is to lazy load itself. This responsibility should be in its factory, which will cache the instance to perform lazy loading and ensure only one connection is created. Following the previous example, MainFactory will pass the same instance of DbFactory to all your classes that needs it, and the connection will be shared and conserved as a DbFactory private field. Consider also to just pass in the db object if you do not really need lazy connecting capabilities.
If you do not multiply the instances of a Factory, it can perform lazy loading and Singleton-like behavior, without obscuring your design with global state. And you can easily avoid duplication of factories by creating and kepting them in the MainFactory of your application. Using a Singleton is a symptom of unresolved dependency, since a Client class, with empty constructor and no setters, can reference a singleton, lying about what it needs to work correctly and causing debugging nightmares when an hidden collaborator breaks. You'll find out while testing, reusing and reading this type of code that it causes great pain: it's not an oop fault, but thoughtlessness of who designed the Singleton.

''Let's make an Utility static class where we can put all these methods. They seem to not have a place to live in.''
Using an Utility class is a smell that you have code which should belong to already existent classes. You should consider to put these methods in the objects which they work with, or to create services to give this code a home if they do not fit in an already existent class. In these service classes you can put cohesive sets of methods which depends on the same collaborators, instead of creating a big static Utility class where you sink all code that does not make sense elsewhere, and which becomes a concentrate of dependencies, being impossible to mock out. A service is passed only in the classes that need it instead.

I hope I have contaminated you with real, confident object-oriented programming ideas. Oop has a learning curve but it should not be difficult in the long run: it is a tool created to simplify the programmer's life and not to make him experience pain and boredom.

This post's title is an homage to The Rest of the Robots. Asimov is one of the few science fiction authors that keep me nailed to a book.

Monday, October 12, 2009

Object-oriented myths

I think object-oriented programming techniques should be explained with a context and not shouted out loud as philosophical principles. Sometimes these techniques are misinterpreted, or exaggerated and used as a weapon against oop proponents.
Some popular myths about oop have risen in the programming world, particularly in the php continent where object orientation is still in its infancy. I want to debunk these legends to show that good oop is actually easier than you think. For instance, Dependency Injection is one of the best thing that can happen to your code.


"You should not expose public fields. Write getters and setters instead."
The point of encapsulation is to protect client classes from changes in the collaborators. In what is using a set*() method different from a public field, for the cause of encapsulation?
There are some classes which only responsibility is to maintain state. We encounter them in every project, being their names User, Post, CreditCard, String, Regex and so on. It is correct for this type of classes to have getters and setters to change their internal state and fulfill their requirements.
The other type of classes are services: stateless objects which do complex work, are not serializable and may have internal and external dependencies, towards other services or processes. These classes should not have any get*() or set*() method, since they are by definition stateless and the list of getters will break encapsulation. If I were a client class I would require a BookRepository object to search books, because I use it to... search books and not to change the underlying database calling BookRepository::setDb(Zend_Db $db). It's not my job to pass the collaborators in: I use the object only to search books.
If you find a complex service class which also has a state, the most useful thing to do is to break up the class in little ones because the responsibility is too high for a single unit. Testability and cohesion will improve.
So without setters, how I get collaborators references in, for example, a ServiceClass object private fields? You can create them directly in ServiceClass methods (bad) or realize Dependency Injection, passing them in the constructor of ServiceClass. A Factory will then call new, passing in the collaborators and encapsulating the creation. This practice leads us to the next myth.

"Why using a factory? There's no point in creating an object only to create another one."
The process of an object's creation can be intensive and complicated. If you use Dependency Injection (and you probably should as it is a standard practice for producing solid object-oriented code), every object needs its collaborators passed in the constructor, and the collaborators need other collaborators and so on. It's useful to abstract away this process in a Factory class whose methods perform the construction in one centralized place. Again, entity objects like Strings, Users and Posts are a bit special and using a Factory for them is not required, provided that they don't even had collaborators.
Though, if you find yourself creating a factory and subsequently, in the next line of code, using its methods to create a business object, chances are the design can be improved. The principle is that objects should ask for things, and not look for them.
Let's make the following assumptions:
  • You write object-oriented applications, so all your code is kept in classes. This is not necessarily true for hybrid languages like php.
  • You strive for minimizing the coupling of your components, respecting the Law of Demeter. You want to reuse classes and you want to be able to test them in isolation.
So start with examining where you are creating a BusinessObject in a class Client. The possible cases are three (actually two):
  • (not possible) BusinessObject has a longer lifecycle than Client, so you cannot create it in Client. Ask for it in the constructor.
  • BusinessObject has the same lifecycle of Client: it's a collaborator. So stop using a factory and simply ask for BusinessObject in the constructor of Client.
  • BusinessObject has a shorter lifecycle than Client: it must be created at a specific time, when some method on Client is called.
The latter case is the most interesting one. If BusinessObject is an entity, you can create it directly: there are no external dependencies to inject and there is little behavior to mock out in tests. If BusinessObject is a service class, with one or more external dependencies and more than a bit of behavior, you should indeed use a Factory to encapsulate its creation. But since you strive to reduce coupling, Client must not know if BusinessObject calls methods on an hundred different objects or returns prepackaged results. So you should pass in a Factory object in the constructor of Client: this solution resembles an Abstract Factory pattern, with the difference that we are focusing on lifetimes and not on extensibility and introduction of new subtypes.
In sum, all direct service object creation (use of the new operator) should be encapsulated in Factories, which can be used in the application bootstrap or passed in the constructor of the Client class if you need object creation as a business requirement (and the object is more complex than a String). Obviously if you are using setter injection it does not make a great difference, but the Api will be more cluttered. If your setters does not accept multiple calls to change collaborators, they have my blessings.
Warning: all the class names used are examples. For instance Client and BusinessObject are two classes that could also be called A and B. I often use Client to denote a class which is attempting to create an object, according to the GoF terminology. BusinessObject is a generic name for a class, more readable than Foo and Bar.

This post is becoming too long to not lose focus, so I'll continue tomorrow with the rest of object-oriented myths.
You may want to subscribe to the feed to discover the other myths as soon as they are published.

Sunday, October 11, 2009

The value of abstractions

There is a constant trade-off between levels of abstraction and performance problems in software development and in other fields. We write code in high-level languages and not in assembly or machine code, but sometimes go down a level to write fast C extensions.
Every time you call a function, being it your own work or provided by a language or a framework, you are using an abstraction: is it worthwhile or you're wasting time writing bloated levels of indirection?

To understand the importance of abstractions in modern software, consider the process of retrieving a web page. When you type an url in the location bar of your browser, the following abstractions are taken advantage of:
  • first of all, the location bar, plus the form and inputs system, is an abstraction over the raw Hyper Text Transfer Protocol (HTTP). You don't write http requests by hand like GET /.
  • the http request and response are transported over a text flux based protocol which resides at a lower level of abstraction, the Transmission Control Protocol (TCP). The purpose of this abstraction is to free the high-level protocols from the burden of considering segmentation of messages.
  • the TCP layer then uses the underlying one, the Internet Protocol (IP), to deliver packets back and forth from your machine and the webserver, and to ensure their reliable transmission. IP abstracts away physical details by mapping internet hosts with numeric addresses, the famous ip addresses everyone is always talking about.
  • IP layer uses one or more data link layer protocols, such as Ethernet, to send frames of data between physical network points. These points are identified with Mac addresses in an Ethernet architecture.
  • While Ethernet is capable of physically transport data by changing the voltage over wires, it uses electronic circuits as black boxes that perform mathematical and logic calculations, like Cmos logic gates. These circuits present only binary voltage levels as their output and hide all the transistors they are constructed with.
That's a total of five levels of abstraction only to retrieve a web page. But there's more: every time you write a function or a class you are producing an abstraction. You hide the details of implementation as private members of a class and present a public Api which constitutes the abstraction considered. Moreover, if you design an object model, or a relational model, or every kind of model, you're abstracting away details from the real world. When writing the classic User class for a blogging application, you probably do not include the height or the eyes color of the user as a field.
Even assembler has procedures: multiple level of abstractions are present in every piece of software we encounter.

We have said that there is a trade-off in using abstractions: there are a lot of advantages in dealing with less data and a simplified model of the reality, built according to the desire of the abstraction user. This user can be an upper layer of abstraction or a real person. These advantages, however, come with a cost:
  • Performance cost. Every software layer has an overhead, which is time spent performing management operations and not business (read useful for the job at hand) ones. If you're calling an external method or function, you're pushing variables on the stack and passing the control to a subroutine: the cpu also must take the time to do allocate all local variables. More abstracted code is also prone to have a long execution complexity to consider every possible case it should manage. Multiplying these time costs for thousands of calls gives you the picture.
  • Limitations of the interface. When you want to do something the abstraction does not provide as a feature, you have to go down at a lower level and it's often a not pleasant activity.
  • Leaks. Sometimes an abstraction performs horribly if you do not take into consideration at all what it hides from your view. For instance, in Java the Remote Method Invocation feature lets you call methods on other phisycal machines objects, treating them as local instances. Imagine what happens when the connection is slow or too many calls are made...
The pros of abstraction, however, are usually by far more powerful than the cons:
  • Simplicity of the interface when there is no need to consider the underlying layer; think about the location bar of your browser again. This is a fundamental principle of software development, Divide et impera.
  • Standardization and reusing: the Tcp layer abstraction is used by all the upper level protocols, such as Ftp, Smtp, etc.; they do not have to implement their own low-level procedures.
  • Decoupling: the protocols from the upper layers and the high-level software components (if correctly designed with Dependency Injection) are decoupled from the low-level implementations. This is true for Ip which decouples browsers from knowing the voltage levels to transmit, and for Zend_Auth php objects which do not know if they are authenticating credentials against Ldap, a database table, or whatever.
The trade-off is present in nearly every component of a software application: a discussion started on my previous post on php profiling about whether it's right to use a framework and an Orm as abstractions on the php core capabilities, or to cut out the middle man and just access native php directly. In general, I am a fan of the abstraction choice, since the advantages it provides are concrete and immediate, while the disadvantages are only hypothetical. Maybe the performance will need optimization and caching; maybe the abstraction will leak details; but surely the developers work will be simpler than just using native php and the flexibility of the procuced code will be increased.
There is also the fear of overengineering an application. But don't let fear take control of your development process: do informed choices about using frameworks and external tools. Experiment and understand strong and weak points of different approaches before adopting or removing a level of abstraction.

One famous quote summarizes this post:
There is no problem in computer science which cannot be solved by one more level of indirection, except too many levels of indirection.

Saturday, October 10, 2009

5 reasons to use a framework

In my last post, Optimizing a php application in 5 minutes, a reader pointed out in a comment the performance problems that derive from using a framework. I believe generalizations of development techniques can be dangerous, so I'll present my thoughts on the advantages of incorporating a framework in a php application.

Here is Rob's original comment:
    How would using a bloated framework help you scale in a big application? The Zend Framework is full of useless wrapper and abstraction classses (Zend_Session, Zend_Db spring to mind), which add extra overhead and require_once's to your codebase. If I were optimizing a large app, I'd use as much of PHP's native functionality as possible and look at implementing other CPU and resource intensive operations in C/C++. The Zend Lucene module for example, is implemented entirely in PHP and as a result scales horribly and performs terribly when compared with Lucene or clucene (for which there's a pecl extension).
    The point is this, if you're looking at building performant apps that will scale, you shouldn't be implementing someone elses framework solution that has wrapper classes for native PHP functions and requires ten classes (require_once) just to bootstrap an application. PHP should look like PHP, and SQL should look like SQL. Don't use an ORM. You need to know what your SQL is doing. You need to be able to stick an EXPLAIN in front of a statement or move from in-line SQL to stored procedures. Avoid using expensive functions and classes written in PHP (Zend PDF, Zend Lucene). Look for pecl extensions or try and roll your own - they aren't that difficult once you get the hang of them. -- Rob Hofmeyr
I am a keen user of Zend Framework, one of the leading frameworks for the php language, and I want to show the reasons why I'm incorporating such a bloat in my applications.

1. Optimizing the right thing
As I pointed out in the post about profiling, you should take your time to optimize bottlenecks in an application, and finding them before intervening is mandatory. The Zend Framework Mvc stack has a fixed time cost per request, and while the application grows and the operations performed in the controllers multiply, remains more or less fixed.
The ports of the application, where it communicates with the external world, are more likely to need optimization and caching: web services and database calls are the most popular bottlenecks. Also intensive calculus operations can be moved in a C extension, but this is not the general case. The majority of php applications only deal with data, and bridge databases and other services with the end user. Note that my examples in the previous post were about a in-development application which is still fairly small at the moment: there were no references to external services. If your searches are heavy for the database, would you prefer to cut out the object-oriented library and construct sql by concatenation, or to cache results for some seconds?

2. Powerful library
Before rolling out your own solutions and reinvent the wheel, you should ask yourself some questions:
  • Am I likely to replicate all the functionality required by my application with the same quality of a collectively developed framework, with people that file bugs and submit good patches every day? With the same test coverage?
  • Am I likely to avoid the same bloat I am trying to avoid while adding more and more features to my own library?
  • Am I be able to develop all these things by myself, with time and cost restraints?
The cost of a popular solution derives from all the features that are included and that we do not take advantage of. But the maintenance burden is taken care by the core developers of the framework and by its community, while you're left with smoothing and optimizing the code to boost your performance (using a cache where it's needed, which it is often provided with the framework). Given the other advantages, it's a trade-off I'm willing to make.

3. Object model
Php frameworks provide a basic object-oriented library, even only by wrapping native php functions. This is necessary because I (and thousands of other php developers) deal with an object model. This means using an object-oriented approach and producing classes instead of functions. For the sake of unit testing and decoupled design, the infrastructure of an object model should be also object-oriented.
So why I'm using an Orm? Because it lets me work with my object model and then persisting all changes in a relational database. If not, I would have to write all my persistence and loading Sql by hand, and probably ending up in writing a general-purpose solution which I'll use for all my classes, to avoid maintaining boilerplate Sql all the time. This solution will resemble a generic Orm.
And why I'm using a framework? Because it has a general-purpose Orm included (although in php pure persistent-ignorant Orms are not stable yet; think of Doctrine 2 and Zend_Entity).

4. Standardization
Obviously a Zend Framework developer can work on many applications that rely on its components: his ability and knowledge is valuable on a wide range of codebases. In-house solutions are probably related to one or more projects and if you start to stretch them to cover more cases you'll find yourself building a generic framework like Zf.

5. Flexibility
A php framework fills the holes in the php language. Zend Framework takes advantage of the Spl and Pdo but it provides database adapters which really abstract away MySQL and Oracle, translation adapters which abstract away Gettext and Xml, feed objects that abstract away Atom and Rss... I can go on.
Object-oriented components make me happy: apart from Standard Php Library and PDO, much of the php functionality resides in functions while it will be more useful to me in classes and interfaces, giving me polymorphism and inheritance capabilities. This architecture is much more flexible than a procedural one.

For small and prototype applications a framework is not needed. But if you want to scale in lines of code, and not scaling in requests per second only, considering a framework can help you very much in the long run. Do not focus on saving cpu cycles, but developer's brain ones.

Friday, October 09, 2009

Optimizing a php application in 5 minutes

It is often said that premature optimization is the root of all evil: it is indeed true that the optimization stage must come after the main development of an application has been completed. Optimizing means reducing loading and execution times, improving the user experience by making the application reacting more responsively.
When it comes the time to optimize your web application, don't go blindly searching for the bottleneck. Often there are no obvious improvable points in a codebase and your assumptions about the slowness causes can be wrong. Profiling is the activity of discovering what is forcing your application run slower than expected, by analyzing the code execution and time tracking.
If your language of choice is php, fortunately this process takes only 5 minutes.

Minute 1: xdebug installation
In a shell accessed directly of by ssh on the server which runs the php application, type:
sudo pecl install xdebug
Obviously if you already have xdebug on your development server you can skip this step. The pecl binary should create a minimal configuration for you, but if you not see a line referencing xdebug.so in your php.ini add it by yourself:
zend_extension=/path/to/xdebug.so
The xdebug extension provides many utilities to php developers. One of them is the profiling of code execution.

Minute 2: xdebug profiling configuration
Under the loading directive of xdebug in php.ini, add the following lines:
xdebug.profiler_enable = 1
xdebug.profiler_output_dir = /tmp
These directives tell xdebug to enable the profiler from the start of php scripts and to put cachegrind files in /tmp, after the script have finished running. The cachegrind files are lists of all the function calls made during the script execution, along with their source and information on the elapsed time. Make sure there is enough disk space on the folder you choose to kept them, since their size can quickly go up to hundred of megabytes, and to disactivate the profiling directives after you finished your optimization work.

Minute 3: load a page of your choice
I hope this does not take an entire minute, otherwise a long optimization phase will be mandatory.

Minute 4: installing webgrind
At http://code.google.com/p/webgrind/ you can download webgrind, a web application created for interpreting cachegrind files, which are not human readable. There are other solutions for reading cachegrind files, but I prefer a portable web application since where there is php, webgrind can be installed.
Simply decompress the package into a folder in your webserver and load its path it in the browser. Webgrind is written in php5 and it does not have dependencies to configure.

Minute 5: loading a cachegrind files and observing the result
Select from the webgrind menu Show 90% of [select a cachegrind file] in percent|milliseconds, and hit update. After the file has been uploaded and analyzed, a list of functions and methods similar to the following will be shown:


Every function comes with a color that distinguish it between userland functions (green), php functions (red) and constructs (gray), such as require_once(). Probably you can optimize directly only the green functions, but other tools such as the apc cache can improve the constructs as well.
The numbers crunched by webgrind comprehend the Invocation count (the times the function has been called), the Total self cost and the Total Inclusive Cost. The latter is the time elapsed between the function calls and the instant when they returned a value; the former is the effecttive time spent in the function body during the execution, excluding calls to other functions. You should find obvious optimization spots observing Total self costs, and in fact the default ordering of webgrind uses this metric.
I added a long, no-op for cycle to the constructor of the NakedService class to simulate a bottleneck like a slow query or an access to a webservice. See by yourself what happens when I profile again:

Look for places in your code that can be improved in speed not with static analysis, but enabling the profiler during the real execution.
I hope the 5 minutes have been well spent. Profiling applications is often necessary and it should not be difficult once you have this structure in place.

If you want a large sample of requests to profile only the frontend, you should use Apache Bench instead.

Thursday, October 08, 2009

Unit testing view helpers

The architecture of the Zend Framework, one of the most popular php frameworks, is very extensible and presents a lot of hooks for subclassing and new implementations. The problem which arises from time to time is the testability of the components produced: view helpers are an example of problematic testing and here I will write about solutions for unit testing them.

View helpers are a key point of the Mvc implementation in Zend Framework, along with the Zend_Controller component. The responsibility of view helpers is to keep programming logic out of the view scripts, which are rendered by the view object. We are talking about the presentational layer: every big of logic kept in a view helper can be reused in other scripts.
View helpers are instantiated on the fly by the view object (a Zend_View instance, or another Zend_View_Interface implementation) and kept there. This object will then include the scripts in a method, providing access to its scope to call fake methods with the name of view helpers (a __call() implementation). Since the scope of the object provides the $this handler, view scripts reference it to call view helpers:
<?php
echo $this->doctype();
?>
<html>
...
This script takes advantage of the Doctype view helper (a Zend_View_Helper_Doctype instance) to produce an html doctype declaration.
You can also write your own view helpers: according to the manual, they should provide an empty constructor to allow instantiation by the view object and a method which name corresponds to the class base name. For instance doctype() is the strategy method of Zend_View_Helper_Doctype.
The view helper class should implement Zend_View_Helper_Interface, which has the only injection point in this architecture, the setView() method.

The empty constructor is the problem in view helper management, since it gets in the way of simple test code when you write view helpers that make use of other view helpers as collaborators. For instance, I wrote yesterday a IconLoader helper which use the standard HeadStyle one to add css rules to the page.
The injection point which I was talking about, the setView() method, is called after instantiation. Once my IconLoader helper is instantiated, the view object injects itself in the helper using this method, providing a reference to other helpers.
In this design, the view acts as a Service Locator, and we have no idea which helpers could be called by another one: every helper class could depend on everything else.
Unit testing prescribes to test the helper class in isolation, substituting the collaborators with mocks or stubs. We have to put in test doubles as collaborators, otherwise we are testing more than one helper at the time and if the test fails we cannot tell if the problem is in the SUT (IconLoader) or in the referenced helpers (HeadStyle, ...). Note that collaborators can reference more collaborators, and soon IconLoader class can depend on the entire framework.

My very-simple-testing solution would be require helpers to specify their collaborators in the constructor or via setters, implementing Dependency Injection. We cannot change the standard Zend Framework architecture, though, but it's not a framework's fault. This solution would have required to build a small automatic dependency injection system, which is not in the scope of Zend Framework 1.x (but will be in 2.x as far as I know).

With the current architecture, we can make different choices to simplify testing (remember an helper's constructor must not have parameters, and we must test our components in isolation):
  • Use the real view object and the real view helpers as collaborators. This is integration testing, and failures on the collaborators or view object or what else they refer to will make my main test fail too. Moreover, at every test you should bootstrap all the Zend Framework's Mvc system, so it's not a viable solution.
  • Providing setters for collaborators. The view object cannot call these setters for us, so in the bootstrap we should require the view helper from the already set up view object and call the setters with the mandatory collaborators. In my example, I would have created a My_Helper_IconLoader::setHeadStyle() method. This is the simplest solution for testability, since we have only to call setters in the test for IconLoader view helper and passing in mocks; however, it requires to instantiate all view helpers which need collaborators at every page request, so it's a bit heavy but mandatory if the collaborators are not view helpers but other complex service classes. Starting to mock collaborators is right, though.
  • Mocking the view object/Service Locator with phpunit. This can be done for one view helper, by setting an expectation on a (mocked too) view object __call() method. But when using multiple helpers as collaborator, phpunit cannot distinguish between calls with different parameters and decide which collaborator helper to return. It's an hack which would not work very well.
  • Provide a Fake view object. This is my choice: write once a fake view class, which implements Zend_View_Interface but instead of creating view helpers only returns the ones set at construction time. The definition of a fake object is a class with a running implementation, but different from the production one, often a simplified implementation used for testing.
With my fake view object, the testing phase becomes very simple. In my setUp() method I have:
    $this->_headStyleMock = $this->getMock('Zend_View_Helper_HeadStyle', array('appendStyle'));
    $view = new View();
    $view->setHelper('headStyle', $this->_headStyleMock);
    $this->_helper = new IconLoader();
    $this->_helper->setView($view);
and after this injection, I can set expectations on $this->_headStyleMock and exercise IconLoader in the test methods.
You can find the View fake class at:
http://nakedphp.svn.sourceforge.net/viewvc/nakedphp/trunk/tests/NakedPhp/Stubs/View.php?revision=52&view=markup
along with some tests on it, which could help you grasp its usage:
http://nakedphp.svn.sourceforge.net/viewvc/nakedphp/trunk/tests/NakedPhp/Stubs/ViewTest.php?revision=52&view=markup
Obviously this fake class was Test-Driven Developed.



Feel free to ask any questions. I care about (unit) testability and using extensively frameworks can often make difficult the TDDer life.

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