Login

PHP Service Layers: Handling Entity Collections

In this fourth part of the series, I add to the mapping layer of this sample application a couple of additional classes. These new classes will handle collections of entities (and more specifically, user objects).

Superbly covered in Martin Fowler’s book Patterns of Enterprise Application Architecture, a service layer (http://martinfowler.com/eaaCatalog/serviceLayer.html) is an enterprise-level pattern that can be used for encapsulating application logic behind a single interface. This interface can be used by different clients. As with a few other patterns available, a service is particularly useful in the development of applications that use the domain-driven design paradigm (DDD), where the domain model has its own constraints and rules, and lives completely isolated from the persistence layer (the so-called persistence agnosticism).

Of course, this doesn’t mean that a service must be implemented in every possible use case, just because it looks like a sophisticated approach whose name sounds quite impressive. However, as current web applications become larger, more complex and functional, implementing a service can be a great help. This is especially true when they’re used in conjunction with an MVC stack, where action controllers tend to get "fatty" easily (either due to ignorance or an improper design of the model).

You, as a PHP developer, can take advantage of the benefits provided by a service as well, without having to radically modify the infrastructure of your MVC applications. And to prove it, in previous chapters of this series I started building a sample program, whose main area of concern is to employ a service layer to perform CRUD operations on some user entities.

So far, the program’s functionality is admittedly pretty limited. I’ve only managed to implement its domain model, along with its mapping and data access layers. However, the former is still incomplete. It’s necessary to add an extra dependency to it, which will be responsible for handling collections of entities.

Given that, in this fourth installment of the series I’ll be implementing the aforementioned dependency, which will be easy to understand.

Persisting the model in a MySQL database: a quick review of the application’s persistence layer

Just in case you haven’t read the previous episode of this series, where I implemented the data access layer of the sample application, below I included this layer’s source code.

Here’s the first building block of the layer. It’s a segregated interface, responsible for defining a contract for generic database adapters. Check it out:

Although its contract is somewhat revealing, the above interface is useful for constructing a pluggable structure that permits users to consume different database adapters at runtime. Since in this case, I plan to use a MySQL database as the underlying storage mechanism, the only thing we need to do to get this persistence layer ready to go is define an adapter that works with that specific RDBMS.

/**
* Close automatically the database connection when the instance of the class is destroyed
*/
public function __destruct()
{
$this->disconnect();
}
}

(MyApplication/Database/MysqlAdapterException.php)

<?php

namespace MyApplicationDatabase;

class MysqlAdapterException extends Exception{}

Since the logic of the above "MysqlAdapter" class has already been discussed, we needn’t waste any time explaining how it functions again. However, I’d like to summarize what we’ve achieved so far with reference to the implementation of a functional service.

On the one hand, the domain and data access layers of this sample application are up and running, living happily separated from each other. On the other hand, its mappers are almost functional, since they require an additional collaborator that handles collections of entities to work as expected.

Obviously, it’s time to give the mappers what they need! So, in the following section I’ll be showing you the definition of the collection handling class just mentioned, which will be implemented as a plain array collection.

Now, click on the link below and keep reading.

{mospagebreak title=Building a generic array collection class}

As I noted in the prior segment, it’s necessary to create a pair of classes capable of traversing and accessing collections of entities, so they can be used internally by the "findAll()" and "search()" methods implemented by the previous data mappers.

The following class performs these tasks in a simple fashion. Look at it:

The "AbstractCollection" class is nothing but a simple wrapper for a plain PHP array. This class encapsulates the functionality required for iterating over its elements, as well as for counting and accessing them, thanks to the implementation of the Iterator, Countable and ArrayAccess SPL interfaces.

While this abstract class does a good job of handling collections of generic entities, in this case it’s mandatory to spawn a concrete subclass that allows it to specifically handle user objects. Remember, our final goal is to implement a user service.

Don’t worry, however, because this derivative will be shown in the following segment. So keep reading.

Taking the final step: developing a user collection class

If you think that implementing a concrete class responsible for traversing collections of user entities is difficult, the following code bit should make you change your mind. Check it out:

That was really easy to code and read, right? As you can see, the creation of a child class that works with a specified type of domain object is reduced to overriding the abstract parent’s $_entityClass field and nothing else. Period.

With these two collection handling classes living in sweet harmony, we’ve taken a big step toward the implementation of a functional user service.

Final Thoughts

In this fourth part of the series, I added a couple of additional classes to the mapping layer of this sample application. They’re charged with handling collections of entities (and more specifically, user objects).

With the inclusion of these classes, at this point the application is functional (assuming that the corresponding MySQL database has been previously created). What’s more, it’s really easy to set up a domain model with a few user entities in it, then build a mapper and finally start putting data into, and pulling it out of, the storage area.

But, what does this buy us, if what we’re trying to implement here is a user service, not a user mapper (which is already done)? Well, leave your concerns behind, because in the upcoming tutorial I’ll be defining the service, so that you can finally see how it fits into the current application schema.