一、情景:
上一篇老王的装饰者模式在卖煎饼已觉得没有发展前景了,一天突然做决定说要开一家面包店。他想制作一个能够自动制作面包的,面包机器,这样一来只要把面粉倒进去,然后设置不同的按钮,就能制作出不同的面包啦。老王美滋滋的想着,下面的情景。
二、情景后续:
老王又来求设计模式大佬了,来咨询制作面包机器的方法,大佬推荐了一种工厂方法的设计模式
三、工厂模式(Factory)
- 定义:定义了一个创建对象的接口,但由子类决定要实例化但类是哪一个。工厂方法把实例化退迟到子类
- 重要组件
- Product 定义工厂方法所创建的对象接口
- ConcreteProduct 具体的产品
- Fectory 工厂接口,里面定义了生产Product方法
- ConcreteCreator 具体的工厂方法,返回生产具体的产品。
四、代码演示
4.1 定义面包接口 Ibread
/**
* @author liuzihao
* @create 2020-11-22-11:13
* 面包接口
*/
public interface Ibread {
/**
* 描述
* @return
*/
String desc();
}
4.2具体的面包实现
/**
* @author liuzihao
* @create 2020-11-22-11:15
*/
public class Breakbread implements Ibread {
@Override
public String desc() {
return "黑面包";
}
}
public class BuckWheaBread implements Ibread {
@Override
public String desc() {
return "荞麦面包";
}
}
4.3 定义工厂方法
/**
* @author liuzihao
* @create 2020-11-22-11:16
* 工厂接口,用于生产面包
*/
public interface IFactory {
/**
* 创建一个面包
* @return
*/
Ibread createBread();
}
4.4 黑面包按钮、荞麦面包按钮
/**
* @author liuzihao
* @create 2020-11-22-11:18
* 黑面包按钮,用于生产黑面包
*/
public class BreakBreadButtonFactory implements IFactory {
@Override
public Ibread createBread() {
return new Breakbread();
}
}
/**
* @author liuzihao
* @create 2020-11-22-11:20
* 荞麦面包按钮,用于生产荞麦面包
*/
public class BuckWheaBreadButtonFactory implements IFactory {
@Override
public Ibread createBread() {
return new BuckWheaBread();
}
}
制作不同面包的 控制按钮已经制作好了,可以测试一下
/**
* @author liuzihao
* @create 2020-11-22-11:29
*/
public class DemoTest {
public static void main(String[] args) {
// 生产黑面包
IFactory iFactory = new BreakBreadButtonFactory();
Ibread breakBread = iFactory.createBread();
System.out.println(breakBread.desc());
// 生产荞麦面包
IFactory factory = new BuckWheaBreadButtonFactory();
Ibread buck = factory.createBread();
System.out.println(buck.desc());
}
}
这样两个按钮就可以成功制作出不同的面包啦。只要把这两个按钮安装到面包机上就可以啦
五、小结
工厂方法 满足开发密闭原则,他就是针对下面讲的简单工厂方法的一种改进。
六、番外,谈谈大家说的简单工厂
这里说的简单工厂,也可以叫静态工厂吧,具体是根据类型,然后采用switch方法,返回不同的生产对象,代码如下:
public Ibread create(String type) {
switch (type) {
case "1":
return new Breakbread();
case "2":
return new BuckWheaBread();
default:
throw new RuntimeException("不支持改类型");
}
}
其实上面设置 并不能成设计模式中的一种,更像是一种编码习惯,因为方便,很多程序员都喜欢用它,慢慢的也就被大家称为设计模式了
上面这种方式,最大的缺点就是 如果新增加一个类型的面包,那就就需要修改工厂方法,这违背了 开放密闭原则。所以改进方法就是我们今天介绍的,工厂方法,方法工厂方法也有他的缺点,比如生产的产品单一,假如老王又想推出一款 能制作冰淇淋的机器那该怎么办呢,
- 当然可以再像面包机器一样 制作一台。但是这样太麻烦啦,老王的店面都不够摆放了
- 或者能不能将机器进行改进,能生产面包和冰淇淋这种一系列产品族呢,那就就是下一篇介绍的,抽象工厂方法了