One of the biggest advantages of PHP is its pragmatism (which can turn into a curse when used inappropriately), as it allows developers to quickly start building functional web programs without having to tackle a steep learning curve or deal with a complicated API. As an application becomes larger and more complex, however, it is sometimes necessary to sacrifice a little of this pragmatism and construct some additional abstraction layers that permit you to keep the application modular and scalable for further improvements. One typical case where an extra abstraction layer can be useful is in the construction of a repository, where it can help concentrate the query logic in a program that reveals a rich domain composed of a great variety of objects. Being a fundamental piece of Domain-Driven Design (DDD), a repository can be thought of as a mediator that acts between the domain and the mapping layers of a program. This mediator allows you to easily query collections of objects ,and produces the illusion of those collections residing in memory at the same time. As with other topics related to applying the OOP paradigm in PHP, the most effective way to grasp the logic of a repository is by example. In keeping with this idea, in previous installments of this series I started building from scratch a sample web application. This application was responsible for manipulating simple user entities. So far, I've created the domain, mapping and data access layers corresponding to this application, and also defined a couple of additional classes that handle collections of entities through an array-like interface. With all of these layers already up and running, the next logical step is to build a structure that permits you to put them to work together, while maintaining their isolation from each other. You're probably wondering what that structure is, right? Well, the "glue" for the aforementioned layers is a user repository class, and in this article I'm going to partially implement it, so that you can understand its driving logic. Ready to learn how to create such a repository in a few simple steps? Then begin reading! Reviewing the collection classes created previously As I explained in the introduction, a repository must be capable of querying collections of domain objects through a friendly API. To restrict the responsibility of the classes that compose this sample application and make them perform only a few discrete tasks, in this case I decided to create two independent classes responsible for handling collections of objects. The first of these classes is an abstract parent tasked with manipulating generic entities. Its source code looks like this: (CollectionAbstract.php) <?php abstract class CollectionAbstract implements Iterator, Countable, ArrayAccess As you can see from the above code fragment, the previous "CollectionAbstract" class is an implementer of the Countable, Iterator and ArrayAccess PHP built-in interfaces. Its objective is to handle collections of generic entities through the set of methods declared by the interfaces. Its underlying logic is that simple. With the earlier abstract parent neatly encapsulating most of the functionality required for manipulating domain objects by using an array-like approach, building a class that only works with user entities is a breeze. If you're still not convinced of this, then focus your attention on the following "UserCollection" subclass, which does exactly that: (UserCollection.php) <?php class UserCollection extends CollectionAbstract Were you expecting to see a longer code snippet? I don't think so. In either case, the above "UserCollection" class only implements a single method. This method, called "add()," assures that every object added to its internal collection will be effectively a user entity. So far, so good. Provided that you've grasped how the two collection classes do their thing, it's time to start building the user repository mentioned at the beginning. You'll finally see how all of the classes previously defined fit together. To learn more on this topic, click on the link that appears below and read the following segment.
blog comments powered by Disqus |
|
|
|
|
|
|
|