Java Design Pattern -- factory pattern, java design pattern --
The so-called factory is to build products, such as a small brick factory, there is only one kiln, both bricks and tiles can be made, this is called a simple factory model. The scale is a little bigger. I have multiple kiln, some of which are specially made bricKs, some of which are specially made tiles, and I want to make others, such as ceramic tiles. I will use a special kiln, this has become the factory method model. But if I open a car assembly plant that requires both tires, engines, frames, and other combinations, it is necessary to abstract the engineering model. Therefore, our factory model can be divided into three types: simple factory model, factory method model, and abstract factory model. First, a simple factory: You tell me what product you want. If I can produce this product, I will produce it for you. The simple factory model is also called the static factory model, because the products produced by the factory are fixed at the beginning, and the several products can be created. There is no way to create more products. The design principle is that new products do not need to modify the original code. It is like a brick-and-tile kiln that wants to produce porcelain. Even if you don't try again, you have to make a lot of internal changes. The following code example is a simple factory type that can produce mobile phones and only IPhone and Samsung mobile phones. If you want to produce a mobile phone, sorry, it cannot be produced at present. RuntimeException, you have to make it. If you continue to make judgments, it will be equivalent to changing the current factory class. Code:
Public class SimplePhoneFactory {public static Cellphone getCellphone (String type) {if ("iPhone ". equals (type) {return new IPhone ();} else if ("Samsung ". equals (type) {return new Samsung () ;}else {throw new RuntimeException ("Incorrect mobile phone type creation ");}}}
Factory method: The Factory method is based on a simple factory and can be expanded to manage factory production in a clearer way from the design idea. Segment the factory implementation of each product. In this mode, the above mobile phone Factory is a broad Factory (Interface), and then the specific implementation of each product factory. If you want to add a new product, add a new product implementation factory without modifying the original code. Code:
/* Factory method interface */public interface PhoneFactory {public Cellphone getPhone ();}
/** @ Description: iPhone factory */public class IPhoneFactory implements PhoneFactory {@ Overridepublic Cellphone getPhone () {// TODO Auto-generated method stubreturn new IPhone ();}}
/** @ Description: samsung factory */public class SamsungPhoneFactory implements PhoneFactory {@ Overridepublic Cellphone getPhone () {// TODO Auto-generated method stubreturn new Samsung ();}}
The code above shows that each product requires its own implementation factory. If we need to add new products, such as mobile phones, we only need to add a MIPhoneFactory to implement PhoneFactory.
Abstract Factory: at the beginning, we also talked about using abstract factory for combination products. That is to say, such factories are much more complicated than the other two. In fact, we can't compare abstract factories with simple factories because they are not used to solve the same type of problems, and there is basically no comparability. Abstract factories are used to target product families, while simple factory and factory methods are aimed at a single product. If abstract factories are used to manage a single product, nothing can be done. Here we also take cell phones as an example. We need many accessories to make cell phones, such as CPU, camera, memory, etc, for the time being, we only think that only these three components are used to determine whether a mobile phone is good or bad. Use Abstract Factory for implementation. First, we define the CPU interface and some CPU columns that can be produced. Here we use GoodCPU and BadCPU as examples:
Public interface CPU {void run (); void start () ;}// high-end CPUclass GoodCUP implements CPU {@ Overridepublic void run () {System. out. println ("high-end CPU running method... ") ;}@ Overridepublic void start () {System. out. println (" high-end CPU start method... ") ;}/// Low-end CPU class BadCPU implements CPU {@ Overridepublic void run () {System. out. println (" low-end CPU running method... ") ;}@ Overridepublic void start () {System. out. println (" low-end CPU start method... ");}}
Then there is the camera interface and the related camera production types, and the method is casually written.
Public interface Camera {public void take ();} class GoodCamera implements Camera {@ Overridepublic void take () {System. out. println ("high-end Camera photo... ") ;}} Class BadCamera implements Camera {@ Overridepublic void take () {System. out. println (" low-end Camera taking... ");}}
The last memory interface has a series of types:
Public interface Memory {void work ();} class GoodMemory implements Memory {@ Overridepublic void work () {System. out. println ("High-Performance Memory working");} class BadMemory implements Memory {@ Overridepublic void work () {System. out. println ("low-Performance Memory working ");}}
As we mentioned above, the abstract factory is the factory that uses some column components to combine products. The CPU, camera, and memory we wrote above are all components of our component mobile phone. Now, we start to write our abstract factory. Of course, for convenience, there must be a factory interface:
public interface AbPhoneFactory { CPU getCPU(); Camera getCamera(); Memory getMemory();}
Then, based on our own needs, we can randomly combine several components to get our products. Of course, this is the final product combined by a group of products.
For example, we combine good CPU, good memory, and good cameras into a good mobile phone:
public class GoodsPhoneFactory implements AbPhoneFactory{@Overridepublic CPU getCPU() {// TODO Auto-generated method stubreturn new GoodCUP();}@Overridepublic Camera getCamera() {// TODO Auto-generated method stubreturn new GoodCamera();}@Overridepublic Memory getMemory() {// TODO Auto-generated method stubreturn new GoodMemory();}}
You can also combine a poor CPU, memory, and camera into a poor mobile phone:
public class BadPhoneFactory implements AbPhoneFactory{@Overridepublic CPU getCPU() {// TODO Auto-generated method stubreturn new BadCPU();}@Overridepublic Camera getCamera() {// TODO Auto-generated method stubreturn new BadCamera();}@Overridepublic Memory getMemory() {// TODO Auto-generated method stubreturn new BadMemory();}}
Of course, you can also combine them into medium ones. This is all for your convenience. You just need to add a factory for implementation.
Finally, let's summarize:
For a single product, the simple factory is simpler, but the new product is weak, or does not comply with the design principles. The factory method adds the factory class implementation without modifying the original class, more in line with design principles. Is it time for us to select a factory method for a single product? The following is a comparison:
-- Simple structure complexity simple factory simpler Factory better than factory Method
-- Code complexity: The Factory method is more complex. The simple factory method is better than the factory method.
-- Client programming difficulty factory method client needs to know more about implementation factory simple factory is better than factory Method
-- Difficult to manage factory methods because there are many factory implementation methods, it is more difficult to manage simple factories than factory methods
In combination with the above four points, we say that simple factories are easier to use than factory methods. This is why simple factories are more used than factory methods during development.
For product families, if the factory mode is used, the only choice is abstract factory.
OK. For more code and test code, see github: https://github.com/liujishuai/designpatterns.