Showing posts with label domain model. Show all posts
Showing posts with label domain model. Show all posts

Tuesday, March 15, 2016

When to write setters

I have set out, almost unconsciously, to use constructor injection by default in the last few years while writing object-oriented applications. With Dependency Injection as a given, constructor injection satisfy most of my requirements for building an object graph and dynamically configuring collaborators.

The spectrum

I see the statefulness of an object not as an absolute but over a spectrum.
At one end of the spectrum we have immutable objects: these objects acquire a configuration in their constructor and are effectively final (to employ a Java-specific term) for the rest of their lifecycles. Their fields are private and there's no way of modifying them outside of the constructor; their collaborators are only scalars or other immutable objects. In Java fields can even be final so that accidental reassignment is regarded as a compile-time error.
The physical state of an object may still change without its external behavior being affected, like in the case of caching. I still consider this kind of white-box-immutable objects as immutable.
Stateful objects instead may have a behavior that changes as a result of its own state (or of its collaborators). You call some Command methods on it, and the response of further calls to Query methods change. Hopefully the Commands encapsulate some domain logic to constrain the state transition to a valid and modelled one.
At the extreme end of the spectrum we find setters: methods which only mutate the value of one or more fields, possibly skipping any validation, domain modeling or consistency check. The setters considered here are public methods, because their limited-scope versions do not provide the same violations.
If you want to write procedural code, setters proliferate (still it's probably easier to just use public fields at that point). There are only a few valid use cases where I have found setters useful in object-oriented programming, and here is the (short) list.

Configuration which has default values

Classes may have a few configuration values that you are able to tune; especially when there is more than a few of these parameters, I find useful to separate hard dependencies in the constructor and setters that are able to override the default parameters when the object has already been constructed. If you forgot to call these methods, the object still has to work correctly.
Alternative solutions for this use case are of course constructors with default parameters, which I definitely prefer if there are not so many options to tune (1 or 2). You can also look into with Value Objects which produce a new instance upon reconfiguration, and model all of the configuration parameters as a single entity; or into a Builder if you want to invest in an additional class and its API.

Adding Observers

Observers (or listeners if you prefer) are collaborators which are notified of internal events happening inside an object that may interest them.
I treat the observers of an object as an append-only list data structure, with an empty list or array as the natural Null Object. The object is initialized without any observer, and a setter like addListener(...) has the more limited capability of adding an observer but not of removing or modifying an existing one.
The nature of the Observer pattern is investing on a common bus that many observers can be attached to, even if they come from different packages and libraries. Therefore I find it natural to support the dynamic wiring of other objects, even if they make the object more mutable can before. The needs of integration become more important than guaranteeing safety of construction in these scenarios.

Reconstitution

When objects are unserialized from a cold storage such as a stream of bytes or a JSON object, encapsulation is very likely going to be violated. Object-relational mappers have been doing this for ages by working directly on annotated private fields, with sometimes powerful results but also lots of dangers from storage and code being out of sync.
In the scenarios where you control the reconstitution of objects, such as rebuilding an object from a MongoDB document, it's often easier to provide an explicit API like a setState() method than to rely on the magic of a library which is going to bypass your public methods. To constrast the possible misuse, you can tag this method as @private (or package protected in Java), or make it very awkward to use outside of the persistence context by requiring a particular data structure to be passed in.

Conclusion

There are very few use cases for setters in real object-oriented programming; default to constructor injection and to immutable objects to avoid overcomplicating your design. Employ setters for non-mandatory, cross-cutting initializations so that your code does not have to bend over backwards to support these use cases while at the same time it can be robust to cowboy modification of internal state.

Wednesday, February 24, 2010

3 simple steps to Ubiquitous Language

A customer should be able to view its past orders, along with their dates and chosen products. This is necessary so that clients can view a single piece and request an arbitrary amount of it again.
This piece of documentation seems to have been written by a poor analyst. It is also the first break in the chain between the user needs and the programmer understanding of the business domain.
A common practice in agile development is incorporating the final user in the process, even to the point of substituting the analyst with a programmer. In fact, in Italy one of the few things that works well is the small size of software firms, which eliminates communication overhead. One time we were able to get a vacation packages selling system up and running in a day, tailoring it in real time to the adjustments provided by the customer.
However, in every serious project a written set of requirements is necessary, to serve as an analysis of the domain and as future documentation. But formal language is not a sole property of php code: Italian, English and other languages can be used in such a way to define without ambiguity the concepts and the functionalities of a domain model. Communication is the major issue in software design and this issue should be addressed accordingly: by defining an higher-level language over the natural tongue.
Let's walk through some steps to transform the sample initial analysis in an instance of Ubiquitous Language, that captures information from the domain.
We will make additional hypotheses on the requirements and the model because we do not have a user of the application available here we can ask questions to. This process should be conducted in the original requirements gathering and initial modelling phase.

Step 1
Synonyms are the most powerful enemy of an Ubiquitous Language: different domain concepts should be named differently and coincident concepts should be named equally. This practice promotes consistency and predictability in documentation and then in the produced code.
The names of concepts are usually written capitalized, to highlight their special role in the prose. They often become class names, so the capitalization is a suited trait. Anyway they will find their place in the domain layer or be eliminated while refactoring.
Once grasped, the practice of using Ubiquitous names will become a second skin, and you'll find yourself making questions such as "We are talking about this data as associated to a particular Customer?" and "So a Customer can make many Orders and an Order should have a unique Customer?" all the time.
A Customer should be able to view its past Orders, with their dates and chosen Products. This is necessary so that Customers can view a single Product and request an arbitrary amount of it again.

Step 2
Look at the available operations and see how they can be better described by involving the Ubiquitous Language.
A Customer should be able to find its past Orders, with their dates and chosen Products. This is necessary so that Customers can view a single Product and create a new Order associated to it.

Step 3
Maintain the Ubiquitous language in sync with the refactoring of the domain concepts, and let it evolve with the code.
Contuinuing with the example, let's say the customer asks for a refinement: only some products are available for shipping, while others are difficult to send and they should be "retired" at a particular warehouse. Here's another piece of description that involves the Ubiquitous Language and describes these additions.
"A Product has a Delivery relationship, which may be a Shipping or a HandOver. A Delivery is always a property of the single Product and it exhibits traits such as a description and its availability in time."
I hope this panoramic of the Ubiquitous Language concept will be helpful in improving your human language usage in documentation and communication with users and other developers; your goal should be to convey concentrated, distilled knowledge.
If you have any suggestion to expand on this topic, feel free to add a comment.

Friday, February 19, 2010

The Number one rule of design

The post on php's foreach construct raised a discussion about the design of the language and of userland code, so I'm recollecting my thoughts here. However, note that I was not discussing the utility of the construct, only the use of array functions when dealing with homogeneous transformation of an array, such as an array with exactly the same type or number of elements.

I would like to introduce a general principle I follow while designing an [object-oriented] system.
A design is good if it makes reacting to change easy.
Decoupling between different classes and packages can be measured by thinking about hypothetical changes to the requirements and how they can be accomodated. This is a double advantage: not only you will be more ready to embrace change, but you will be also writing testable code; unit testing is essentially a practice that change all the environment around a SUT by using stubs and mocks, to find out if the software unit complies to its contract.
Change will not always happen in the ways you have forethought, but high cohesion in software modules will help in dealing with it.
Anyway, I am not the person that invented this design rule (so you shouldn't call me a moron and go on with your practices.) It is contained in a famous paper titled On the Criteria To Be Used in Decomposing Systems into Modules, but we should call it the Number one rule of design:
We have tried to demonstrate by these examples that it is almost always incorrect to begin the decomposition of a system into modules on the basis of a flowchart. We propose instead that one begins with a list of difficult design decisions or design decisions which are likely to change. Each module is then designed to hide such a decision from the others.
This is really one of the most important rules in the information technology world. That's why you can plug in nearly everything in your computer in a standard interface, why you can drive any car and why a structure like Internet is possible. This is information hiding.

The discussion that started in the comments of the previous post is about how to pass an high number of parameters (and by high I mean more than 3) from a bunch of Client classes to a function or a method of a Server class. We will now apply the #1 rule of design to this problem.
The first solution is obvious: every parameter modelled as a formal parameter of the method. Though, a long signature lacks clarity, renders parameters order important and creates issues with default values.
A suggestion proposed in the comments is extending php syntax to automatically pass a map:
function foo($arg1, 'arg2' => 0, 'arg3' => false) {}
foo('arg1' => 42, 'arg2' => 10);
foo('arg1' => 42, 'arg2' => 10, 'arg3' => true);
which is syntactic sugar for:
function foo(array $args) {
    $args['arg2'] = isset($args['arg2'] ? $args['arg2'] : 0;
    ...
}
foo(array('arg1' => 42, 'arg2' => 10, 'arg3' => true));
and would make simpler passing maps as an argument.
My solution would be refactoring the method a bit and passing an Argument object as a parameter. An object will be particularly useful when the number of parameters is not fixed and there are many defaults.
Moreover, a separate object decouples default values handling by code execution. I think that passing an high number of parameters is often a smell since it's likely that a subset of these parameters will always be passed together, or one of them is repeatedly passed to different methods.
Let's consider passing normal arguments, passing a map (with or without sweet syntax, since it is functionally equivalent) versus using an Argument object.

Hypothetical change: adding a parameter.
Formal parameters: you have to modify the method signature and review the Client classes or add a default.
Map: you add a default for the parameter, if applicable.
Argument object: you can add the parameter to the Argument object if it fits; in other cases adding to the signature is a better choice.
Hypothetical change: deleting a parameter.
Formal parameters: you have to fix all the method calls.
Map: the method signature does not change.
Argument object: the method signature does not change.
Hypothetical change: adding another method with the same signature.
Formal parameters: duplicate and maintain the two signatures.
Map: duplicate the signature and maintain both the old and the new one, with the same default values.
Argument object: duplicate the one-parameter, short signature.
Hypothetical change: the default value for some parameters now has to be picked up from a configuration or a database.
Formal parameters: you have to add a collaborator in the Server class, and an argument to its constructor or a setter to inject it.
Map: you can tweak the definition but the signature remains the same. The collaborator problem is still present.
Argument object: create it with a factory that has a database-backed repository or a configuration parser as collaborator.
Hypothetycal change: a method parameter has to be validated, lazy calculated, and so on.
Formal parameters: no chance other than computing the value in the Clients. Maybe currying the method would work but it is a change of signature anyway.
Map: you have to compute the value internally, by adding collaborators and coupling, or externally, changing the Clients.
Argument object: the object or the factory that creates it effectively hides the parameter preprocessing or derivation, so no problem. Sometimes the Argument object itself can perform the calculation alone, or you can swap different subclasses of it. Endless possibilities.

Note that the higher the number of parameters, the more they are likely to change in computation, number and default value. That's why a method with 1 or 2 parameters is usually not an issue. An Argument object should comprehend parameters that change together. This object responsibility is decouple as much as possible the Server class from a [large] set of parameters.
Furthermore, an Argument object handles default values in relation to a default literal value with the power of a getter over a public property. You can hook pretty much everything in the creation and in the methods of an Argument object, protecting Clients and Servers from having to import the default argument from foreign packages, libraries and applications.
Finally, an Argument object captures a domain concept with a name, a protocol and a behavior, while a map is only a plain data structure. You can tell what a map contains, but you can't tell what a map does.
The code sample deals with calculation of a final price for an object, with three example of design for a Shop class.
<?php
class ShopWithFormalParameters
{
    /**
     * We use float for simplicity but a decimal structure would be
     * the correct choice.
     * @param float $regularPrice    price of the item
     * @param float $itemDiscount    discount on this item (percentual)
     * @param float $globalDiscount  discount of the shop during
     *                               sales period (percentual)
     * @param float $bonus           value of bonus coupons
     *                               used by the customer
     * @return float
     */
    public function getPrice($regularPrice,
                             $itemDiscount = 0,
                             $globalDiscount = 0,
                             $bonus = 0)
    {
        return $regularPrice
             * (1 - $itemDiscount / 100)
             * (1 - $globalDiscount / 100)
             - $bonus;
    }
}

$formalShop = new ShopWithFormalParameters();
printf("Price 1st item: %.2f\n", $formalShop->getPrice(200.00, 10, 20));
printf("Price 2nd item: %.2f\n", $formalShop->getPrice(200.00, 0, 20, 5.00));

class ShopWithMap
{
    /**
     * Syntax does not allow to pass a map easily, but
     * this signature is equivalent.
     * @param array $arguments  @see ShopWithFormalParameters::getPrice()
     *                          for keys
     * @return float
     */
    public function getPrice(array $args)
    {
        // similarly, the defaults would fit in the signature
        $args['itemDiscount'] = isset($args['itemDiscount']) ?
                                $args['itemDiscount'] : 0;
        $args['globalDiscount'] = isset($args['globalDiscount']) ?
                                  $args['globalDiscount'] : 0;
        $args['bonus'] = isset($args['bonus']) ? $args['bonus'] : 0;

        return $args['regularPrice']
             * (1 - $args['itemDiscount'] / 100)
             * (1 - $args['globalDiscount'] / 100)
             - $args['bonus'];
    }
}

$mapShop = new ShopWithMap();
printf("Price 1st item: %.2f\n", $mapShop->getPrice(array(
    'regularPrice' => 200.00,
    'itemDiscount' => 10,
    'globalDiscount' => 20
)));
// note that defaults had not to be specified if they
// precede actual parameters in the "signature"
printf("Price 2nd item: %.2f\n", $mapShop->getPrice(array(
    'regularPrice' => 200.00,
    'globalDiscount' => 20,
    'bonus' => 5.00
)));

// my take: refactoring towards a loosely coupled solution
class Item
{
    private $_regularPrice;
    private $_discount;

    /**
     * A couple of arguments always change together,
     * thus it makes sense to put them in the same argument object.
     * The item discount is totally encapsulated here,
     * so the new domain concept has been fairly useful
     * as now the ObjectOrientedShop does not even know a
     * item-specific discount exist.
     */
    public function __construct($regularPrice, $discount = 0)
    {
        $this->_regularPrice = $regularPrice;
        $this->_discount = $discount;
    }

    /**
     * @return float
     */
    public function getPrice()
    {
        return $this->_regularPrice * (1 - $this->_discount / 100);
    }
}

class ObjectOrientedShop
{
    private $_globalDiscount;

    /**
     * One argument changes rarely, or never.
     * So a setter or a constructor option can take care of it.
     */
    public function __construct($globalDiscount = 0)
    {
        $this->_globalDiscount = $globalDiscount;
    }

    /**
     * Only two arguments, which make introducing a map useless.
     * We are protected from changes that affect the Item:
     * adding an argument which is cohesive with Item should be
     * kept with the Item class. Global options should be kept in the
     * constructor or in a field reference anyway.
     * Per-call parameters such as bonus, if necessary, would be
     * wrapped with $bonus in a Sale object which can come from any
     * external service.
     * @param Item      we don't need docblocks to tell what Item is
     * @param float     bonus coupons value
     * @return float
     */
    public function getPrice(Item $item, $bonus = 0)
    {
        return $item->getPrice()
             * (1 - $this->_globalDiscount / 100) - $bonus;
    }
}

$ooShop = new ObjectOrientedShop(20);
printf("Price 1st item: %.2f\n", $ooShop->getPrice(new Item(200.00, 10)));
printf("Price 2nd item: %.2f\n", $ooShop->getPrice(new Item(200.00), 5.00));

Wednesday, February 03, 2010

Where is business logic?

Have you ever heard of Multitier architecture? If not, you have probably encountered it without knowing its name while working on web applications.
In a multitier architecture, an application is divided in different horizontal layers, each addressing a different concern. Every layer builds on the one that lies directly under it to perform its work, thus decoupling for example html presentation (upper layer) from sql queries (lower layer).
The number of layers is flexible and there is a high number of variants for a multitier architecture, but the simplest model many web applications fall in is composed of three layers:
  • user interface: generates html, handles user input and displays errors.
  • Domain Model: objects and classes that represent concepts, such as Post, Thread, Forum, User, Message and so on.
  • Infrastructure: usually data access code to a database and, by extension, the Sql schema itself where the relational model is used. External services also qualify as infrastructure.
Thus there are three major approaches to development, which differ in the layer of the application that contains the greater quantity of business logic. Which User can close a particular Thread and in what order the Messages for a particular User are listed? In which Forum a User can add a Post?
The answers to these questions ideally reside in one of the fundamental layers as specifications require (though sometimes they are scattered trough the layers, which is a very effective way to complicate a design.)

Smart Ui
As the name says, this style keeps the logic in the user interface. A Smart Ui example is a folder full of php scripts that move data back and forth from a MySql database.
During maintenance, usually the replication of rules and code in different scripts increase, rendering difficult to change and expand the application; this style is appropriate only for small projects which only shuffle data from tables to html pages.

Smart database
A style primarily taught in database classes, which result in a very accurate schema, full of constraints, triggers and stored procedures to maintain data integrity.
Note that if you want to implement this approach, you probably need an expensive database like Oracle because open source databases do not support all the logic you need. Moreover, Sql is not a programming language, you can stretch Ddl with proprietary extensions and set up many rules but you will be replicating them in the front-end (if there is one at least) for error handling and localization.

Rich Domain Model
The most powerful approach is implementing logic in the domain model layer, which is the type of model that should be able to best represent the real world.
It follows that in such an approach the Ui delegates nearly everything to the domain layer, or it is even automatically generated (Naked Objects). Technology is available for the database to be generated automatically once a mapping from objects to tables is defined (Orms like Hibernate and Doctrine 2). The dependencies are inverted as all other layers mirror the domain model.
The advantages of a rich domain model are multiple:
  • testing is simple because infrastructure and Ui do not get in the way; no need to run databases to test business logic or to fill forms with a bot or Selenium.
  • no duplication of logic is permitted, because different views of the user interface refer to the same methods in the domain model.
  • the model of the application is the model presented to the user; there is no translation between concepts and no need for him to learn a data model along with a presentational one. Often a Presentation Model is needed because the underlying Domain Model is anemic.
Essentially with the tools available today for managing generic layers you can achieve everything by manipulating objects directly in memory and storing the result in the database by pushing a big Save button.

Wednesday, December 09, 2009

What everybody ought to know about storing objects in a database

Probably during your career you have heard the term impedance mismatch, which is commonly referred to the problems that arise in converting data between different models (or between different cables if you are into electrical engineering).
Usually the complete expression is object-relational impedance mismatch, which indicates the difficulties of the translation process between two versions of the same domain model: the former resides in memory and it consists in an object graph, while the latter is used for storage and it is a relational model stored in a database. The conversion between parts of both models happens many times while an application runs, and in php's case at least once for every http request.

Object-relational mappers like Hibernate and Doctrine are infrastructure applications which deal with the mismatch, doing their best to implement a transparent mechanism and providing the abstracted illusion of a in-memory model, like the Repository pattern. These particular Orms are the best of breed because they do not force your object graph to depend on infrastructure classes like base Active Records.
The connection between the two models is defined by the developer, by providing metadata about its classes properties: for instance you can annotate a private field specifying the column type you want to use to store its value. But what are the translation rules the developers provide configuration for? Here is a basic set of the tasks an Orm performs for you.
  • Entity classes are translated to single tables as a general rule, with a one-to-one mapping. The class private or public fields which are configured for storage define the columns of a particular table.
  • Objects which you pass to the Orm for being stored become rows of the correspondent table. A User class becomes a User table containing one row for every registered user of your website.
  • A primary key is defined by choosing between the existing fields or inserted ex-novo. Often as a requirement the developer should explicitly define a field.
  • Repeated single (or multiple) class fields become new tables, and the problem of representing them is shifted to representing relationships; in the domain model this kind of objects are Value Objects, which is semantically different from Entities, but databases only care about homogeneous data and such objects receive no special treatment.
  • One-to-one and many-to-one relationships can be represented with a foreign key on the source entity that resembles the original pointer to a memory location.
  • One-to-many relationships are a bit trickier because they require a foreign key on what is called the owning side, in this case the target entity. What can seem strange at first glance is that even if in the domain the relationship is unidirectional (pointer to a collection), elements of a collection need to have a reference to the owner to unequivocally identify it. The mutual registration pattern can be used to build a correct Api starting from this constraint; I will write about it in one of the next posts.
  • Many-to-many relationships are managed by creating an association table that references with foreign keys the participating entities. Every row constitutes a link between different objects; sometimes it may be the case to use such a table also for one-to-many associations, to avoid having a back reference field on collection elements.
  • Inheritance is by far the most complex semantic to maintain as it is not supported at all by relational databases: Single/Class/Concrete table inheritance are three famous patterns which organize hierarchical objects in tables, but I prefer to avoid inheritance altogether if not strictly necessary.
And this list is one of the reasons why in your college courses they told you that a model should be as small and simple as possible: a simple model can undergo much more simple transformations for storage and transmission than a complex one.
Note that some contaminations leak from the database side to the object graph, such as the bidirectionality of one-to-many relationships, present even when it is not required by the domain model.
Orms take care for you of this translation process and can even generate the tables from the classes source code, but they only perform automatically the tedious part of object-relational mapping. You should know very well how the mapping works if you plan to use such powerful tools without reducing your database to a list of key/value pair.

The image at the top is an Entity-Relationship model used to design database schemas. I find it not useful anymore as I now prefer to think in classes terms, with Uml diagrams.

Saturday, November 28, 2009

Saturday question: mixing Repository and Active Record

Saturday is becoming the 'questions day of week', since it is not the first time that after a week of work some readers email me to carry on the discussion on design and testability, two topics that are stressed in my blog posts. :)
This week, Fedyashev wrote to me about mixing architectural patterns in a single application:
I really like these Active record and Repository patterns.
The drawback of Repository pattern is its cost(takes more time then
Active record). Benefit is higher abstraction which really helps on
complicated business logic.
The drawback of Active record is that lower testability(db interaction
is required) and harder in handling complicated domain logic.
Is it acceptable to take the best of these two patterns to be used in
the same application?
I was thinking about using Active record for simple CRUDs and Repository
for complicated domain objects.
The idea behind this intention is to keep cost of code lower but still
have a good code.
What would you recommend?
There are cases in which Active Record would be an acceptable pattern. Since the drawback of Active Record is little testability, the primary scenario for its application is when there is nothing to test. Some applications are data intensive and require only to move information back and forth from the database.
CRUD screens, as you suggest, often have little logic and can take advantage of active records. But we should evaluate case by case, since it is very easy for logic to leak into Active Record instances, and logic should be thoroughly tested.
For example, logic is present in managing validation of entities upon insertion and editing: a classical situation is searching for already existent nicks upon user registration. A Repository is capable of performing validation using external resources as they can be injected at construction or passed as a method parameter, while an Active Record probably not (and it will be more complex to test this validation).

Another problem I see in mixing up these patterns is the different libraries requirements. Typically, we want repositories to aggregate an instance of a lower-layer framework that encapsulates Sql queries or whatever storage we are using (Hibernate or Doctrine 2), while Active Records are subclasses of other frameworks abstract base classes (Zend_Db or Doctrine 1).
The paradoxical result is that implementing both patterns leads to use two different version of Doctrine at the same time, which I do not recommend for maintenance reasons and code clarity.
A solution would be keep the implementations in two separate BoundedContext, which are different domain models that can communicate, for instance using the same underlying relational database. Though, BoundedContext is a DDD term and suppose that you work with persistent-ignorant models in both contexts.

However, the real choice is not between Active Record and Repository but between Active Record and Data Mapper (persistence-ignorant domain model). It seems for instance that Doctrine 2 provides a default repository class you can tweak later, although it has default methods only for retrieving entities and not to insert them (I think the insertion can be managed with events). It's not really difficult to change your approach from:
$user = new User();
$user->nick = 'John Doe';
$user->save();
to:
$user = new User();
$user->nick = 'John Doe';
$em->save($user);
when what you gain is freedom from activating a mysql daemon to test the User class, without using Repositories. Repositories may come into play later, when and where you want a finer control on the bridge with the database.

Tuesday, November 17, 2009

Doctrine 2 and Zend Framework first date

This morning I have tried for the first time to use Doctrine 2 in a Zend Framework application. I used the latest release, 2.0.0 alpha3, for this experiment.
The chosen application is my recently born project NakedPhp, a port of the Naked Objects Java framework which generates the user interface and let the end user manipulate domain objects directly.
During this first run, I have not set up an application resource yet and I have just hardcoded a few configurations to bootstrap correctly Doctrine. I will publish a resource class (conforming to the Zend_Application_Resource_Resource interface) soon when I have it ready.

Doctrine\ORM\EntityManager is the Facade class which act as a portal towards the functionality of Doctrine 2, and it is the homologue of Hibernate EntityManager. Our code should interact mainly with this class.
Though, I have isolated the EntityManager behind an interface since I do not want infrastructure code to slip in NakedPhp for now. The code will obviously depend on Doctrine but it is good practice to have an interface I can mock out easily, as I don't need all the methods of the EntityManager and this way I just hide everything is not mandatory instead of introducing coupling to it.

Doctrine 2 is released in three packages: Common, Database Abstraction Layer and ORM. Instead of downloading three different packages I just grab them from the subversion repository:
svn export http://svn.doctrine-project.org/tags/2.0.0-ALPHA3/lib/
and move the Doctrine/ and vendor/ folders in my library/ directory along with Zend/. The vendor folder contains a small annotation parser.
It can be useful also to export other resources:
svn export http://svn.doctrine-project.org/tags/2.0.0-ALPHA3/bin/
svn export http://svn.doctrine-project.org/tags/2.0.0-ALPHA3/sandbox/
The bin/ folder contains the doctrine.php and doctrine command-line scripts (same thing), while the sandbox provides a working example of Doctrine 2.

Doctrine 2 prescribes that model classes (entities) and proxies should be autoloaded, so after moving doctrine.php in application/ I deleted the reference to Doctrine autoloader and added:
require_once __DIR__ . '/../application/bootstrap.php';
which is my bootstrap file, where:
  • the library/ folder is added to the include_path
  • the autoloader is set up to load Zend/ classes
  • a Zend_Loader_Autoloader_Resource sets up autoloading for my model classes.
  • my autoloader is set up to take care of \Doctrine and \NakedPhp namespaces.
In the future, I will add proxies autoloading setup to this file. Since you probably don't have your own autoloader for namespaced classes, you can simply use IsolatedClassLoader from Doctrine\Common.

It's time to code a cli-config.php file to use with doctrine.php; this file should define two variables (it is well-documented in the sandbox example). My final result is:
$classLoader = new \Doctrine\Common\IsolatedClassLoader('Proxies');
$classLoader->setBasePath(__DIR__ . '/../application/');
$classLoader->register();

$config = new \Doctrine\ORM\Configuration();
$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ArrayCache);
$config->setProxyDir(__DIR__ . '/Proxies');
$config->setProxyNamespace('Proxies');

$connectionOptions = array(
    'driver' => 'pdo_sqlite',
    'path' => '/var/www/nakedphp/sqlite/database.sqlite'
);

// These are required named variables (names can't change!)
$em = \Doctrine\ORM\EntityManager::create($connectionOptions, $config);

$globalArguments = array(
    'class-dir' => __DIR__ . '/../application/models'
);
Which is practically the cli-config.php file grabbed from the sandbox, but slightly edited:
  • there were two instances of Doctrine\Common\IsolatedClassLoader, one for the entities and one for the proxies. I deleted the first one since entities autoloading is already taken care for in the bootstrap.
  • I haven't used proxies for now, but the configuration is mandatory. The default namespace and folder are enough.
  • I changed the path to the sqlite database. Sqlite was the fastest choice to get the application up and running, but remember that both the sqlite database file and its directory must be writable by apache and php.
  • I changed also the argument class-dir to specify my entities folder.
Before starting to use the Doctrine 2 command-line interface, you will have to define annotations on your model classes. For instance, @Column and @OneToOne annotations. Since I have developed without even caring about the database until now, I had to add also an $_id private property. :)
I also submitted a patch to improve the errors generated by the schema tool in case of incorrect field names referenced on relations, which is what happened to me today.

Now, it's time to generate your schema:
php bin/doctrine schema-tool --re-create --config=bin/cli-config.php
If cli-config.php is in the directory where you issue this command, you can leave out the --config option.
Maybe after playing a bit with Doctrine 2, you will want to see what was inserted in the database:
php bin/doctrine run-sql --sql="SELECT * FROM Example_Model_Place" --config=bin/cli-config.php 
To obtain an EntityManager reference in a controller, you can set up a dumb resource that includes cli-config.php and return $em. I used a factory which was already available and add a method for retrieving the instance.

So I now have an hacked working instance of Doctrine 2 in my project. The next step will be writing an application resource to allow configuration to be specified following the standard, in application.ini. I will publish this resource in the next days.

The image at the top is the NakedPhp example application screen that says saving was successful. I implemented the storage of my persistence-agnostic in-memory object graph in less than an hour.

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!

Thursday, October 29, 2009

The Repository pattern

A Repository is a Domain-Driven Design concept but it is also a standalone pattern. Repositories are an important part of the domain layer and deal with the encapsulation of objects persistence and reconstitution.

A common infrastructure problem of an object-oriented application is how to deal with persistence and retrieval of objects. The most common way to obtain references to entities (for example, instances of the User, Group and Post class of a domain) is through navigation from another entity. However, there must be a root object which we call methods on to obtain the entities to work with. Manual access to the database tables violates every law of good design.
A Repository implementation provides the illusion of having an in-memory collection available, where all the objects of a certain class are kept. Actually, the Repository implementation has dependencies on a database or filesystem where thousands of entities are saved as it would be impractical to maintain all the data in the main memory of the machine which runs the application.
These dependencies are commonly wired and injected during the construction process by a factory or a dependency injection framework, and domain classes are only aware of the interface of the Repository. This interface logically resides in the domain layer and has no external dependencies.

Let's show an example. Suppose your User class needs a choiceGroups() that lists the groups which an instance of User can subscribe to. There are business rules which prescribe to build a criteria with internal data of the User class, such as the role field, which can assume the values 'guest', 'normal' or 'admin'.
This method should reside on the User class. However, to preserve a decoupled and testable design, we cannot access the database directly to retrieve the Group objects we need from the User class, otherwise we would have a dependency, maybe injected, from the User class which is part of the domain layer to a infrastructure class. This is want we want to avoid as we want to run thousands of fast unit tests on our domain classes without having to start a database daemon.
So the first step is to encapsulate the access to the database. This job is already done in part from the DataMapper implementation: [N]Hibernate, Doctrine2, Zend_Entity. But using a DataMapper in the User class let its code do million of different things and call every method on the DataMapper facade: we want to segregate only the necessary operations in the contract between the User class and the bridge with the infrastructure, as methods of a Repository interface. A small interface is simply to mock out in unit tests, while a DataMapper implementation usually can only be substituted by an instance of itself which uses a lighter database management system, such as sqlite.
So we prepare a GroupRepository interface:
<?php
interface GroupRepository
{
    public function find($id);

    /**
     * @param $values   pairs of field names and values
     * @return array (unfortunately we have not Collection in php)
     */
    public function findByCriteria($values);
}
Note that a Repository interface is pure domain and we can't rely on a library or framework for it. It is in the same domain layer of our User and Group classes.
The User class now has dependencies only towards the domain layer, and it is rich in functionality and not anemic as we do not have to break the encapsulation of the role field and the method is cohesive with the class:
class User
{
    private $_role;

    // ... other methods

    public function choicesGroups(GroupRepository $repo)
    {
        return $repo->findByCriteria(array('roleAllowed', $this->_role));
    }
}
Now we should write an actual implementation of GroupRepository, which will bridge the domain with the production database.
class GroupRepositoryDb implements GroupRepository
{
    /**
     * It can also be an instance of Doctrine\EntityManager
     */
    public function __construct(Zend_Entity_Manager_Interface $mapper)
    {
        // saving collaborators in private fields...
    }

    // methods implementations...
}
In testing, we pass to the choicesGroups() method a mock or a fake implementation which is really an in-memory collection, and which can have also utility methods for setting up fixtures. Unit testing involves a few objects and keeping them all in memory is the simplest solution. Moreover, we have inverted the dependency as now both GroupRepositoryDb and User depend on an abstraction instead of on an implementation.

Another advantage of the Repository and its segregated interface is the reuse of queries. The User class has no knowledge of any SQL/DQL/HQL/JPQL language, which is highly dependent on the internal structure of the Group class and its relations. What is established in the contract (the GroupRepository interface) are only logic operations which take domain data as parameters.
For instance, if Group changes to incorporate a one-to-many relation to the Image class, the loading code is not scattered troughout the classes which refer to Group, like User, but is centralized in the Repository. If you do not incorporate a generic DataMapper, the Repository becomes a Data Access Object; the benefit of isolating a Repository implementation via a DataMapper is you can unit test it against a lightweight database. What you are testing are queries and results, the only responsibility of a Repository.
Note that in this approach the only tests that need a database are the ones which instantiate a real Repository and are focused on it, and not your entire suite. That's why the DDD approach is best suited for complex applications which require tons of automatic testing. Fake repositories should be used in other unit tests to prevent them from becoming integration tests.

Also the old php applications which once upon a time only created and modified a list of entities are growing in size and complexity, incorporating validation and business rules. Generic DataMappers a la Hibernate are becoming a reality also in the php world, and they can help the average developer to avoid writing boring data access classes.
Though, their power should be correctly decoupled from your domain classes if your core domain is complex and you want to isolate it. Repositories are a way to accomplish this decoupling.

Thursday, August 27, 2009

Applying Domain-Driven Design and Patterns review

Applying Domain-Driven Design and Patterns: With Examples in C# and .NET is a book from Jimmy Nilsson which shows you how to begin applying such things as TDD, object relational mapping, and DDD to .NET projects...techniques that many developers think are the key to future software development. Although it is based on .NET technology and features C# examples, it is a valuable resource for DDD adopting in every object-oriented language and one of the few practical books on Domain-Driven Design, along with the original one from Eric Evans.

The main feature of this book is a full description of the process followed in development: previous solutions are presented along with improvements to the object-oriented design and the reasons that have lead to refactoring. For instance, persistence ignorance is not assumed as the basis of a decoupled model but it is the final point of a research path.
This is a panoramic of the topics which the author deals with in the 600+ pages book.

Part 1: Background
The first part of the book is a introduction on low-level techniques like TDD, refactoring, and application of patterns (for example, State pattern). Problem and tradeoffs are discusses regarding databases and their impedance mismatch with an object-oriented model, together with the importance of layering and modelling. Part 1 is important because understanding of the rest of the book strongly depends on these concepts: a responsible programmer should test first and refactor where he expects changes.

Part 2: Applying DDD
In part 2 a full application requirements are discussed along with part of their implementation. Since the title is applying DDD the focus is on building the right model for the example, leaving out infrastructure and security concerns for a moment.
The requirements list comprehends orders and customers management, concurrency conflict detection, validation rules on amount of moneys in orders and customers, atomic saving and validation with an external service. This list is well crafted as it contains the main problems encountered when using a rich Domain Model, so the order management application is a good example to see DDD applied at its best.

Part 3: Applying PoEaa
While part 2 is centered on a persistent-ignorant model, part 3 discuss the infrastructure needed for the example application to work (object/relational mapping in primis) and tradeoffs from the incorporation of database concerns in the pure domain model. PoEaa is Patterns of Enterprise Application Architecture, a famous book from Martin Fowler which presents the principal patterns used in orms and big applications.
PoEaa is full of code examples so it is not important for the author to attach naked code but the discussion on how to persist a rich model is still crucial.

Part 4: What's next?
This part introduces other techniques and topics which are not strictly related to modelling and infrastructure: Service-oriented architecture, Inversion of Control and Dependency Injection, Aspect-oriented programming, Model-View-Controller pattern, user interface development. These are all interesting topics which a smattering of can only help the average developer to enlighten himself and face different ideas and paradigms: TDD for instance needs Dependency Injection to work.

Part 5: Appendices
Last but not least, other styles are proposed in contrast to DDD, such as database-driven development and rich service layers. The same application requirements from part 3 are rediscussed using these new point of views, and the reader gets a comparison between various implementation of the Domain Model pattern.
The appendices contain also a list of the patterns referenced in the book, but the should consider other sources for more information.

Summing up, Applying DDD is a good panoramic on practicing Domain-Driven Design, but also on implementing patterns and using modern tools and approaches like Dependency Injection and Test-Driven Development. It can also be read along or after the original DDD book to improve the understanding of Factories, Repositories and other domain patterns.

Thursday, August 20, 2009

10 orm patterns: components of a object-relational mapper

An Orm is a complex and generic tool which stores objects such as Entities and Value Objects (Customer, Groups, Money classes) in a relational database like MySQL or Sql Server, using metadata provided along with the Domain Model. The internals of an Orm usually follow some useful patterns that a developer should know to understand what is going on under the hood and here's a list of the most famous ones.
  • Table Data Gateway: an object that represent a table of the database, on a one-to-one basis. It is usually built as a generic class which can be subclasses or instantiated for any physical table.
  • Active Record: the most common approach, transforms a row of a table in an object. It strictly couples the object structures to the database tables by making the domain object subclassing an abstract implementation.
  • Data Mapper: a real Orm is an instance of a Data Mapper, a tool that stores objects which are ignorant of the environment where they will be kept, thus decoupling them from persistence concerns.
  • Unit Of Work: maintains a list of dirty objects and writes out the changeset. The purpose of this object is to keep track modified data on the entity object that it knows and its flushing capabilitities substitute the save() method of the Active Record implementations. It is a more resilient and sophisticated pattern than Active Record since it strives for persistence ignorance.
  • Repository: the persistent-ignorant equivalent of the Table Data Gateway. While a single repository implementation is aware of the database backend, a generic interface is placed between service classes and object retrieval mechanisms to aid decoupling.
  • Identity Map: a map of objects organized by class and primary key. It is a first level cache that contains every initialized object, so it can be used to prepare a changeset of database queries on flushing.
  • Lazy Loading: substituting a domain object or collection with a subclass that loads data on the fly when methods are requested, before forwarding the original call.
  • Query Object: a class that represents a query for retrieving objects, encapsulating Sql or other high level languages.
  • Criteria Object: a class that represents a set of criteria for selection of objects of a particular model.
  • Single Table Inheritance / Class Table Inheritance / Concrete Table Inheritance: patterns implemented to represent class inheritance in relational tables. Favoring composition over inheritance is a must because neither of these patterns does a perfect job in persisting data efficiently and in a clean way.
I hope you'll check out more information on the patterns you are using, maybe without even know that they exist. Feel free to add other useful patterns and approaches to the list in the comments.

Wednesday, July 15, 2009

A look at technical question on Naked Objects

Naked Objects pattern strips down the layering of your application to a single one: the Domain Model, and poses a lot of questions about how to implement the functionality that were present in the other layers.
As explained before, the Naked Objects pattern implies a framework that takes care of providing the other layers of an application in a completely generic manner, leaving you with only the responsibility to write a complete Domain Model. This raises immediate issues which are present in the original Pawson thesis and which I explain here with a language close to the developer who wants to use a Naked Objects approach, but is scared that it is only a buzzword for braindead, scaffolded user interfaces.
Here are the questions; the text in bold is quoted from the thesis, while the answers are mine.

How can the user create a new object instance, or perform other operations that cannot naturally be associated with a single object instance?
In a rich Domain Model there are Factories for the creation of objects when it is a complex procedure; otherwise, if it has a no-arguments constructor, it can be created directly by the framework. Thus, the new operator is wrapped in a method of another object, the Factory itself.
We have also Services, that connect business objects providing the operation which will cause coupling if placed on them. For example, a method called searchBooks(Author a) will be placed in a SearchingService class that will depend on Book and Author, but will not couple them to each other. In this case SearchingService could be a Repository.
However, the Naked Objects framework for Java take care of this and provides automatic injection of services in the business objects. Injecting in a newable object a service one sounds strange, since a common rule is that the entity should have a reference to a service only the stack (aka passed as a parameter), to allow the programmer to call new for it wherever he wants in the application.
Leave the business object free of the burden of a service is also possible, because by default every method of a service that has a particular domain object as a parameter will be listed in the user interface like it was on the object itself. In our example, the Author list of operations will show also list searchBooks(), passing automatically the object selected as actual parameter.

How does the concept of a generic presentation layer permit alternative visual representations of an object?
A unique visual representation is sometimes the best approach as it makes the application coherent. If this is really needed, the domain object can implements some standard interfaces of the framework that the generic user interface will recognize and use at its best.

How is the concept of a generic presentation layer compatible with the requirement to support multiple forms of user platform?
As long as the framework does the reflection work and provides metadata on the domain model, it is possible to implement many different generic presentation layers. The NO Java framework provides already a DragNDrop interface for local use and a web one, while there are many independent projects that features other interfaces to plug in.
If you really want, you can write manually a user interface: a side effect of working with the Naked Objects pattern is that the model is forced to be behaviorally complete and it simplifies the work of coding a user interface. In fact, usually a program does it for you.

With no use-case controllers permitted, how can naked objects support the idea of business process?
A REST guru will tell you: expose more resources, and instead of writing a controller to sends losts passwords via mail, you will produce a /lost-passwords/username resource that the user will POST or DELETE to.
There is no difference in a Naked Objects approach: you will produce a LostPasswordRequest object with some methods that once manipulated (with the aid of a mail service) will provide the desired behavior. The advantage is that the process will reside in the domain layer and it will be simpler to test; the skinny controller remains skinny as you cannot write it.
The objects like LostPasswordRequest are also called purposeful objects.

If core objects are exposed directly to the user, how is it possible to restrict the attributes and behaviours that are available to a particular user, or in a particular context?
Simply by conforming to an implicit interface, via duck typing. Where there is a setName() method, if sometimes this should not be used, the framework says to provide a allowName() method that returns a boolean. This is an implicit interface in the sense that the developer is not forced to implement a specific interface but only to write methods with signatures that follow a standard pattern. When the method is not present, a default behavior is provided.
Another option is to configure via an acl the single method access level, preserving some method only for certain admin roles.

How is it possible to invoke multiple parameter methods from the user interface?
Talking of the NO Java framework, the DragNDrop interface will not allow you to do this, suggesting to narrow down the parameters to one.* I think if a service method has two parameters it can be viewed as a single parameter one on the two business object involved, as I explained previously.
Not allowing methods with many parameters to be called in the user interface (they can be used internally but not exposed) will help keep the model simple, and introduce Parameter Object. However, the Web interface allow these calls providing a form to compile with the various parameters.
* Update: this is no longer true as the thesis was about the first version of the framework. So this point is not an issue anymore.

Naked Objects could be the next paradigm shift in object-oriented programming. Why writing four layers when you should write only one?

Monday, July 06, 2009

Becoming a Doctrine 2 committer

In the last weeks I started to contribute with code to the Doctrine project. Doctrine is an Orm and database abstraction layer for php: it is the default orm for Symfony but it's not coupled to it and I integrated it successfully with Zend Framework. It is a good tool for abstracting the database layer and manage the persistence of the Model part of a MVC paradigm, which to me Zf does not very well with its Zend_Db component.

After opening tickets and upload patches for Doctrine 1.x for some months, I took a glimpse of the potentiality of the 2.x branch (that currently is not even in alpha). The code is in the trunk of the Doctrine repository and borrows concepts heavily from Hibernate:
http://trac.doctrine-project.org/wiki/Doctrine2.0
While Doctrine Query Language, based on Hql, was already present in the currently stable 1.x branch, the new Doctrine infrastructure is based on the Unit Of Work pattern instead of the old Active Record one.
The Active Record pattern is very famous and is used for example in Rails. It is the most simple solution of object relational mapping, which defines a class for every table of the database. A row is represented by an object of that class, that is subclassing Doctrine_Record/ActiveRecord depending on the framework and language you are using.
The Unit Of Work pattern does not substitute by itself the Active Record one, but it's part of the solution of refusing to have the domain objects depending on the infrastructure, in this case the mapping classes. This is very clean from a design and testing point of view as the most complex logic of an application resides in the domain classes (the User and Phonenumber ones for instance), and Doctrine 2 let the developer concentrate on writing and testing these models without (almost) taking into account where they will be persisted; how to map these classes is specified in annotations or via other metadata.
If you have written a bit of code you will probably find very interesting these solution, that is already used in Hibernate for the joy of Java programmers.

Said that, I really want to help the project as I dream of doing Domain Driven Design in php and persistence ignorance is a key point of DDD. So I asked how to start contribution to the project and the last week I've written eight test case class for phpunit plus the example model classes that they use. I was helped by Roman Borschel, the lead developer for the 2.x branch, that teached me how to use annotations properly and fixed my faults in the model classes. Keep in mind that contributing to an open source project you use or will use is a win-win situation because it helps the project going forward and obtain feedback, while it helps you to learn to use the tool well. And I will certainly use Doctrine 2 because I think it along with Zend Framework will kick Rails in the ass.

This monday, I have succesfully closed ticket #2276 and I look forward to learn more and go further. If you are a php developer, come to #doctrine-dev on the irc server freenode.net, or stay tuned to try the alpha releases of Doctrine 2 that will come in the future. Having a real domain model, free of dependencies versus concrete orms, is a dream of the php world that will be realized.

Saturday, July 04, 2009

Domain model is everything

What is a good domain model? The one that bridges together domain and infrastructure...
According to Wikipedia, Domain Model is a conceptual model of a system which describes the various entities involved in that system and their relationships. Note that is written capitalized, because it is recognized as a pattern.
Domain Model is typical complemented by infrastructure, the set of all the data and code needed for an application to work, which are not part of the model.
An important part of Domain Model concept is that it is a model: it does not take into account all the world variables but only the interesting ones for our application. If you need a home banking system, you don't need to persist in a relational database the eye color of the customers...

A practical approach
Producing a Domain Model is tipically achieved with classes (business object, a very overloaded term as Fowler says), while in the past a domain model was constructed using data structures and functions which processes them. OOP encapsulate data and methods that act on them in the same place: that's why it's so natural to produce object oriented code.
Not all the classes in an OO project are part of the model: the majority of them constitutes infrastructure. Collections classes, persistence mechanism for objects, file writers and readers, serialization systems, controllers, java servlet, iterators, view helpers, image manipulators - all part of infrastructure, the low level of an application.
The most important level is the model, that sits on the infrastructure (but it does not means that should be aware of all implementation detail of infrastructure classes) and provides the functionality needed to run the most of your user stories. It is the layer that unit tests absolutely have to cover. All the business logic should be encapsulated by the model.
Practically speaking, the User, Group and Article classes which you've seen in many posts and blogs as examples of code, are at the heart of a Domain Model. Controllers and views in a php framework (such as Zend Framework for php developers) are already present, as the job of a framework is to provide infrastructure: it's your model that differentiates the application from another.

Iterative work
Choosing the right model could lead to simple development: failing to do so would complicate subsequent actions. Because it's not possible to write code for a complete model from the start, a developer must be open to further model refinements. For instance, in Ossigeno there is a single script that rebuilds an environment (a particular combination of database and php files) from scratch updating the tables that persists the domain objects. Adding a field to an object means only writing a line of yaml and push the regenerate button.
Requirements gathering is not a definite phase: it's iterative. Whenever further requirements and modelling occurs, it's useful to have a simple way to refine the model code with a push-the-button script. The more you refine and regenerate, the more the Domain Model adapts to the real world; the more it adapts to the part of the world that interest us for our application, bridging the gap between code and domain.

A Linear Programming example
In math, the right model can do the difference with solving a problem or not being capable of solve it in a zillion of years.
Suppose you have to maximize a function of some variables (real numbers or integers): suppose also you have some constraints on the variables that cannot be violated; the solution to the problem should be a bunch of numbers that gives the top value for the objective function and does not infringe constraints.
Well, if you choose particular variables that let you write linear constraints, there's good news for you. You can apply Linear Programming and have the problem solved by a computer in polinomial time. If your model is not so well-crafted, and you have to resort to write constraints where two variables are multiplicated or divided, Linear Programming can't help you. And very bad things happen, such as finding a numeric solution taking weeks.
This example shows us that having a good Domain Model means not only drawing a correct painting of the business domain, but also use the right colors and lines to fit in the canvas. Programmatically speaking, the painting is our model while our infrastructure constitutes the canvas or panel where we draw.
A good model is one that can solve our problems, mapping the application entities into the code, while not overengineering the infrastructure. It can discosts from the real world, but the correct naming (we'll see in an example right now) can lighten the path...

Bridging the gap
We said that a good model stands in between the infrastructure and the business, so we can make an example of what is not a good model.
A bad model is too close to the infrastructure: for example if we model our users, groups and articles in a unique big, multidimensional array, the infrastructure used is very simple and is not subjected to particular stress.
A bad model is also too tight to the business domain: if we take a picture of the users, groups and articles world with static classes, deep inheritance trees and generated fields in the objects will make very hard to save and restore our application state.
However, the need for abstracting away the persistence concerns of objects from a model (for example in Domain Driven Design) have lead the developers to find a way to keep in touch to the domain. This is done by extending the infrastructure using ORMs. An Orm is a superset of the common infrastructure of a framework that cares about persistence of the objects involved in an application: it adds to the allowed infrastructure the typical object composition and inheritance features. Persistence ignorance is a wide argument and it is not treated here.

Sql relationships as an example
A common example of a model where the mapping to the real world is not immediate, and is sacrificed to performance and cleanliness, is the handling of many-to-many relationship in relational databases.
A relational database has been the state-of-the-art tool for persisting the state of an application, and today it's still the a widely used one. However, a relational database in its simplest form consists of tables, columns and rows, so it has no notion of how to handle a many-to-many relationship between our User objects and Group objects. If a user could belong to a single group, we would persist the relationship by a field group_id in the User table; but a User can belong to many groups, and conversely a particular group could have many number of users.
The standard solution is to create a new table, where there are only two columns: group_id and user_id, containing the numerical index of the Group and User rows. A User belonging to a particular group is described by an entry in this table, so we'll name it UserSubscription.
Our modelling has introduced another entity, that does not exists in the real world, but it is useful to mantain a homogeneous infrastructure. This is the best crafted model at this stage of development (not using ORMs).
This solution works particularly well in a rdbms context, so why not abstracting it away? This way we'll have a model withour UserSubscription that maps even better to the real world. This is the next step taken by the Orm family (Hibernate, Doctrine, ...), where you can define any type of relationship and let the Orm do the dirty job of persisting it in the database, with the aid of developer metadata, and providing a language similar to Sql to query the infrastructure layer and obtaining the stored User and Group objects, correctly composed.
This is stretching the gap between domain and infrastructure, letting your good model (that sits in the half) to go even near the domain side. That's why OOP is so successful, that's why Orms are a complex answer to a simple problem, but still so successful.

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