工厂模式是一种创建型设计模式,它的目的是负责实例化大量有共同接口的类,而且也不需要事先知道需要实例的类是什么。由子类来决定实例化哪一个类。
工厂模式分为三种:
1.简单工厂模式。
2.工厂方法模式。
3.抽象工厂方法模式。
简单工厂模式
简单工厂模式一般包括以下几个角色:
1.工厂: 由一个具体的类实现,内部含有一定的逻辑判断。
2.抽象产品: 由一个接口或者抽象类实现,使具体产品得到扩展。
3.具体产品: 有一个具体的类实现,为工厂最终生成的实例化对象。
简单工厂模式的核心思想就是:有一个专门的类来负责创建实例的过程。
package Factorys;//抽象产品interface abstractProduct{ public void doSomething();}//具体产品Aclass ProductA implements abstractProduct{ public void doSomething(){ System.out.println("I am A"); }}//具体产品Bclass ProductB implements abstractProduct{ public void doSomething(){ System.out.println("I am B"); }}//工厂class Factory{ public static abstractProduct createProduct(String type) throws InstantiationException, IllegalAccessException, ClassNotFoundException{ if(type != null){ //使用反射机制生成实例。 return (abstractProduct) Class.forName(type).newInstance(); } return null; }}//结果输出public class simpleFactoryPattern { public static void main(String args[]) throws InstantiationException, IllegalAccessException, ClassNotFoundException{ Factory.createProduct("Factorys.ProductA").doSomething(); Factory.createProduct("Factorys.ProductB").doSomething(); }}
输出结果
I am AI am B
如果具体产品之间含有相同的逻辑,那么我们可以使用一个抽象类来抽象出它们,如果没有,那么我们则用一个接口来扮演这个抽象类,它们也可以一层层的抽象下去,不断的扩展开来。工厂的作用是来实例化各种类对象。只需要根据客户端传入的参数再利用反射机制进行生产即可。
但是考虑一个问题,如果不同的产品的构造条件不同,需要加载的配置信息都不同,那么一个工厂类可以满足需求么,即使在工厂类里面加入大量的逻辑判断语句,来完成不同产品需要的不同的构造条件。当产品种类非常多的时候,那么大量逻辑条件的混杂在一起。可想而知代码会变的多么的可怕。
工厂方法模式
工厂方法模式一般包括以下几个角色:
1.抽象工厂: 由一个接口或者抽象类实现,使具体工厂可以得到扩展,并满足不同产品的需求。
2.工厂: 由一个具体的类实现,内部含有一定的逻辑判断。
3.抽象产品: 由一个接口或者抽象类实现,使具体产品得到扩展。
4.具体产品: 由一个具体的类实现,为工厂最终生成的实例化对象。
工厂方法模式是简单工厂模式的延伸,它继承了简单工厂模式的优点,同时还弥补了简单工厂模式的不足。当一个工厂不能满足需求的时候,当然就需要更多的工厂啦。
package Factorys;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;//抽象工厂interface abstractFactory{}//具体工厂Aclass FactoryA implements abstractFactory{ public static abstractProduct createProduct(String type) throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{ if(type != null){ //使用反射机制生成实例。 Class c = Class.forName(type); //使用Constructor 调用带参构造函数 Constructor constructor=c.getDeclaredConstructor(new Class[]{String.class}); constructor.setAccessible(true); return (abstractProduct) constructor.newInstance(new Object[]{"AAAAAA, "}); } return null; }}//具体工厂Bclass FactoryB implements abstractFactory{ public static abstractProduct createProduct(String type) throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{ if(type != null){ //使用反射机制生成实例。 Class c = Class.forName(type); //使用Constructor 调用带参构造函数 Constructor constructor=c.getDeclaredConstructor(new Class[]{String.class}); constructor.setAccessible(true); return (abstractProduct) constructor.newInstance(new Object[]{"BBBBBB, "}); } return null; }}//抽象产品interface abstractProduct{ public void doSomething();}//具体产品Aclass ProductA implements abstractProduct{ private String string; private ProductA(String string){ this.string = string; } public void doSomething(){ System.out.println(string + "I am A"); }}//具体产品Bclass ProductB implements abstractProduct{ private String string; private ProductB(String string){ this.string = string; } public void doSomething(){ System.out.println(string + "I am B"); }}public class factoryMethodPattern { public static void main(String args[]) throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{ FactoryA.createProduct("Factorys.ProductA").doSomething(); FactoryB.createProduct("Factorys.ProductB").doSomething(); }}
输出结果
AAAAAA, I am ABBBBBB, I am B
在工厂方法模式中,我们定义了一个抽象工厂类作为核心取代了简单工厂模式中的单个具体实现类。我们可以扩展出不同的工厂来配置出需求不同的产品,满足不同的产品。当然,过多的产品时,我们不需要为每一个都配置一个工厂实现类,可以结合简单工厂模式,为构造信息相同的一类产品分配一个工厂类即可。
抽象工厂模式
抽象工厂模式一般包括以下几个角色(和工厂方法模式的角色基本相同):
1.抽象工厂: 由一个接口或者抽象类实现,使具体工厂可以得到扩展,并满足不同产品的需求。
2.工厂: 由一个具体的类实现,内部含有一定的逻辑判断。
3.抽象产品: 由一个接口或者抽象类实现,使具体产品得到扩展。
4.具体产品: 由一个具体的类实现,为工厂最终生成的实例化对象。
抽象工厂模式主要解决的问题是,存在一批相关的产品,它们属于同一个集合,但是它们的构造函数却不相同,我们希望它们能够在一个工厂中生产出来,而不是为这一批产品中的每一个产品分配一个工厂。将这样一批的产品称为产品族。
package Factorys;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;//抽象产品族Ainterface abstractProductA{ public void doSomething();} //产品族A具体产品A1class ProductA1 implements abstractProductA{ private String string; private ProductA1(String string){ this.string = string; } public void doSomething(){ System.out.println(string + "I am A1"); }}//产品族A具体产品A2class ProductA2 implements abstractProductA{ private String string; private ProductA2(String string){ this.string = string; } public void doSomething(){ System.out.println(string + "I am A2"); }}//抽象产品族Binterface abstractProductB{ public void doSomething();} //产品族B具体产品B1class ProductB1 implements abstractProductB{ private String string; private ProductB1(String string){ this.string = string; } public void doSomething(){ System.out.println(string + "I am B1"); }} //产品族B具体产品B2class ProductB2 implements abstractProductB{ private String string; private ProductB2(String string){ this.string = string; } public void doSomething(){ System.out.println(string + "I am B2"); }} interface AbstractFactory { } class FactoryA implements AbstractFactory{ public static abstractProductA createProductA1(String type) throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{ if(type != null){ //使用反射机制生成实例。 Class c = Class.forName(type); //使用Constructor 调用带参构造函数 Constructor constructor=c.getDeclaredConstructor(new Class[]{String.class}); constructor.setAccessible(true); return (abstractProductA) constructor.newInstance(new Object[]{"A产品族, "}); } return null; } public static abstractProductA createProductA2(String type) throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{ if(type != null){ //使用反射机制生成实例。 Class c = Class.forName(type); //使用Constructor 调用带参构造函数 Constructor constructor=c.getDeclaredConstructor(new Class[]{String.class}); constructor.setAccessible(true); return (abstractProductA) constructor.newInstance(new Object[]{"A产品族, "}); } return null; }}class FactoryB implements AbstractFactory{ public static abstractProductB createProductB1(String type) throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{ if(type != null){ //使用反射机制生成实例。 Class c = Class.forName(type); //使用Constructor 调用带参构造函数 Constructor constructor=c.getDeclaredConstructor(new Class[]{String.class}); constructor.setAccessible(true); return (abstractProductB) constructor.newInstance(new Object[]{"B产品族, "}); } return null; } public static abstractProductB createProductB2(String type) throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{ if(type != null){ //使用反射机制生成实例。 Class c = Class.forName(type); //使用Constructor 调用带参构造函数 Constructor constructor=c.getDeclaredConstructor(new Class[]{String.class}); constructor.setAccessible(true); return (abstractProductB) constructor.newInstance(new Object[]{"B产品族, "}); } return null; }}public class abstractFactoryPattern { public static void main(String args[]) throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{ FactoryA.createProductA1("Factorys.ProductA1").doSomething(); FactoryA.createProductA2("Factorys.ProductA2").doSomething(); FactoryB.createProductB1("Factorys.ProductB1").doSomething(); FactoryB.createProductB2("Factorys.ProductB2").doSomething(); } }
输出结果
A产品族, I am A1A产品族, I am A2B产品族, I am B1B产品族, I am B2
抽象工厂模式只需要为每一个产品族分配一个工厂,然后再在每一个工厂中定义不同产品的生产方式。在只有一个产品族的情况下,抽象工厂模式实际上退化到工厂方法模式。而再只需要一个工厂的情况下,工厂方法模式即为简单工厂模式