1.简单(静态)工厂模式
(本博客所有UML类图均转载自知乎https://zhuanlan.zhihu.com/p/37217085)
对UML类图不了解的同学看看这个:https://blog.csdn.net/u013870094/article/details/78826614
简单工厂模式用于根据外界的需求来生产相应的产品的这种情况,当需要一个产品的时候,用户只需要给参数(比如说名字)给工厂,工厂根据这个参数生产响应的产品来即可。
下面放一个完整的DEMO
package defaultPk; public class LearnFactoryDesign { static abstract class AbstractProduct{ //抽象产品 abstract public void getType(); } //产品都要继承自抽象产品类 static class ProductA extends AbstractProduct{ @Override public void getType() { System.out.println("我是A产品!"); } } static class ProductB extends AbstractProduct{ @Override public void getType() { System.out.println("我是B产品!"); } } //工厂类,用于生产产品 static class MyFactory{ public static AbstractProduct getProduct(String type){ if(type=="A")return new ProductA();//也可以用反射获取对象 if (type=="B")return new ProductB(); return null; } } public static void main(String[] args){ MyFactory.getProduct("A").getType(); MyFactory.getProduct("A").getType(); MyFactory.getProduct("B").getType(); MyFactory.getProduct("B").getType(); } }可知实现简单工厂模式要注意两点:
——要有个抽象产品类,产品都要继承于这个类
——要有个工厂类,它一般为一个静态类,在里面接收参数,生产产品。
简单工厂模式优缺点
优点:能动态生产所需要的产品实例
缺点:一旦这个工厂出了问题,所有的客户端都会受到牵连;违背了单一职责,导致系统丧失灵活性和可维护性。简单工厂模式违背了“开放封闭原则”,就是违背了“系统对扩展开放,对修改关闭”的原则。
2.工厂方法模式
基于简单工厂模式的一个扩展,我们可以把工厂也给它抽象咯。
如果说简单工厂模式能提供南京的各种产品,那么抽象工厂模式就能提供南京、上海、苏州等地的各种产品。
我把简单工厂模式的DEMO改了下形成了这个抽象工厂模式的DEMO,我放出来吧。
package defaultPk; public class LearnFactoryDesign { static abstract class AbstractProduct{ //抽象产品 abstract public void getType(); } //产品都要继承自抽象产品类 static class ProductA extends AbstractProduct{ @Override public void getType() { System.out.println("我是A产品!"); } } static class ProductB extends AbstractProduct{ @Override public void getType() { System.out.println("我是B产品!"); } } //抽象工厂类 abstract static class AbstractFactory{ public abstract AbstractProduct getProduct(String type); } //上海工厂 static class ShanghaiFactory extends AbstractFactory{ @Override public AbstractProduct getProduct(String type) { if (type=="A") { System.out.print("上海工厂发货-"); return new ProductA(); } if (type=="B") { System.out.print("上海工厂发货-"); return new ProductB(); } return null; } } static class NanjinFactory extends AbstractFactory{ @Override public AbstractProduct getProduct(String type) { if (type=="A") { System.out.print("南京工厂发货-"); return new ProductA(); } if (type=="B") { System.out.print("南京工厂发货-"); return new ProductB(); } return null; } } public static void main(String[] args){ NanjinFactory nanjinFactory=new NanjinFactory(); ShanghaiFactory shanghaiFactory=new ShanghaiFactory(); nanjinFactory.getProduct("A").getType(); nanjinFactory.getProduct("B").getType(); shanghaiFactory.getProduct("A").getType(); shanghaiFactory.getProduct("B").getType(); } }可知,实现工厂方法模式需要注意两点:
——要有产品的抽象类,所有产品都继承自这个类
——要有工厂的抽象类,所有工厂都继承自这个类
最后根据需求调用特定工厂来生产特定产品即可。
最后看看抽象工厂模式
先回顾下简单工厂模式,它仅仅抽象了产品,所以我们仅能从一个工厂生产同一个家族系的产品。
工厂方法模式,不仅把产品抽象了,还把工厂也抽象了,所以我们能从多个工厂生产同一个家族系的产品,每一个工厂能生产一个产品家族。
最后我们看看马上要说的抽象工厂模式,这个模式把工厂产品都抽象了,不过,与工程方法模式不同的是,它的产品抽象不止一个,而是有多个,这就让工厂能生产不同家族的产品。举个例子:雅马哈的某个工厂原来是搞乐器的,能生产乐器家族的小提琴、钢琴、笛子啥的,后来就开始搞摩托,能生产摩托家族的仿赛、街车、越野车啥的。
总结
要根据是否使用多个工厂、是否生产不同家族系的产品来确定使用何种工厂模式。
