工厂模式
定义
工厂方法定义
Define an interface for creating an object,but let subclasses decide which class to instantiate.Factory Method lets a class defer instantiation to subclasses.
定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
抽象工厂定义
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
为创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类。
工厂模式种类
简单工厂(静态工厂)
工厂方法
多工厂方法
单例工厂
抽象工厂
工厂模式主要分为工厂方法模式和抽象工厂模式。其他的模式是工厂方法的延伸。
工厂模式的多个种类可以看作是一个升级路线: 简单工厂–>工厂方法–>多工厂方法–>抽象方法
简单方法是工厂类没有抽象工厂。不能进行扩展,并且创建方法是静态方法。
工厂方法是简单工厂的升级版,增加了抽象工厂类,创建方法也是成员方法。工厂方法只能生产一类的产品。
多工厂方法是工厂方法的升级版,多工厂方法能够生产多个种类的产品,但是每个种类的产品都需要创建一个匹配的工厂。
抽象工厂则是工厂方法的升级版,抽象工厂能将多个种类的产品放在一个工厂中生产。
工厂模式实现
现在我们需要创建尼安德特人,直立人和智人三个人种。
按照工厂模式,我们需要抽象人,具体人种,抽象工厂,具体工厂四个类。
使用简单工厂,不需要抽象工厂,直接通过具体工厂的静态方法生产出对应人种。
使用工厂方法,通过实现抽象工厂,为每个人种创建对应的工厂,每个工厂创建一个种类。
使用抽象方法,通过实现抽象工厂,为多个具有相同特征的人种建立一个工厂,创建一条生产线,直接生产出需要的人种族。
代码实现
产品准备
抽象出人出来
1 2 3 4 5 6 7 8 9 10 11 12 13 public interface Human { public void talk () ; public void useTools () ; public void walkOnTwoFeet () ; }
尼安德特人类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class HomoNeanderthalensis implements Human { @Override public void talk () { System.out.println("尼安德特人能说话" ); } @Override public void useTools () { System.out.println("尼安德特人能使用工具" ); } @Override public void walkOnTwoFeet () { System.out.println("尼安德特人能用两只脚走路" ); } }
直立人
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class HomoErectus implements Human { @Override public void talk () { System.out.println("直立人能说话" ); } @Override public void useTools () { System.out.println("直立人能使用工具" ); } @Override public void walkOnTwoFeet () { System.out.println("直立人能用两只脚走路" ); } }
智人
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class HomoSapiens implements Human { @Override public void talk () { System.out.println("智人能说话" ); } @Override public void useTools () { System.out.println("智人能使用工具" ); } @Override public void walkOnTwoFeet () { System.out.println("智人能用两只脚走路" ); } }
简单工厂
创建一个简单工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class SimpleFactory { public static <T extends Human> T createHuman (Class<T> c) { Human human = null ; try { human = (Human)Class.forName(c.getName()).newInstance(); } catch (Exception e) { System.out.println("人种生成错误" ); } return (T) human ; } }
工厂方法
创建一个抽象工厂
1 2 3 4 5 6 public abstract class AbstractHumanFactory { public abstract <T extends Human> T createHuman (Class<T> c) ; }
创建一个具体工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class MethodFactory extends AbstractHumanFactory { @Override public <T extends Human> T createHuman (Class<T> c) { Human human = null ; try { human = (Human) Class.forName(c.getName()).newInstance(); } catch (Exception e) { System.out.println("人种生成错误" ); } return (T) human ; } }
多工厂方法
创建一个抽象工厂
1 2 3 public abstract class AbstractHumanFactory1 { public abstract Human createHuman () ; }
为各个人种(产品)创建各自的工厂
直立人
1 2 3 4 5 6 public class HomoErectusFactory extends AbstractHumanFactory1 { @Override public Human createHuman () { return new HomoErectus(); } }
尼安德特人
1 2 3 4 5 6 public class HomoNeanderthalensisFactory extends AbstractHumanFactory1 { @Override public Human createHuman () { return new HomoNeanderthalensis(); } }
智人
1 2 3 4 5 6 public class HomoSapiensFactory extends AbstractHumanFactory1 { @Override public Human createHuman () { return new HomoSapiens(); } }
单例工厂
创建人
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class SingleTonHuman implements Human { private SingleTonHuman () { } @Override public void talk () { System.out.println("人能说话" ); } @Override public void useTools () { System.out.println("人能使用工具" ); } @Override public void walkOnTwoFeet () { System.out.println("人能用两只脚走路" ); } }
创建单例工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class SingleTonHumanFactory { private static SingleTonHuman singleTonHuman ; static { try { Class c = Class.forName(SingleTonHuman.class.getName()); Constructor constructor = c.getDeclaredConstructor(); constructor.setAccessible(true ); singleTonHuman = (SingleTonHuman)constructor.newInstance(); } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } } public SingleTonHuman getInstance () { return singleTonHuman ; } }
抽象工厂
创建一个抽象工厂,其中定义了一个产品族(生产线)
1 2 3 4 5 public interface AbstractFactory { public HomoSapiens createHomoSapiens () ; public HomoErectus createHomoErectus () ; public HomoNeanderthalensis createHomoNeanderthalensis () ; }
创建一个产品线工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class HumanFactory implements AbstractFactory { @Override public HomoSapiens createHomoSapiens () { return new HomoSapiens(); } @Override public HomoErectus createHomoErectus () { return new HomoErectus(); } @Override public HomoNeanderthalensis createHomoNeanderthalensis () { return new HomoNeanderthalensis(); } }
各个工厂的场景实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 public class App { public static void main (String[] args) { HumanFactory humanFactory = new HumanFactory(); HomoErectus homoErectus = humanFactory.createHomoErectus(); homoErectus.useTools(); homoErectus.talk(); homoErectus.walkOnTwoFeet(); HomoNeanderthalensis homoNeanderthalensis = humanFactory.createHomoNeanderthalensis(); homoNeanderthalensis.useTools(); homoNeanderthalensis.talk(); homoNeanderthalensis.walkOnTwoFeet(); HomoSapiens homoSapiens = humanFactory.createHomoSapiens(); homoSapiens.useTools(); homoSapiens.talk(); homoSapiens.walkOnTwoFeet(); } }
应用场景
工厂方法模式
工厂方法模式可以作为new一个对象的替代品。
工厂方法可以用在需要灵活的、可扩展框架的地方。
工厂方法也可以用在异构项目中。
可以用在驱动开发的框架下。
抽象工厂模式
对一个对象族都有相同的约束。
工厂模式优缺点
工厂方法模式优缺点
优点
良好的封装性,代码结构清晰。
工厂方法模式的扩展性很好。
可以屏蔽产品类,我们只需要让工厂帮我们生产产品就行了。
工厂方法是典型的解耦。
抽象工厂模式优缺点
优点
封装性,我们只需要关心接口就行了,不关心产品是怎样创建的,工厂帮我们创建。
产品族内的约束为非公开约束,我们不需要知道知道这个约束,我们只需要得到产品就可以了。
缺点
抽象工厂可以生产一个产品族,但是产品族的扩展很困难。