ZendFramework has always been criticized for its shortcomings as it cannot handle domain logic elegantly. Here are some of my solutions.
ZendFramework has always been criticized for its shortcomings as it cannot handle domain logic elegantly. Here are some of my solutions:
First, let's take a look at how we write Model and Controller:
General Model syntax:
Class Articles extends Zend_Db_Table
{
}
General Controller syntax:
Class ArticlesController extends Zend_Controller_Action
{
Protected $ _ articles;
Public function init ()
{
$ This-> _ articles = new Articles ();
}
Public function createAction ()
{
$ Article = $ this-> _ articles-> createRow ();
$ Article-> title = 'abc ';
$ Article-> content = 'XYZ ';
If ($ id = $ article-> save ()){
$ This-> _ redirect ('...');
} Else {
//...
}
}
Public function readAction ()
{
$ This-> view-> article = $ this-> _ articles-> fetchRow ("id = 1 ");
}
Public function updateAction ()
{
$ Article = $ this-> _ articles-> fetchRow ("id = 1 ");
$ Article-> title = 'abc ';
$ Article-> content = 'XYZ ';
If ($ article-> save ()){
$ This-> _ redirect ('...');
} Else {
//...
}
}
Public function deleteAction ()
{
$ Article = $ this-> _ articles-> fetchRow ("id = 1 ");
If ($ article-> delete ()){
$ This-> _ redirect ('...');
} Else {
//...
}
}
}
We usually say: Rich model is better. In the above example, we can see that the Model code is very small and there are many Controller codes. In general, this is a precursor to bad taste, but the above CRUD example is relatively simple, and the Model has obtained certain CRUD capabilities through inheritance, it can be said that it is very Rich, so this problem does not matter, the real test is what to do when an application contains a large amount of logic.
The so-called logic is roughly divided into two types: application logic and domain logic. For an article object, it is the application logic to send an email notification after the article is added successfully, and how to judge whether it is a popular article is the domain logic.
The principle of application logic and domain logic division is to check whether there is a technical taste. There is application logic, not domain logic. The reason for this division is that the object-oriented model emphasizes reusability, and the domain logic is the soul of a software. only the technical taste is stripped away to make it more likely to be reused.
In ZendFramework, we can regard the Controller as the application layer, because it naturally outlines the use case, so putting the application logic in the Controller can be said in the past, the domain logic should be fully included in the Model. In the common ZendFramework code, the role of Model is generally played by Zend_Db_Table. Zend_Db_Table is the implementation of a table data entry. The table data entry is used to operate a table, and our object is often just a row. Therefore, many domain logics are not likely to be added to the Zend_Db_Table level, but should be the Zend_Db_Table_Row level.
The following describes how to integrate domain logic into Zend_Db_Table_Row:
First, define a Row class:
Class Article extends Zend_Db_Table_Row
{
Public function isHot ()
{
//...
}
}
Then, the Row class can be attached to the Table class:
Class Articles extends Zend_Db_Table
{
Protected $ _ rowClass = 'article ';
}
At this time, you can use the Row class to use methods that contain domain logic (for example, the isHot method:
$ Article = $ this-> _ articles-> fetchRow ("id = 1 ");
If ($ article-> isHot ()){
//...
} Else {
//...
}
Everything I did has only one purpose: to change Zend_Db_Table_Row into a Rich Model!
In the use of ZendFramework. We can use Zend_Db_Table as the factory or warehouse used to manage the object lifecycle in the field. there can be a small number of logics related to the lifecycle of the object in the field, such as the Assembly of the object in the field. More domain logic exists in the Zend_Db_Table_Row object.
The general operation procedure should be as follows: in Zend_Db_Table, Zend_Db_Table_Row or Zend_Db_Table_Rowset is obtained through the fetchRow or fetchAll method. Then, use Zend_Db_Table_Row to complete the domain logic.
If you have a lot of entities, it seems boring to have a custom Row class. if ZendFramework can provide scaffolding like CakePHP to automatically generate code, it will be cool, but this is impossible. ZendFramework and CakePHP have different guiding ideology and follow two steps.