Case Analysis of Simple Factory and Factory Pattern in PHP Design Pattern
- 2021-12-04 18:16:24
- OfStack
This paper illustrates the simple factory and factory patterns of PHP design pattern. Share it for your reference, as follows:
Factory pattern is a kind of creation pattern, which is divided into simple factory pattern, factory pattern and abstract factory pattern. Simple factory can be called a special case of factory pattern
Let's use a simple code to explain 1. Now suppose we are customers and need apple-flavored drinks and banana-flavored drinks
<?php
class AppleDrink{
function getDrinkName()
{
echo ' Apple drink ';
}
}
class BananaDrink{
function getDrinkName()
{
echo ' Banana drink ';
}
}
// Customer 1
$apple = new AppleDrink();
$apple->getDrinkName();
echo "<br/>";
$banana = new BananaDrink();
$banana->getDrinkName();
echo "<br/>";
// Customer 2
$apple1 = new AppleDrink();
$apple1->getDrinkName();
echo "<br/>";
$banana1 = new BananaDrink();
$banana1->getDrinkName();
Run results:
Apple drink
Banana drink
Apple drink
Banana drink
This is the most basic way to write it. Customers and drinks are strongly coupled, which is what we usually call hard coding
One day, the boss felt that the name AppleDrink was not easy to sell in China, and wanted to change it to Xingmu (eye-catching), which is the name of China (McDonald's changed to Golden Arch)
You will find that every place you need to find NEW in the code is changed to
new Xingmu()
If it has other initialization steps, it is even more nightmare, and it is likely to cause some unnecessary troubles
Let's change this file in simple factory mode
<?php
class AppleDrink{
function getDrinkName()
{
echo ' Apple drink ';
}
}
class BananaDrink{
function getDrinkName()
{
echo ' Banana drink ';
}
}
class FruitFactory{
function makeDrink($fruit){
if ($fruit == 'apple'){
return new AppleDrink();
}elseif ($fruit == 'banana'){
return new BananaDrink();
}
}
}
$factory = new FruitFactory();
$apple = $factory->makeDrink('apple');
$apple->getDrinkName();
echo "<br/>";
$banana = $factory->makeDrink('banana');
$banana->getDrinkName();
echo "<br/>";
$apple1 = $factory->makeDrink('apple');
$apple1->getDrinkName();
echo "<br/>";
$banana1 = $factory->makeDrink('banana');
$banana1->getDrinkName();
Run results:
Apple drink
Banana drink
Apple drink
Banana drink
Now we find that if the boss wants to change his name, I only need to put the name in FruitFactory
new AppleDrink
Replace with
new Xingmu()
That is, there is no need to change other places, and there is no need to turn over the code to find where to use it
new
So, the decoupling between the customer and the drink is realized, and it is also in line with the object-oriented design idea. I just want a bottle of drink, and I don't need to know how to make this drink.
This is the simple factory model, Users can directly create the required instance according to the factory class when using it, Without knowing how these objects are created and organized, The outside world is isolated from specific classes, Low coupling, Is beneficial to the optimization of the whole software architecture, Applicable to the factory class is responsible for the creation of less objects, customers only know the parameters of the factory class passed in, for how to create objects (logic) do not care, simple factory mode is also called static factory mode can be written as a static method of the factory class in the premise of not need to instantiate the factory directly call the static method to return the required instance
Ok, so then again, the company is going to diversify its products and add orange-flavored drinks. So what do we need to do? First, we need to add orange-flavored drinks, and then we need to add judgment in the factory. When the fruit label is orange, we need to return to orange-flavored drinks
class OrangeDrink{
function getDrinkName()
{
echo ' Orange flavored drink ';
}
}
class FruitFactory{
function makeDrink($fruit){
if ($fruit == 'apple'){
return new AppleDrink();
}elseif ($fruit == 'banana'){
return new BananaDrink();
}elseif ($fruit == 'orange'){
return new OrangeDrink();
}
}
}
Then every time we need to add a new product, we need to change the factory file. When the object generation is complicated, the factory file will get bigger and bigger, and the change may cause some unexpected problems
Object-oriented design principles, open to extension, closed to change, then there is no way, in the original code on the basis of adding products
The answer is yes, let's rewrite this method one more time
<?php
interface Drink{
function getDrinkName();
}
class AppleDrink implements Drink{
function getDrinkName()
{
echo ' Apple-flavored drink ';
}
}
class BananaDrink implements Drink{
function getDrinkName()
{
echo ' Banana flavored drink ';
}
}
interface FruitFactory{
function makeDrink();
}
class AppleFactory implements FruitFactory{
function makeDrink()
{
return new AppleDrink();
}
}
class BananaFactory implements FruitFactory{
function makeDrink()
{
return new BananaDrink();
}
}
$appleFactory = new AppleFactory();
$apple = $appleFactory->makeDrink();
$apple->getDrinkName();
echo "<br/>";
$bananaFactory = new BananaFactory();
$banana = $bananaFactory->makeDrink();
$banana->getDrinkName();
Run results:
Apple-flavored drink
Banana flavored drink
Now when you need to add orange-flavored drinks again, you just need to add orange-flavored drinks products and orange-flavored drinks factories, without changing the original code
class OrangeDrink implements Drink{
function getDrinkName()
{
echo ' Orange flavored drink ';
}
}
class OrangeFactory implements FruitFactory{
function makeDrink()
{
return new OrangeDrink();
}
}
This is the factory pattern, which is a derivative of the simple factory pattern and solves many problems of the simple factory pattern. First of all, the principle of opening and closing is fully realized, which is open to expansion and closed to change. Secondly, it realizes a more complex hierarchical structure, which can be applied to occasions with complex product results. The factory method pattern abstracts the simple factory pattern. There is an abstract Factory class (which can be abstract classes and interfaces). This class will not be responsible for specific product production, but only formulate 1 specification, and the specific production work will be completed by its subclasses. In this pattern, factory classes and product classes can often correspond in turn. That is, an abstract factory corresponds to an abstract product, and a concrete factory corresponds to a concrete product, so this concrete factory is responsible for producing the corresponding product.
Summary:
Whether it is simple factory pattern, factory method pattern or abstract factory pattern, they all belong to factory pattern, and they are very similar in form and characteristics, and their ultimate goal is decoupling. When we use it, we don't have to care whether this pattern is a factory method pattern or an abstract factory pattern, because the evolution between them is often elusive. Often you will find that the factory method pattern clearly used becomes an abstract factory pattern because the products in the class constitute product families in different hierarchical structures when new requirements come and a new method is added. For the abstract factory pattern, when one method is reduced so that the products provided by the product no longer constitute a product family, it evolves into the factory method pattern. Therefore, when using the factory mode, you only need to care about whether the purpose of reducing the coupling degree is achieved
For more readers interested in PHP related content, please check the topics on this site: "Introduction to php Object-Oriented Programming", "Encyclopedia of PHP Array (Array) Operation Skills", "Introduction to PHP Basic Grammar", "Summary of PHP Operation and Operator Usage", "Summary of php String (string) Usage", "Introduction to php+mysql Database Operation Skills" and "Summary of php Common Database Operation Skills"
I hope this article is helpful to everyone's PHP programming.