When it comes to factories and assembly lines, the work is repeated over and over again. It is really harder than us coders.
The factory pattern is also used very frequently. Its official explanation is: define an interface for creating objects and let the subclass decide which class to instantiate. The factory pattern defers instantiation of a class to its subclasses.
As shown in the figure, there are two types of super users and ordinary users in the system. Define a public interface User class and define a public abstract factory class abstractUserFactory. The userFactory class implements the method createUser to create the User class by inheriting the abstractUserFactory class. , thereby realizing the factory mode, the implementation code is as follows:
Php code
<?php abstract class abstractUserFactory { public abstract function createUser(); } class userFactory extends <span style="font-size: 1em; line-height: 1.5;">abstractUserFactory </span><span style="font-size: 1em; line-height: 1.5;">{</span> Php代码 public function createUser( $className ) { try{ if(class_exists($className)) return new $className(); else{ $error = "no class"; throw new Exception($error); } }catch( Exception $e ) { echo 'Caught exception: ', $e->getMessage(), "\n"; } } } interface User{ public function getGrade(); } class superUser implements User{ public function getGrade() { echo 1; } } class commonUser implements User{ public function getGrade() { echo 0; } } $userFactory = new userFactory(); $userFactory->createUser( 'superUser' )->getGrade(); $userFactory->createUser( 'commonUser' )->getGrade(); 运行结果:10Caught exception: no class
Advantages of the factory mode:
1. Good encapsulation and clear code structure. The creation of an object is conditionally constrained. For example, if a caller needs a specific product object, he only needs to know the class name (or constraint string) of the product. There is no need to know the arduous process of creating an object, which reduces the coupling between modules. .
2. Very good scalability. In the case of adding product categories, "embracing change" can be completed by appropriately modifying the specific factory class or extending a factory class. For example, in the above example, if you need to add a blue diamond user, you only need to add a blueUser class. The factory class can complete system expansion without modifying tasks.
3. Shielding product categories. This feature is very important. The caller does not need to care about how the implementation of the product class changes. It only needs to care about the interface of the product. As long as the interface remains unchanged, the upper modules in the system should not change.
4. Typical decoupling framework. The high-level module value needs to know the abstract class of the product, and other implementation classes do not need to be concerned. It is in line with Dimit's law. I don't need to communicate if I don't need it. It is also in line with the dependency inversion principle. It only relies on the abstraction of the product class. Of course, it is also in line with According to the substitution principle, use product subclasses to replace product parent classes, no problem!
Usage scenarios of factory pattern:
1. Factory pattern is a replacement for new object, so it can be used wherever objects need to be generated, but you need to carefully consider whether to add a factory class for management and add code complexity.
2. When you need a flexible and extensible framework, you can consider using the factory pattern. Everything is an object, and everything is a product.
3. Factory pattern can be used in heterogeneous projects.
4. You can use the test-driven development framework. For example, to test a class A, you need to generate class B that is related to class A at the same time. We can use the factory pattern to virtualize class B to avoid the coupling between class A and class B. (Currently, Java has jmock and easymock, and this scenario has been weakened).
Extensions of factory pattern:
1. Simple factory pattern (commonly used in PHP)
A module only needs a factory class, there is no need to generate it, just use a static method. According to this Requirements, we modify the abstractUserFactory in the above example, as shown in the figure:
Remove the abstractUserFactory abstract class, and set createUser to a static class, which simplifies the class creation process. Its disadvantage is that it is difficult to extend the factory class and does not comply with the opening and closing principle, but it is still a very practical design pattern.
2. Upgrade to multiple factory classes (one-to-one between products and factories)
Each product class corresponds to a creation class. The advantage is that the responsibilities of the creation class are clear and the structure is simple, but it provides scalability and Maintainability has a certain impact. If you want to extend a product class, you need to create a corresponding factory class, which increases the difficulty of expansion. Because the number of factory classes and products is the same, the relationship between the two objects needs to be considered during maintenance.
Of course, in complex applications, the multi-factory method is generally used, and then a coordination class is added to prevent the caller from communicating with each sub-factory. The function of the coordination class is to encapsulate the sub-factory classes and provide a unified access interface to high-level modules. .
3. Alternative to singleton mode
This mode is implemented by instantiating a class that defines a private no-argument constructor through reflection. Visual inspection is not possible with PHP, so I will skip it here.
4. Delayed initialization
After an object is consumed, it is not released immediately. The factory class maintains its initial state, waiting to be used again. For the PHP interpreted language, it can be extended to lazy loading, that is, the corresponding class file is loaded only when the factory class is ready to create a new object, instead of loading possible classes every time the script is executed.