I. Introduction
At 2:30 midnight, I want to fly to the sky and wait side by side with the sun!!!
Xiaobian once heard such a sentence in his work: "You can't write a factory."
Factory pattern is one of the most commonly used creating design patterns in Java, which provides the best way to create objects. The client will not expose the details of creation when calling, just call the method of the factory class to specify the object to be created.
II. Simple factories
Introduction: Simple factory is not strictly one of 23 design modes, but simple factory is the simplest way to use it.
Disadvantage: The responsibility of the factory class is too heavy. If new products are added, the logic of the factory needs to be modified and the principle of opening and closing violated (the principle of opening and closing violated here can also adopt the mechanism of reflection to meet the principle of opening and closing to a certain extent).
Requirements: Now you need to create video tutorials that record various types of videos, such as java, python, and so on. The code is as follows:
Step 1: Define an abstract product class, which takes abstraction as the underlying architecture. It is often more stable, and at the same time, it has formulated specifications.
/** * @Auther: IT Cheap man * @Date: 2019/9/5 09:51 * @Description: Abstract products */ public abstract class Video { /** * record video */ public abstract void recording(); }
Step 2: Different product classes implement different interfaces
/** * @Auther: IT Cheap man * @Date: 2019/9/5 09:53 * @Description: python Video products */ public class PythonVideo extends Video { @Override public void recording() { System.out.println("Recording in progress python Video Course"); } }
/** * @Auther: IT Cheap man * @Date: 2019/9/5 09:52 * @Description: java Video products */ public class JavaVideo extends Video { @Override public void recording() { System.out.println("Recording in progress java Video Course"); } }
Step 3: Implement the Video Factory class and provide a way to obtain different product objects
/** * @Auther: IT Cheap man * @Date: 2019/9/5 09:54 * @Description: Video Factory, Producing Different Video Objects */ public class VideoFactory { /** * Getting different video objects through the factory * * If you add a PHP video course, you need to modify the factory, which violates the open-close principle. * * @param type Video type * @return Video object */ public static Video getVideo(String type) { if ("java".equals(type)) { return new JavaVideo(); } if ("python".equals(type)) { return new PythonVideo(); } return null; } /** * Obtaining different video objects through factory reflection mechanism * * By reflection, even if new products are added, there is no need to modify the factory. * * @param t Video object type * @return Video object */ public static Video getVideo(Class t) { try { return (Video) Class.forName(t.getName()).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return null; } }
Step 4: Client calls
/** * @Auther: IT Cheap man * @Date: 2019/9/5 09:57 * @Description: Customer Call Class */ public class Client { public static void main(String[] args) { // Obtaining objects by type Video java = VideoFactory.getVideo("java"); java.recording(); // Obtaining objects by reflection Video python = VideoFactory.getVideo(PythonVideo.class); python.recording(); } }
III. Factory Method
Introduction: On the basis of simple factories, we will evolve the factory method. Simply speaking, the factory method is to defer the instantiation of classes to factory subclasses.
Advantages: Similar to simple factories, users only need to care about the factories corresponding to the products, not about the details of creating the products. But simple factories violate the principle of opening and closing, and the factory method solves this problem well. Because the instantiation of objects is deferred to the subclasses of factories, it conforms to the open-close principle and improves scalability.
Disadvantage: This is also obvious. If a new product needs to create a product object and a factory for the corresponding product, the number of classes will easily increase and the complexity will increase.
Implementation steps: first create abstract factory class, then create java factory, python factory and implement abstract factory respectively. From the code point of view, the instantiation of each video object is implemented in various corresponding factory classes.
/** * @Auther: IT Cheap man * @Date: 2019/8/8 16:50 * @Description: Abstract factory */ public abstract class VideoFactory { /** * Creating Video Objects * @return */ public abstract Video createVideo(); }
/** * @Auther: IT Cheap man * @Date: 2019/8/8 16:51 * @Description: java Realize factories concretely */ public class JavaVideoFactory extends VideoFactory { @Override public Video createVideo() { return new JavaVideo(); } }
/** * @Auther: IT Cheap man * @Date: 2019/8/8 16:51 * @Description: python Realize factories concretely */ public class PythonVideoFactory extends VideoFactory { @Override public Video createVideo() { return new PythonVideo(); } }
/** * @Auther: IT Cheap man * @Date: 2019/8/8 16:52 * @Description: Client Call */ public class Test { public static void main(String[] args) { // Users only need to find the corresponding video factory, then they can create the corresponding video object. VideoFactory factory = new JavaVideoFactory(); Video videl = factory.createVideo(); videl.recording(); } }
IV. ABSTRACT FACTORY
Simple factories and factory methods have a common feature, that is, they only create a single product, they can only create a video object.
Now the demand has changed. A java course not only needs to include video, but also handwriting (notes), that is to say, Video + handwriting, two together is a complete product. In other words, video and handwriting are the same product family.
Simple factories and factory methods can not meet the demand, so they continue to evolve into abstract factories.
Introduction: The abstract factory pattern provides a set of product object interfaces to create a series of related or interdependent products. The biggest difference between the abstract factory pattern and other factory patterns is that the abstract factory is the object to create a series of related products.
Advantages: No need to care about the details of the creation, a series of products will be unified together to create.
Disadvantage: It is difficult for product family to extend new products. It is necessary to modify the definition of abstract factory, and it also increases the difficulty of abstraction and understanding of the system.
Step 1: On the basis of the above, we first need to create a definition of the handwritten product, as well as the corresponding implementation class.
/** * @Auther: IT Cheap man * @Date: 2019/8/9 09:58 * @Description: Notes */ public abstract class Notes { /** * Writing Handwriting */ public abstract void write(); }
/** * @Auther: IT Cheap man * @Date: 2019/8/9 10:39 * @Description: java Notes */ public class JavaNotes extends Notes { @Override public void write() { System.out.println("write java Notes");} }
/** * @Auther: IT Cheap man * @Date: 2019/8/9 10:43 * @Description: python Notes */ public class PythonNotes extends Notes { @Override public void write() { System.out.println("write python Notes");} }
Step 2: Define Abstract factories, and provide a method to create multiple products. Then, there are corresponding classes of course factories to implement the method separately.
/** * @Auther: IT Cheap man * @Date: 2019/8/9 10:01 * @Description: Abstract factory */ public interface CurriculumFactory { /** * Create Video * @return */ Video getVideo(); /** * Create Handwriting * @return */ Notes getNotes(); }
/** * @Auther: IT Cheap man * @Date: 2019/8/9 10:44 * @Description: python Factory Category */ public class PythonFactory implements CurriculumFactory { @Override public Video getVideo() { return new PythonVideo(); } @Override public Notes getNotes() { return new PythonNotes(); } }
/** * @Auther: IT Cheap man * @Date: 2019/8/9 10:39 * @Description: java Factory Category */ public class JavaFactory implements CurriculumFactory { @Override public Video getVideo() { return new JavaVideo(); } @Override public Notes getNotes() { return new JavaNotes(); } }
/** * @Auther: IT Cheap man * @Date: 2019/8/9 10:41 * @Description: Client Class */ public class Test { public static void main(String[] args) { // Users only need to be clear about the corresponding video factory, then they can obtain a series of products corresponding to the product family. CurriculumFactory factory = new PythonFactory(); Notes notes = factory.getNotes(); Video video = factory.getVideo(); notes.write(); video.recording(); } }