This article mainly introduces the simple factory mode in PHP design mode programming. It provides an example of fruit sales and calculator design, for more information, see the simple Factory mode, which is also called the Static Factory Method mode. The simple factory mode is determined by a factory object to create a product instance.
1. several forms of factory models
The factory mode is dedicated to instantiating a large number of classes with common interfaces. The factory mode dynamically determines which class to instantiate without having to know which class to instantiate each time in advance. The factory model has the following forms:
(1) Simple Factory mode, also known as Static Factory Method Pattern ).
(2) Factory Method mode, also known as Polymorphic Factory mode or Virtual Constructor mode;
(3) Abstract Factory mode, also known as Toolkit (Kit or Toolkit) mode. The following is a simple class diagram of the simple factory model.
Simple factory mode, or static factory method mode, is a special implementation of different Factory method modes. In other documents, simple factories are often discussed as special cases of common factory models.
Learning the simple factory model is a good preparation for learning the Factory method model. it is also a good preparation for learning other models, especially the Singleton and Singleton modes.
2. introduction of simple factory models
For example, a farm company sells all kinds of fruits to the market. In this system, you need to describe the following fruits:
Grape
Strawberry
Apple
The fruit is very different from other plants, that is, the fruit can finally be picked and eaten. A natural practice would be to establish an interface suitable for various fruits so that they can be separated from other plants on the farm. As shown in.
The fruit interface specifies the interfaces that all fruits must implement, including methods required for any fruit class: planting plant (), growing grow (), and harvesting harvest (). The class diagram of the interface Fruit is as follows.
The source code of this fruit interface is as follows.
Code List 1: Source code of the interface Fruit
interface Fruit{public function grow();public function harvest();public function plant();}
Apple is a kind of fruit, so it implements all the methods declared by the fruit interface. In addition, because Apple is a perennial plant, a treeAge exists to describe the age of the apple tree. The following is the source code of the Apple class.
Code List 2: Source code similar to Apple
class Apple implements Fruit{private $_treeAge;public function grow(){echo "Apple is growing.";}public function harvest(){echo "Apple has been harvested.";}public function plant(){echo "Apple has been planted.";}public function getTreeAge(){return $this->_treeAge;}public function setTreeAge($treeAge){$this->_treeAge = (int) $treeAge;}}
Similarly, the Grape class is a Fruit class and implements all the methods declared by the Fruit interface. However, because grapes are divided into two types: seedless and seedless, there is more seedless than the common fruit, as shown in.
The source code of grape is as follows. It can be seen that Grape class also implements the fruit interface, but is a seed type of the fruit type.
Code List 3: Source code of Grape class
class Grape implements Fruit{private $seedless;public function grow(){echo "Grape is growing.";}public function harvest(){echo "Grape has been harvested.";}public function plant(){echo "Grape has been planted.";}public function getSeedless(){return $this->seedless;}public function setSeedless($seedless){$this->seedless = (boolean) $seedless;}}
The Strawberry class implements the Fruit interface. Therefore, it is also a child type of the Fruit type. its source code is as follows.
Code List 4: Source code of the Strawberry class
class Strawberry implements Fruit{public function grow(){echo "Strawberry is growing.";}public function harvest(){echo "Strawberry has been harvested.";}public function plant(){echo "Strawberry has been planted.";}}
Farm gardeners are also part of the system, naturally represented by a suitable class. This class is the FruitGardener class, and its structure is described by the class diagram below.
The FruitGardener class creates different fruit objects, such as Apple, Grape, or Strawberry instances, based on client requirements. If an invalid requirement is received, the FruitGardener class throws a BadFruitException.
The source code of the gardener class is as follows.
Code List 5: Source code of the FruitGardener class
class FruitGardener{public static function factory($which){$which = strtolower($which);if ($which == 'apple') {return new Apple();} elseif ($which == 'strawberry') {return new Strawberry();} elseif ($which == 'grape') {return new Grape();} else {throw new BadFruitException('Bad fruit request');}}}
As you can see, the gardener class provides a static factory method. Call the client to create the fruit object required by the client. If the client request is not supported by the system, the factory method throws a BadFruitException. The source code of this exception class is as follows.
Code List 6: Source code of the BadFruitException class
class BadFruitException extends Exception{}
During use, the client only needs to call the static method factory () of FruitGardener. See the following illustration
Client source code.
Code listing 7: how to use the exception class BadFruitException
try {FruitGardener::factory('apple');FruitGardener::factory('grape');FruitGardener::factory('strawberry');//...} catch (BadFruitException $e) {//...}
In this way, the farm will surely have a bumper harvest!
3. design an "object-oriented" calculator using a simple factory model
/* ** Object-oriented calculator * ideas: * 1. Basic object-oriented, encapsulation, inheritance, too many * 2. parent class public class * 3. various operation classes * // ** base class. operation classes * only provide basic data, not involved in the Operation */class Operation {// The first number is public $ first_num = 0; // The second number is public $ second_num = 0;/*** get the result, other classes override this method * @ return double $ result */public function getResult () {$ result = 0.00; return $ result ;}} /*** addition class */class OperationAdd extends Operation {/*** overwrites the parent class and implements the addition algorithm */public function getResult () {$ result = 0; return $ this-> first_num + $ this-> second_num;}/*** subtraction class **/class OperationSub extends Operation {/*** overwrites the parent class, implement addition algorithm */public function getResult () {$ result = 0; return $ this-> first_num-$ this-> second_num ;}} /*** multiplication class **/class OperationMul extends Operation {/*** overwrites the parent class and implements the addition algorithm */public function getResult () {$ result = 0; return $ this-> first_num * $ this-> second_num;}/*** Division class **/class OperationDiv extends Operation {/*** overwrites the parent class and implements the addition algorithm */public function getResult () {$ result = 0; if ($ this-> second_num = 0) {throw new Exception ('division operation second parameter cannot be zero! '); Return 0;} return $ this-> first_num/$ this-> second_num ;}} /*** Factory class */class OperationFactory {/*** factory function * @ param string $ operation * @ return object */public function createOperation ($ operation) {$ operator = null; switch ($ operation) {case '+': $ operator = new OperationAdd (); break; case '-': $ operator = new OperationSub (); break; case '*': $ scheme = new OperationMul (); break; case '/': $ scheme = new OperationDiv (); break; default: return 0 ;} return $ OperationFactory (); $ operator = $ operation-> createOperation ('/'); $ operator-> first_num = 10; $ rows-> second_num = 20; var_dump ($ rows-> getResult ());