设计模式(二):工厂方法模式
一、概念简介
工厂方法模式同样属于类的创建型模式,也被称为多态工厂模式。它的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中去,核心工厂类不再负责产品的创建,成为了一个抽象工厂角色,仅仅负责具体工厂子类的必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引入新的产品。
(百度上找的类图,和car有关的)
二、实现与比较
昨天我们学习了简单工厂方法模式,今天我们又在学习工厂方法模式,那么这两种方法模式的区别在哪呢?各自又有啥长处和不足呢?现在我们将二者实现以下,对比一下它们的区别:
-
假设,在昨天的基础上,我们今天又要生产一种新的水果----橘子(Orange),那么昨天的类就要进行对应的修改:
-
1.创建Orange类,让它继承Fruit抽象类,并重写get方法
-
2.在FruitFactory工厂类添加生产Orange对象的逻辑
public static Fruit getFruit(Class cls) throws Exception{ if (Apple.class==cls){ return Apple.class.newInstance(); }else if (Banana.class==cls){ return Banana.class.newInstance(); }else if (Orange.class==cls){ //添加了Orange对象的创建逻辑判断 return Orange.class.newInstance(); }else { throw new Exception("创建水果实例失败"); } }
-
虽说只添加了一个Orange类和两行对象创建逻辑判断,但是,这与我们的开闭原则相违背,开闭原则的思想是:对拓展开放,对修改关闭。所以这时候我们的工厂方法模式就派上用场了
-
-
于是乎,我们再来用工厂方法来实现新需求
-
1.也是创建Orange类,和上面步骤1一样
-
2.将FruitFactory工厂类改造成接口,里面定义一个getFruit方法
public interface FruitFactory { Fruit getFruit();//定义方法 }
-
3.创建对应的AppleFactory,BananaFactory,OrangeFactory,让它们都实现FruitFactory工厂接口,并实现里面的getFruit方法
-
//Apple具体生产工厂类 public class AppleFactory implements FruitFactory { public Fruit getFruit(){ return new Apple(); } } //Banana具体生产工厂类 public class BananaFactory implements FruitFactory { public Fruit getFruit(){ return new Banana(); } } //Orange具体生产工厂类 public class OrangeFactory implements FruitFactory { @Override public Fruit getFruit() { return new Orange(); } }
main方法里进行测试
public static void main(String[] args) throws Exception { Fruit apple = getFruitByFactory("com.tys.facrotymethod.AppleFactory"); apple.get(); Fruit banana = getFruitByFactory("com.tys.facrotymethod.BananaFactory"); banana.get(); Fruit orange = getFruitByFactory("com.tys.facrotymethod.OrangeFactory"); orange.get(); } //用反射提取出获得水果实例的方法 public static Fruit getFruitByFactory(String className) throws Exception{ Class<?> cls = Class.forName(className); if (cls==AppleFactory.class){ return AppleFactory.class.newInstance().getFruit(); }else if(cls==BananaFactory.class){ return BananaFactory.class.newInstance().getFruit(); }else if(cls==OrangeFactory.class){ return OrangeFactory.class.newInstance().getFruit(); }else{ throw new Exception("创建水果实例失败"); } }
-
-
通过上面两种方法模式实现的比较,我们可以发现,工厂模式是弥补了简单工厂方法模式的拓展性不足的缺点,当有新水果品种需要生产时,它不必去修改原有的工厂类,只需要添加OrangeFactory这样一个具体生产工厂就行(当然创建Orange水果类都是必不可少的),从而满足开发封闭----对拓展开发,对修改关闭。
三、总结
其实所以设计模式都各有所长,也各有所短,虽然工厂模式看上去像是蛮不错的,但是我们也可以发现,它实际上比简单工厂方法模式要复杂一下,并不是说它的实现原理有多复杂,而是它为了实现拓展性----增加了AppleFactory,BananaFactory,OrangeFactory三个具体工厂类,而简单工厂模式则是不需要的,若是后面还有源源不断的新水果需要生产,比如:梨子(Pear),西红柿(Tomato),菠萝(Pineapple)等等,那么我们必须创建对应的水果工厂具体实现类,想想都头疼。。。
总得来说,让我自己来概括一下这两种设计模式,我会酱紫说:
- 简单工厂模式就好比于程序员在小型IT公司工作,它分工不细致,要求你最好啥都能干,你一个人可能要做前端、测试、后端等等
- 工厂方法模式就好比与在BAT这种大厂工作,它分工十分细致,要求你在一个岗位上拧螺丝,你做后端就只做后端,绝不让你碰前端