Archive for the ‘Design Patterns’ Category
Zend Framework DAL: DAOs and DataMappers
A Data Access Layer (DAL) is the layer of your application that provides simplified access to data stored in persistent storage of some kind. For example, the DAL might return a reference to an object complete with its attributes instead of a row of fields from a database table.
A Data Access Objects (DAO) is used to abstract and encapsulate all access to the data source. The DAO manages the connection with the data source to obtain and store data. Also, it implements the access mechanism required to work with the data source. The data source could be a persistent store like a database, a file or a Web service.
And finally, a DataMapper is used to move data between the object and a database while keeping them independent of each other. The DataMapper main responsibility is to transfer data between the two and also to isolate them from each other.
Zend Framework Example
app/
controllers/
UserController.php
views/
lib/
Project/
Dao/
Db/
User.php
Service/
User.php
DataMapper/
User.php
Entity/
User.php
Model/
User.php
Zf/
DataSource/
Dao/
Mapper.php
Domain/
Entity.php
Db/
Adapter.php
Database Table Structure
CREATE TABLE `user` ( `id` int(11) NOT NULL auto_increment, `first_name` varchar(100) NOT NULL, `last_name` varchar(100) NOT NULL, PRIMARY KEY (`id`) )
The User DAO
The DAO pattern provides a simple, consistent API for data access that does not require knowledge of an ORM interface. DAO does not just apply to simple mappings of one object to one relational table, but also allows complex queries to be performed and allows for stored procedures and database views to be mapped into data structures.
A typical DAO design pattern interface is shown below:
class Project_Dao_Db_User extends Zf_Db_Adapter
{
public function find($id)
{
$db = $this->getConnection();
$query = $db->select()->from('user')->where('id = ?', $id);
return $db->fetchRow($query);
}
public function findAll()
{
$db = $this->getConnection();
$query = $db->select()->from('user');
return $db->fetchAll($query);
}
public function insert($data)
{
$db = $this->getConnection();
$db->insert('user', $data);
return $db->lastInsertId();
}
public function update($id, $data)
{
$db = $this->getConnection();
$where = $db->quoteInto('id = ?', $id);
return $db->update('user', $data, $where);
}
public function delete($id)
{
$db = $this->getConnection();
$where = $db->quoteInto('id = ?', $id);
return $db->delete('user', $where);
}
}
Source Code: Zf_Db_Adapter
The User Entity
An Entity is anything that has continuity through a life cycle and distinctions independent of attributes that are important to the application’s user.
class Project_Entity_User extends Zf_Domain_Entity
{
public $id;
public $firstName;
public $lastName;
}
Source Code: Zf_Domain_Entity
The User DataMapper
class Project_DataMapper_User extends Zf_DataSource_Dao_Mapper
{
protected $_map = array(
'id' => 'id',
'first_name' => 'firstName',
'last_name' => 'lastName'
);
public function find($id)
{
$dao = new Project_Dao_Db_User();
$row = $dao->find($id);
if (!$row) {
return false;
}
return $this->map($row);
}
}
Source Code: Zf_DataSource_Dao_Mapper
The User Model
The following class represents the User Relational Model:
class Project_Model_User
{
public function getUser($id)
{
$mapper = new Project_DataMapper_User();
$mapper->setEntity(new Project_Entity_User());
$user = $mapper->find($id);
return $user;
}
}
The User Controller
class UserController extends Zend_Controller_Action
{
public function viewAction()
{
$model = new Project_Model_User();
$user = $model->getUser($this->_getParam('id'));
if ($user) {
$userId = $user->getId();
$userFirstName = $user->getFirstName();
$userLastName = $user->getLastName();
// get an array of database fields and values
$row = $user->getRow();
}
}
}
Keep in mind that ORM tools such as phpDataMapper and Doctrine offer an alternative way of modeling data. ORMs and ERMs are popular with Web frameworks, and the combination of an ORM and DDD makes DAOs redundant, however, it has not been proven to be better than a straightforward approach of implementing a collection of domain-specific data access functions.
That’s all, I hope you’ve found this post useful.
The Little Manual of API Design
This manual gathers together the key insights into API design that were discovered through many years of software development on the Qt application development framework at Trolltech (now part of Nokia). When designing and implementing a library, you should also keep other factors in mind, such as efficiency and ease of implementation, in addition to pure API considerations. And although the focus is on public APIs, there is no harm in applying the principles described here when writing application code or internal library code.
An Alternative to Zend_Controller
Zend Framework is very flexible and one of its strengths is that it allows developers to implement their own components. The Zend_Controller component, for example, is very powerful. Of course, it’s not my intention to replace it, but to offer an alternative that decreases the number of decisions a developer needs to make when developing an application.
Meet Zf_Controller. The Zf_Controller component has the following goals:
- Abstract complexity: Try to reduce the level of details so the developer can focus on a few concepts at a time.
- Emphasize Convention over Configuration: Emphasize CoC, meaning that the user only needs to specify unconventional aspects of the application.
- Maintain backwards compatibility: Allow the developer to replace Zf_Controller with Zend_Controller in case the application grows in size or complexity.
- Improve performance: Load less classes, execute less code.
- Remove circular references: Avoid circular references.
- Remove Singleton classes: Avoid implementing the Singleton pattern.
- Research: Learn more about the framework, what it does, how it works.
Project Structure
Zend_Controller allows you to use the project structure that best suits your needs. On the other hand, Zf_Controller is more rigid, it only allows you to use the standard project structure:
project/
app/
config/
controllers/
ErrorController.php
IndexController.php
views/
layouts/
scripts/
error/
index/
index.phtml
domain/
Model/
Example.php
lib/
Zend/
Zf/
Zf_Controller classes:
Zf/
Controller/
Action/
Helper/
Layout.php
Action.php
Front.php
Bootstrap File
Zend_Controller:
define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../app'));
set_include_path(APPLICATION_PATH . '/../lib'
. PATH_SEPARATOR . get_include_path());
require_once "Zend/Loader.php";
Zend_Loader::registerAutoload();
$frontController = Zend_Controller_Front::getInstance();
$router = $frontController->getRouter();
$routes = include_once APPLICATION_PATH . '/config/routes.php';
$router->addRoutes($routes);
$layout = Zend_Layout::startMvc();
$layout->setLayoutPath(APPLICATION_PATH . '/views/layouts');
$frontController->dispatch();
Zf_Controller (no Router):
define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../app'));
set_include_path(APPLICATION_PATH . '/../lib'
. PATH_SEPARATOR . APPLICATION_PATH . '/../domain);
require_once "Zend/Loader.php";
Zend_Loader::registerAutoload();
$frontController = new Zf_Controller_Front();
$frontController->setLayoutPath(APPLICATION_PATH . '/views/layouts');
$frontController->dispatch();
Action Controller
The default action controller and the default action are named “index”:
class IndexController extends Zf_Controller_Action
{
public function indexAction()
{}
}
Error Controller
Zend_Controller:
class ErrorController extends Zend_Controller_Action
{
// Action used by Zend_Controller
public function errorAction()
{
$error = $this->_getParam('error_handler');
echo $error->exception->getMessage();
}
}
Zf_Controller:
class ErrorController extends Zf_Controller_Action
{
// Action used by Zf_Controller
public function indexAction($e)
{
echo $e->getMessage();
}
}
Rendering a View Script
Zf_Controller does not use the ViewRenderer helper class. To make the code more readable and testable, you need to call the render() method and return a value:
class IndexController extends Zf_Controller_Action
{
public function indexAction()
{
$view = $this->initView();
$view->message = 'Hello';
// Renders views/scripts/index/index.phtml
return $this->render();
}
public function testAction()
{
$view = $this->initView();
$view->message = 'Goodbye';
// Renders views/scripts/index/index.phtml
return $this->render('index');
}}
index.phtml file:
<p><?php echo $this->message ?></p>
Using a Layout
By setting the path to your layouts in the Bootstrap file, you automatically enable the default layout “layout.phtml”:
$frontController = new Zf_Controller_Front(); $frontController->setLayoutPath(APPLICATION_PATH . '/views/layouts');
To disable the layout:
class IndexController extends Zf_Controller_Action
{
protected $_isLayoutEnabled = false;
}
To use a different layout:
class IndexController extends Zf_Controller_Action
{
protected $_layoutScript = 'main.phtml';
}
main.phtml file:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <?php echo $this->headTitle() ?> <?php echo $this->headScript() ?> <?php echo $this->headStyle() ?> </head> <body> <div id="content"><?php echo $this->layout()->content ?></div> </body> </html>
Source Code:
http://svn.fedecarg.com/repo/Zf/Controller/
Implementing your own Front Controller in Zend Framework
There’s no doubt that the additional complexity of implementing the default Front Controller in ZF results in a number of benefits. The most important ones are flexibility and extensibility. The Front Controller implementation takes into consideration the future growth of your application and its design reduces the level of effort required to extend it. A good example of this is the plugin architecture.
But, what if after evaluating the requirements of your system, you determine that there’s not sufficient complexity to implement the default Front Controller? What if you don’t need all that flexibility, a URL mapper, a ViewRendered plugin or an ActionStack helper. Maybe all you need is just a couple of controllers, and that’s it. It’s clear that the standard Front Controller does provide more options and meets every possible use case requirement, but at the cost of complexity and a lot of classes.
So, what to do? Do you choose a different tool for the job, or replace the default Front Controller with your own implementation? How hard can it be? Is it really that difficult to replace the most important component of the Zend Framework and maintain backwards compatibility?
You are about to find out.
In this series of posts, I’ll try to cover a few things I’ve learned about implementing my own Front Controller in Zend Framework. Most of the ideas and code are based on my previous posts:
- Zend Framework: The Cost of Flexibility is Complexity
- Zend Framework Automatic Dependency Tracking
- Zend Framework Controller: 22% Drop in Responsiveness
- Refactoring the Front Controller of the Zend Framework
- Improving the performance of Zend_Controller
- Zend Framework Architecture
Will simplicity finally meet power?
Domain-Driven Design with Zend Framework
Part 1: Domain-Driven Design and MVC Architectures
Part 2: Domain-Driven Design: Data Access Strategies
Part 3: Domain-Driven Design: The Repository
Some of the Domain-driven design concepts explained in my previous posts are applied in this sample application. I’m also going to use the Zend Framework infrastructure to speed up some development tasks.
Directory Structure
app/ -> Application and UI Layers domain/ -> Domain Layer lib/ -> Infrastructure Layer
Application and UI Layers
app/
controllers/
UserController.php
views/
layouts/
scripts/
Domain Layer
This layer should be well separated from the other layers and it should have few dependencies on the framework(s) you are using. I’m going to group all the classes and interfaces under the namespace “Project” and add it to my include path:
domain/
Project/
Dao/
Db/
IUser.php
IUserProfile.php
User.php
UserProfile.php
Model/
User/
IRepository.php
Repository.php
User.php
UserProfile.php
Users.php
Infrastructure Layer
This layer acts as a supporting library for all the other layers:
lib/
Zend/
...
Zf/
Db/
Adapter.php
Exception.php
ReplicationAdapter.php
Domain/
Collection.php
Entity.php
Exception.php
Repository.php
User Entity
The User and UserProfile objects have a one-to-one relationship and form an Aggregate. An Aggregate is as a collection of related objects that have references between each other. Within an Aggregate there’s always an Aggregate Root (parent Entity), in this case User:
class Project_Model_User extends Zf_Domain_Entity
{
/* @var int */
private $id;
/* @var string */
private $name;
/* @var Project_Model_UserProfile */
private $profile;
public function __construct($properties)
{
$this->define($properties);
}
}
Usage:
$array = array('id'=>1, 'name'=>'Federico');
$user = new Project_Model_User($array);
$user->setProfile($profile);
echo $user->getId(); // Outputs 1
echo $user->getName(); // Outputs Federico
Users Collection
A collection is simply an object that groups multiple elements into a single unit.
class Project_Model_Users extends Zf_Domain_Collection
{
public function __construct($users)
{
foreach ($users as $user) {
if (!($user instanceof Project_Model_User)) {
throw new Zf_Domain_Exception(...);
}
$this->append($user);
}
}
}
User DAO
The UserDAO class allows data access mechanisms to change independently of the code that uses the data:
class Project_Dao_Db_User extends Zf_Db_Adapter
{
public function find($id)
{
$db = $this->getConnection();
$query = $db->select();
$query->from('user');
$query->where('id = ?', $id);
$result = $db->fetchRow($query);
return $result;
}
public function findAll()
{
...
return $resultSet;
}
}
User Repository
A Repository is basically a collection of Aggregate Roots. Collections are used to store, retrieve and manipulate Entities and Value objects, however, object management is beyond the scope of this post.
The UserRepository object injects dependencies on demand, making the instantiation process inexpensive. A caller method is responsible for dynamically creating the setter and getter methods. You can easily mock objects by passing a custom config array via the constructor.
class Project_Model_User_Repository extends Zf_Domain_Repository
{
/* @var Project_Dao_Db_User */
private $userDao;
/* @var Project_Dao_Db_UserProfile */
private $userProfileDao;
/* @var array IoC Spec */
private $inject = array(
'userDao' => 'Project_Dao_Db_User',
'userProfileDao' => 'Project_Dao_Db_UserProfile'
);
public function getUserById($id)
{
$row = $this->getUserDao()->find($id);
$user = new Project_Model_User($row);
$row = $this->getUserProfileDao()->findByUserId($id);
$profile = new Project_Model_Profile($row);
$user->setProfile($profile);
return $user;
}
public function getUsers()
{
$users = array();
$rows = $this->getUserDao()->findAll();
foreach ($rows as $row) {
$users[] = new Project_Model_User($row);
}
return new Project_Model_Users($users);
}
}
Usage:
$repo = new Project_Model_User_Repository(); $user = $repo->getUserById(1); $profile = $user->getProfile(); $users = $repo->getUsers();
Source Code
http://fedecarg.com/projects/show/zfdomain
http://fedecarg.com/projects/show/zfreplicationadapter
Links
If you’re interested in learning more about Domain-driven design, I recommend the following articles:
Domain Driven Design and Development In Practice
Domain-Driven Design in an Evolving Architecture
Domain-Driven Design: The Repository
Part 2: Domain-Driven Design: Data Access Strategies
The Ubiquitous Language
The ubiquitous language is the foundation of Domain-driven design. The concept is simple, developers and domain experts share a common language that both understand. This language is set in business terminology, not technical terminology. This ubiquitous language allows the technical team become part of the business.
The Repository
Repositories play an important part in DDD, they speak the language of the domain and act as mediators between the domain and data mapping layers. They provide a common language to all team members by translating technical terminology into business terminology.
In a nutshell, a Repository:
- Is not a data access layer
- Provides a higher level of data manipulation
- Is persistence ignorance
- Is a collection of aggregate roots
- Offers a mechanism to manage entities
Injecting DAO’s
In DDD, you inject Repositories, not DAO’s in domain entities. In the absence of an ORM framework, the DAO handles the impedance mismatch that a relational database has with object-oriented techniques. For example, imagine you have an entity named User that needs to access the database to retrieve the User details:
class User
{
// DAO needs to be injected
private $_dao;
private $_data;
public function setDao(UserDaoInterface $dao) {}
public function getDao() {}
public function setData($data) {}
public function getData()
{
if (null === $this->_data) {
$data = $this->getDao()->find($id);
$this->setData($data);
}
return $this->_data;
}
}
The User DAO class will look something like this:
interface UserDaoInterface
{
public function find($id);
}
class UserDaoDb implements UserDaoInterface
{
// Db needs to be injected
private $_db;
public function setDb(DbInterface $db) {}
public function getDb() {}
public function find($id)
{
$db = $this->getDb();
$query = $db->select();
$query->from('user');
$query->where('id = ?', $id);
return $db->fetchRow($query);
}
}
$userDao = new UserDaoDb();
$userDao->setDb($db);
$user = new User();
$user->setDao($userDao);
$data = $user->getData();
Is there an easier way to create entities and inject dependencies? The process of creating an entity is complex, because an entity always has relationship with other objects in your domain model. When creating an entity, we have to initialize its relationships as well. Therefore, it’s a good practice to delegate this task to another object.
But, what about separation of concerns? DAO’s are related to persistence, and persistence is infrastructure, not domain. The main problem with the example above is that we have lots of different concerns polluting the domain. According to DDD, an object should be distilled until nothing remains that does not relate to its meaning or support its role in interactions. And that’s exactly the problem the Repository pattern tries to solve.
Injecting Repositories
Lets create a UserRepository class to isolate the domain object from details of the UserDaoDb class:
class User
{
// Repository needs to be injected
private $_repository;
private $_data;
public function setRepository(UserRepositoryInterface $repo) {}
public function getRepository() {}
public function setData($data) {}
public function getData()
{
if (null === $this->_data) {
$data = $this->getRepository()->getUserById($id);
$this->setData($data);
}
return $this->_data;
}
}
It’s the responsibility of the UserRepository to work with all necessary DAO’s and provide all data access services to the domain model in the language which the domain understands.
class UserRepositoryInterface
{
public function getUserById($id);
}
class UserRepository implements UserRepositoryInterface
{
// DAO needs to be injected
private $_userDao;
public function setUserDao(UserDaoInterface $userDao) {}
public function getUserDao() {}
public function getUserById($id)
{
return $this->getUserDao()->find($id);
}
}
$userDao = new UserDaoDb();
$userDao->setDb($db);
$userRepo = new UserRepository();
$userRepo->setUserDao($userDao);
$user = new User();
$user->setRepository($userRepo);
$data = $user->getData();
The main difference between the Repository and the DAO is that the DAO is at a lower level of abstraction and doesn’t speak the ubiquitous language of the domain.
So, what’s next?
We’ve seen how to write a persistence-ignorant domain model. Next, I’ll explain how to automate the creation and injection of dependencies.
Domain-Driven Design: Data Access Strategies
Part 1: Domain-Driven Design and MVC Architectures
The Domain Model
Here are some of the features a Domain-driven design framework should support:
- A domain model that is independent and decoupled from the application.
- A reusable library that can be used in many different domain-specific applications.
- Dependency Injection in order to inject Repositories and Services into Domain Objects.
- Integration with unit testing frameworks, such as PHPUnit.
- Good integration with other frameworks, such as Zend, Symfony, Doctrine, etc.
The Zend Framework, for example, is part of the infrastructure layer and acts as a supporting library for all the other layers. However, the domain layer should be well isolated from the other layers of the application and should not be dependent on the framework you are using.
Data Access Strategies
When accessing data from a data source, you have to decide how your application will communicate with a data source. Each data access strategy has its own advantages and disadvantages. Here are some design patterns that support DDD:
Generic DAO’s
Data Access Objects (DAO’s) and Repositories play an important role in DDD. The goal of a DAO is to abstract and encapsulate all access to the data and provide an interface. The DAO always connects, reads and saves data to a data source. From the applications point of view, it makes no difference when it accesses a database, XML file or Web service:
$user = new UserDbDao(); $row = $user->findUserById(456); echo $row->name; $user = new UserXmlDao(); $row = $user->findUserById(456); echo $row->name;
Table Data Gateway
An object that acts as a Gateway to a database table. One instance handles all the rows in the table. The Zend_Db_Table solution is an implementation of the Table Data Gateway pattern:
$user = new User(); $rows = $user->find(456); $row = $rows->current(); echo $row->name;
More info: Table Data Gateway
Row Data Gateway
An object that acts as a Gateway to a single record in a data source. There is one instance per row. Zend_Db_Table_Row is an implementation of the Row Data Gateway pattern:
$user = new User();
$row = $user->fetchRow($user->select()->where('user_id = ?', 1));
echo $row->name;
More info: Row Data Gateway
Active Record
An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data. The Mad_Model component is an ORM layer that follows the Active Record pattern where tables map to classes, rows map to objects, and columns to object attributes:
$user = new User(); $userFinder = new UserFinder(); $row = $userFinder->find(456);
More info: Active Record
Data Mapper
A layer of Mappers that moves data between objects and a database while keeping them independent of each other and the mapper itself:
$user = new User(); $userMapper = new UserMapper(); $row = $userMapper->findByEmail($email);
More info: Data Mapper
Data Transfer Objects
A Data Transfer Object (DTO) in Domain-driven design is not the same as a Value Object. A DTO is often used in combination with a DAO to encapsulate data. It allows you to reduce communication effort when dealing with a lot of small data entities. For example:
class UserData
{
public function setId($id) {}
public function getId() {}
public function setFirstName($firstName) {}
public function getFirstName() {}
public function setLastName($lastName) {}
public function getLastName() {}
}
$user = new UserData();
$user->setFirstName('Jim');
$user->setLastName('Morrison');
$userDao = new UserDbDao();
$userDao->insert($user);
A DTO is a simple container for a set of aggregated data. It should contain no business logic and limit its behaviour to activities such as internal consistency checking and basic validation. Be careful not to make the DTO depend on any new classes as a result of implementing these methods.
Domain-Driven Design and MVC Architectures
According to Eric Evans, Domain-driven design (DDD) is not a technology or a methodology. It’s a different way of thinking about how to organize your applications and structure your code. This way of thinking complements very well the popular MVC architecture. The domain model provides a structural view of the system. Most of the time, applications don’t change, what changes is the domain. MVC, however, doesn’t really tell you how your model should be structured. That’s why some frameworks don’t force you to use a specific model structure, instead, they let your model evolve as your knowledge and expertise grows.
Domain-driven design separates the model layer “M” of MVC into an application, domain and infrastructure layer. The infrastructure layer is used to retrieve and store data. The domain layer is where the business knowledge or expertise is. The application layer is responsible for coordinating the infrastructure and domain layers to make a useful application. Typically, it would use the infrastructure to obtain the data, consult the domain to see what should be done, and then use the infrastructure again to achieve the results. Srini Penchikala explains this in more detail here: “Domain Driven Design and Development In Practice“.
Object-oriented programming is the most important element in the domain implementation. Domain objects are designed using classes and interfaces, and take advantage of OOP concepts like inheritance, encapsulation, and polymorphism. Most of the domain elements are true objects with both State (attributes) and Behaviour (methods or operations that act on the state). Entities and Value Objects in DDD are classic examples of OOP concepts since they have both state and behaviour.
Terminology used by Domain-driven design
- Entity: An object which has a distinct identity. For example, a User entity has a distinct identity with an ID.
- Value Object: An object which has no distinct identity, like numbers and dates. For example, if two Users have the same date of birth, you can have multiple copies of an object that represents the date 16 Jan 1982.
- Factory: Used to create Entities. For example, you can use a Factory to create a Profile entity from a User entity.
- Repository: Used to store, retrieve and delete domain objects from different storage implementations. For example, you can use a Repository to store the Profile your Factory created.
- Service: When an operation does not conceptually belong to any object.
The purpose of this post was to provide a brief introduction to Domain-driven design.
Part 2: Domain-Driven Design: Data Access Strategies
Links
If you’re interested in learning more about Domain-driven design or Model-driven design, I recommend the following articles:
Favour object composition over class inheritance
What does “favour composition over inheritance” mean, and why is it a good thing to do?
Object composition and inheritance are two techniques for reusing functionality in object-oriented systems. In general, object composition should be favoured over inheritance. It promotes smaller, more focused classes and smaller inheritance hierarchies.
Troels Knak-Nielsen wrote:
Class inheritance is a mix of two concepts. The extending class inherits the parents implementation (functions/methods) and it inherits the parents type. In a statically typed language, the latter is fairly important, since you can’t freely mix types. So if some method expects an argument of a given type, you might use inheritance to satisfy this. In a dynamically typed language that is a non-issue. You can simply implement the expected behaviour and that’s all there is to it. If you need a more explicit contract, you can document it or – since PHP has sort of a middle-way on this matter – you could use a statically typed interface (Eg. implements Person, rather than extends Person) to do the same thing. Since PHP is dynamically typed, this (slightly more verbose and restrictive) solution is purely optional. You can just use an implicit contract (duck typing).
The other use of class inheritance is to reuse implementation. If your abstract class Person is extended by a subclass Employer, you would have access to the same code in Employer as you do in Person. You could achieve code-reuse with composition as well, but it takes a bit more work. Employer would have to implement a wrapper that delegates control to a Person instance in this case. Eg.:
class Person {
function sayHello() {
echo "Hello, World!";
}
}
class Employer {
protected $person;
function __construct() {
$this->person = new Person();
}
function sayHello() {
$this->person->sayHello();
}
}
rather than:
class Person {
function sayHello() {
echo "Hello, World!";
}
}
class Employer extends Person {}
As you can see, slightly more work to do, which is why people often use inheritance in these cases. The cost however, is that the Person-Employer relationship is now set in stone; It can’t be changed or intercepted at runtime. There is also the matter of clarity. While the compositional code is more verbose, it is also very clear about what it does. You can look at the code and know what it does. With the inheritance version, you need to look at the superclass to find out what it does. Some times there are multiple levels of inheritance, making you trace up and down the chain to figure out exactly what code is available in the concrete class. Finally, there is the problem of multiple inheritance. In PHP, you can’t. You only have one shot at inheritance, so if you want to reuse code from two places, well, you’re out of luck.
Source: SitePoint Forums
Kenneth Downs: Why I do not use ORM
A thorough knowledge of database behaviour tends to lead a person away from ORM. First off, the two basic premises of ORM are factually incorrect: One, that there is some native incompatibility between databases and code, and two, that all the world must be handled in objects. These two misconceptions themselves might be excusable if they turned out to be harmless, but they are far from harmless. They promote a wilful ignorance of actual wise database use, and in so doing are bound to generate methods that are inefficient at best and horrible at worst.