05 _ factory mode, 05 factory Mode
Factory Model
1. Simple Factory: another class or object is usually used to encapsulate the instantiation operation.
2. Factory mode: The real factory mode is to define an abstract factory method and postpone the Instantiation to the subclass! (Interfaces play a key role !)
Here is a simple example to illustrate how to use the factory model: Suppose you need to open several Pizza stores. Each Pizza store has several different types of Pizza for customers to choose from. The initial code may be as follows.
Version 1: No design pattern is used: every time you add a new type of pizza, you have to modify the pizzaStore Code, although its work content has not changed (pizzaStore is only responsible for ordering pizza, is not responsible for creating pizza ). This is obviously unreasonable.
<Script type = "text/javascript" src = "00_Interface.js"> </script>
<Script type = "text/javascript">
/**
* Define the Pizza interface. Each Pizza has the following methods: "prepare", "bake", and "pack ".
* @ Type {Interface}
*/
Var Pizza = new Interface ("Pizza", ["prepare", "bake", "box"]);
/**
* Three different Pizza types are implemented respectively.
* @ Constructor
*/
Function CheesePizza (){
}
CheesePizza. prototype = {
Constructor: CheesePizza,
Prepare: function (){
// Implement the prepare method
}, Bake: function (){
// Bake Implementation Method
}, Box: function (){
// Implement the box method
}
}
Function CornPizza (){
}
CornPizza. prototype = {
Constructor: CornPizza,
Prepare: function (){
// Implement the prepare method
}, Bake: function (){
// Bake Implementation Method
}, Box: function (){
// Implement the box method
}
}
Function PorkPizza (){
}
PorkPizza. prototype = {
Constructor: PorkPizza,
Prepare: function (){
// Implement the prepare method
}, Bake: function (){
// Bake Implementation Method
}, Box: function (){
// Implement the box method
}
}
/***
* Pizza store implementation class
* @ Type {orderPizza: Function }}
*/
Var pizzaStore = {
OrderPizza: function (type ){
Var pizza;
If (type = "cheese "){
Pizza = new CheesePizza ();
} Else if (type = "corn "){
Pizza = new CornPizza ();
} Else if (type = "pork "){
Pizza = new PorkPizza ();
}
Interface. ensureImplements (pizza, [Pizza]);
Pizza. prepare (); // prepare
Pizza. bake (); // bake
Pizza. box (); // boxed
Return pizza;
}
}
// Var pizza = pizzaStore. orderPizza ("cheese ");
Var pizza = pizzaStore. orderPizza ("pork ");
Alert (pizza. constructor );
</Script>
Version 2: Use a simple factory: extract the code for creating pizza to a simple factory. This factory object is only responsible for creating pizza, at the same time, you do not need to modify the pizzaStore class when adding new varieties.
1. Add the factory object for creating pizza
// Create a simple factory for pizza
Var PizzaFactory = {
CreatePizza: function (type ){
Var pizza;
If (type = "cheese "){
Pizza = new CheesePizza ();
} Else if (type = "corn "){
Pizza = new CornPizza ();
} Else if (type = "pork "){
Pizza = new PorkPizza ();
}
Interface. ensureImplements (pizza, [Pizza]);
Return pizza;
}
}
2. Use this factory object in pizzaStore to create
Var pizzaStore = {
OrderPizza: function (type ){
Var pizza = PizzaFactory. createPizza (type );
Pizza. prepare (); // prepare
Pizza. bake (); // bake
Pizza. box (); // boxed
Return pizza;
}
}
3. The remaining parts remain unchanged.
Version 3: Use a real factory model: the difference between a real factory model and a simple factory is that it uses a subclass instead of an object or class to create an instance. According to the formal definition: The Factory is a class that delays the instantiation of its member objects to the subclass.
<Script type = "text/javascript" src = "00_Interface.js"> </script>
<Script type = "text/javascript">
/**
* Define the Pizza interface. Each Pizza has the following methods: "prepare", "bake", and "pack ".
* @ Type {Interface}
*/
Var Pizza = new Interface ("Pizza", ["prepare", "bake", "box"]);
// Assume that your pizza store has two branches located in three different regions, producing the local taste of pizza respectively.
// Define an abstract base class, PizzaStore
Var PizzaStore = function (){
};
PizzaStore. prototype = {
Constructor: PizzaStore,
OrderPizza: function (type ){
Var pizza = this. createPizza (type );
Pizza. prepare ();
Pizza. bake ();
Pizza. box ();
Return pizza;
}, CreatePizza: function (type ){
Throw new Error ("this method is not implemented in the abstract class. It is implemented in a specific subclass! ");
}
}
// Hunan Branch: spicy taste
Function HuNanPizzaStore (){
PizzaStore. call (this, arguments );
}
;
// Inherit the base class
HuNanPizzaStore. prototype = new PizzaStore ();
HuNanPizzaStore. prototype. constructor = HuNanPizzaStore;
HuNanPizzaStore. prototype. createPizza = function (type ){
Var pizza;
If (type = "greenPepper "){
Pizza = new GreenPepperPizza (); // the implementation of the specific Pizza class is omitted...
} Else if (type = "redPepper "){
Pizza = new RedPepperPizza (); // the implementation of the specific Pizza class is omitted...
}
Interface. ensureImplements (pizza, [Pizza]);
Return pizza;
}
// Shanghai Branch, sweet
Function ShangHaiPizzaStore (){
PizzaStore. call (this, arguments );
}
ShangHaiPizzaStore. prototype = new PizzaStore ();
ShangHaiPizzaStore. prototype = {
Constructor: ShangHaiPizzaStore,
CreatePizza: function (type ){
Var pizza;
If (type = "tomato "){
Pizza = new TomatoPizza (); // the implementation of the specific Pizza class is omitted...
} Else if (type = "pineapple "){
Pizza = new PineapplePizza (); // the implementation of the specific Pizza class is omitted...
}
Interface. ensureImplements (pizza, [Pizza]);
Return pizza;
}
}
// Use
Var pizzaStore;
PizzaStore = new HuNanPizzaStore ();
PizzaStore. orderPizza ("greenPepper"); // order green pepper pizza from Hunan Branch
PizzaStore = new ShangHaiPizzaStore ();
PizzaStore. orderPizza ("pineapple"); // order pineapple pizza from Shanghai Branch
</Script>
After using the real factory model, it is very easy to add other branches. You only need to add a PizzaStore subclass and implement its createPizza method, which will not affect other classes! You can also modify each subclass to add pizza for different ingredients. This is the most important feature of the factory model. General operations on pizza can be placed in the abstract parent class PizzaStore, while other specific implementations are implemented in the corresponding subclass!
Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.