Factory pattern is a design pattern used to create objects. We do not expose the logic of object creation, but encapsulate the logic in a function, so this function can become a factory. Factory patterns can be divided into: 1 Simple factory 2 Factory method 3 Abstract factory
Simple factory
Simple factory pattern is very easy to understand. It belongs to class creation pattern, also known as static factory method pattern. A factory class is specially defined to be responsible for creating instances of other classes. The created instances usually have a common parent class, that is, all the created examples are instantiated by this constructor
function bookShop () { var book = new Object(); book.price = 'No price'; if (name === 'JS programming') { book.price = '10'; book.bookFunctio=()=>{} } if (name === 'vue.3.0') { book.price = '20'; book.bookFunctio=()=>{} } if (name === 'Big data visualization') { book.price = '30'; book.bookFunctio=()=>{} } return book; } var book1 = bookShop('JS programming'); var book2 = bookShop('vue.3.0'); var book3 = bookShop('Big data visualization');
The data obtained must be examples of bookShop construction. There are different price s and different functions in the examples. This is the simple factory mode and the most basic factory mode
advantage:
The factory class contains the necessary logical judgment to decide when to create an instance of which product. The client can be exempted from the responsibility of directly creating product objects, and it is very convenient to create corresponding products. The responsibilities of factories and products are clearly distinguished.
The client does not need to know the class name of the specific product created, but only needs to know the parameters.
You can also import configuration files to replace and add new specific product classes without modifying the client code.
Disadvantages:
The factory class of simple factory mode is single, which is responsible for the creation of all products. The responsibility is too heavy. Once it is abnormal, the whole system will be affected. Moreover, the factory class code will be very bloated and violate the principle of high aggregation.
Using simple factory mode will increase the number of classes in the system (introducing new factory classes), and increase the complexity and understanding difficulty of the system
It is difficult to expand the system. Once new products are added, the factory logic has to be modified. When there are many product types, the logic may be too complex. The simple factory mode uses the static factory method, resulting in the failure of the factory role to form a hierarchical structure based on inheritance.
Factory method model
In the factory method mode, the core factory class is no longer responsible for the creation of all products, but to hand over the specific creation work to the child factory. This is not very clear in some online examples. In the universal programming language, the core of this is inheritance. The child factory inherits the attributes of the parent factory and instantiates the child factory when instantiating, The generated instances are also instances of different child factories, but the class in the front end is actually a syntax sugar, and we can also write according to inheritance. But what I see is that we can put the child factory on the prototype, so that when the factory produces objects, it is ostensibly generated from the parent factory. There is no need to repeat what is related to the prototype chain of prototype
var BookShop = function (name) { // If BookShop is called directly from the outside instead of the new keyword call, the new BookShop call will be returned; otherwise, it will be called directly // Create an instance of this product class and return it to the outside //if (this instanceof BookShop) { var bookObj = new this[name]() return bookObj // } else { // return new BookShop(name) // } } BookShop.prototype = { Programme: function () { this.books = ['css world', 'JS Advanced programming', 'ES6 Introductory tutorial'] }, //Science: function () { // this.books = ['man and nature', 'mystery of nature', 'entering science'] //}, //Society: function () { // this.books = ['spiritual guy cultivation manual', 'flower shaking hand', 'Doudou shoes'] //} } var programme = new BookShop('programme'); //var science = BookShop('science'); //var society = BookShop('society');
If BookShop is called directly from the outside instead of the new keyword call, the new BookShop call will be returned. Otherwise, it will be called directly. This sentence has nothing to do with the factory method mode. It is mainly compatible with the instantiation of the factory and does not use the new keyword. I have commented out the repetition or the place that has nothing to do with the factory method mode itself, and only look at the simplest
1. Mounting of sub factory,
2. The parent factory creates instances by using different child factories by receiving parameters, and obtains instances created by different constructors. This is the factory method mode. new is the same constructor, but not the same instance
advantage:
Advantages of factory method
The multi-level products associated in the product family can be managed together within the class, instead of introducing multiple new classes for management.
When a product family is needed, the abstract factory can ensure that the client always uses only the product group of the same product.
Abstract factory enhances the scalability of the program. When adding a new product family, there is no need to modify the original code to meet the opening and closing principle.
shortcoming
When a new product needs to be added to the product family, all factory classes need to be modified. It increases the abstraction and understanding difficulty of the system.
Abstract factory pattern
Abstract factory pattern is relatively complex. If you want to understand abstract factory pattern, you must know what abstract classes are
abstract class
- What is an abstract class is to call an undefined method in the parent class, which must be implemented in the subclass.
- What is an abstract method? It is a method that has been defined but not implemented. People with computer foundation will know that there are interfaces in c + + and java, which are similar
Object.extend = function(des,source){ for(p in source){ des[p] = source[p]; } return des; }; Object.prototype.extend = function(object){ return Object.extend.apply(this,[this,object]); }; function BaseClass(){}; BaseClass.prototype = { initialize:function(name,age){ this.name = name; this.age = age;//An abstract method was called this.oninit(); }, //An abstract method is an empty method implemented by a derived class oninit:function(){} }; function ClassA(){}; ClassA.prototype = (new BaseClass()).extend({ oninit:function(){ alert(this.name + ' : ' + this.age); } }); var obj = new ClassA(); obj.initialize('Tom',22);
If the subclass is not an abstract class, the abstract method of the abstract parent class must be rewritten in the subclass. In short, no matter what it is, I will define it first. Whoever wants to inherit will implement this method
Abstract factory
- The core problem is inheritance. The ability of abstract factories lies in different factories to inherit Abstract factories
let agency = function(subType, superType) { //Determine whether the abstract class exists in the abstract factory if(typeof agency[superType] === 'function') { function F() {}; //Inherit parent class properties and methods F.prototype = new agency[superType] (); //Point the constructor of the subclass to the subclass subType.constructor = subType; //The subclass prototype inherits the parent class subType.prototype = new F(); } else { throw new Error('Abstract class does not exist!') } }
As above: the ability to inherit abstract classes is called abstract factory
The code is also easy to understand. Generally speaking, mount all the skills of the parent class to the prototype of an empty class, then point the constructor of the subclass to the subclass, and then mount the skills of the empty class to the subclass, so that the subclass can learn the skills of the parent class from the parent class
agency.mouseShop = function() { this.type = 'mouse'; } agency.mouseShop.prototype = { getName: function() { return new Error('Abstract methods cannot be called'); } }
As above: create an abstract class and wait for inheritance
function mouse(name) { this.name = name; this.item = ['Buy me, my thread is long',"Play games, thief slip"] } //Abstract factory implements mouse class inheritance agency(mouse, 'mouseShop'); //Override abstract methods in subclasses mouse.prototype.getName = function() { return this.name; }
As above: ordinary classes inherit Abstract subclasses and override the methods of abstract subclasses
//Instantiate a common class let mouseA = new mouse('association'); console.log(mouseA.getName(), mouseA.type); //Lenovo mouse
Above: instantiate a common class and use the methods and properties of the class
Summary:
1. The first two factories look very simple, but the abstract factory concept may be difficult for some people to understand. In fact, a simple example can not see the convenience of the factory, but let's imagine that if there are many similarities, or many kinds of factories, there are many similarities, then the necessity of a general factory comes out, Multiple ordinary classes can be written more easily, because their commonalities have been named and defined in the sub abstract classes. After inheritance, we can just focus on our own logic and code
2. This is a kind of thinking, not a copy of the development mode. The thinking of the factory is very useful in some situations, especially in the more complex and cumbersome places, which can make our development logic clearer and better analyze the code logic. It is not always suitable to use the factory mode. Teach students according to their aptitude according to local conditions