A simple factory pattern is the creation pattern of a class, also called the Static Factory method (static Factory methods) pattern. The simple factory pattern is determined by a factory object to create an instance of that product class.
1. Several forms of the factory model
The factory model is specifically responsible for instantiating a large number of classes that have a common interface. The factory model can dynamically determine which class to instantiate, without having to know in advance which class to instantiate each time. The factory model has the following forms:
(1) Simple Factory (Factory) mode, also known as static Factory method mode (static Factory methods pattern).
(2) Factory Methods (Factory method) mode, but also antisymmetric (polymorphic Factory) mode or virtual constructor (fictitious constructor) mode;
(3) Abstract Factory (Factory) mode, also known as the Toolbox (Kit or Toolkit) mode. The following is a brief class diagram of the simple factory pattern.
The simple factory model, or the static factory method pattern, is a special implementation of different factory method patterns. In other literatures, simple factories are often discussed as a special case of the common factory model.
Learning a simple factory model is a good preparation for learning the factory method pattern, and a good preparation for learning other patterns, especially the single case pattern and multiple example patterns.
2. Introduction of Simple Factory model
For example, there is a farm company that specializes in selling all kinds of fruits to the market. The following fruits need to be described in this system:
Grape Grape
Strawberry Strawberry
Apples Apple
The fruit is very different from other plants, that is, the fruit can be picked and eaten at last. A natural way to do this is to create an interface that is suitable for all kinds of fruit so that it can be separated from other plants in the farm. As shown in the following figure.
The fruit interface prescribes the interfaces that all fruits must achieve, including the methods that any fruit must have: planting plant (), growing Grow (), and Harvesting harvest (). The class diagram of the interface fruit is shown below.
The source code for this fruit interface is shown below.
Code Listing 1: The source code for the interface fruit
Interface Fruit
{public
function grow ();
Public Function Harvest ();
Public function plant ();
}
The Apple class is a kind of fruit, so it implements all the methods declared by the fruit interface. In addition, because the apple is the perennial plant, therefore has one treeage nature, describes the apple tree the age. Here is the source code for this Apple class.
Code Listing 2: Source code for Apple class
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 one of the fruit classes and implements all the methods declared by the fruit interface. However, since the grapes are divided into seeds and seedless, there is a seedless property over the usual fruit, as shown in the following figure.
The source code for the grapes is shown below. As can be seen, the Grape class also implements the fruit interface, which is a seed type of the fruit type.
Code Listing 3: The source code for class grape
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 and is therefore a subtype of the fruit type, as shown in the source code below.
Code Listing 4: The source code for class strawberry
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.";
}
}
The gardener of the farm is also a part of the system, and naturally it should be represented by a suitable class. This class is the Fruitgardener class, whose structure is described by the following class diagram.
The Fruitgardener class creates different fruit objects, such as Apple, Grape (Grape), or strawberry (strawberry), according to the requirements of the client. The Fruitgardener class throws a Badfruitexception exception if an illegal request is received.
The source code for the Gardener class is shown below.
Code listings 5:fruitgardener Class source code
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. At the client's call, this method creates the desired fruit object for the client. If the client's request is not supported by the system, the factory method throws a Badfruitexception exception. The source code for this exception class is shown below.
Code listings 6:badfruitexception Class source code
Class Badfruitexception extends Exception
{
}
When used, the client simply calls the Fruitgardener static method Factory (). Please see below for the signal
Sexual client source code.
Code Listing 7: How to use exception classes Badfruitexception
try {
fruitgardener::factory (' Apple ');
Fruitgardener::factory (' grape ');
Fruitgardener::factory (' Strawberry ');
//...
} catch (Badfruitexception $e) {
//...
}
In this way, the farm will be the harvest of hundreds of fruit!
3. Design an "object-oriented" calculator using simple Factory mode
/** * Object-oriented Calculator * thinking: * 1, object-oriented Basic, encapsulation, inheritance, much too * 2, the parent of common class * 3, various types of operations * */** * base class, Operation class * Only provide basic data, do not participate in operation/class Operat
Ion {//First number public $first _num = 0;
The second number public $second _num = 0;
/** * Gets the result, the other class overrides this method * @return double $result/Public Function GetResult () {$result = 0.00;
return $result; }/** * Addition class/class Operationadd extends Operation {/** * overrides the parent class to implement the addition algorithm */Public Function GetResult () {$re
Sult = 0;
return $this->first_num + $this->second_num;
}/** * Subtraction class * */Class Operationsub extends Operation {/** * overrides the parent class to implement the addition algorithm */Public Function GetResult () {
$result = 0;
return $this->first_num-$this->second_num;
}/** * Multiplication class * */Class Operationmul extends Operation {/** * overrides the parent class to implement the addition algorithm */Public Function GetResult () {
$result = 0;
return $this->first_num * $this->second_num; /** * * * */class Operationdiv extends Operation {/** * overrides the parent class to implement the addition algorithm */Public functionGetResult () {$result = 0;
if ($this->second_num = = 0) {throw new Exception (' second parameter cannot be zero for division operation! ');
return 0;
return $this->first_num/$this->second_num; }/** * Factory class */class Operationfactory {/** * Factory function * @param string $operation * @return Object/Public F
Unction CreateOperation ($operation) {$oper = null;
Switch ($operation) {case ' + ': $oper = new Operationadd ();
Break
Case '-': $oper = new Operationsub ();
Break
Case ' * ': $oper = new Operationmul ();
Break
Case '/': $oper = new Operationdiv ();
Break
Default:return 0;
return $oper;
}} $operation = new Operationfactory ();
$oper = $operation->createoperation ('/');
$oper->first_num = 10;
$oper->second_num = 20;
Var_dump ($oper->getresult ());