概念介绍
工厂方法模式(FACTORY METHOD)是一种常用的类创建型设计模式, 此模式的核心精神是封装类中变化的部分,提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用和方便后期维护拓展的目的。它的核心结构有四个角色,分别是抽象工厂;具体工厂;抽象产品;具体产品(百度百科)
结构
工厂方法模式的主要角色如下。
-
抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品。
-
具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
-
抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
-
具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
优劣势
优势
-
用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程
-
在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无须对原工厂进行任何修改,满足开闭原则
劣势
- 每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度
栗子
这里我以做鸡为栗子,假设只做鸡,不做其他的。鸡有不同的做法,比如炸鸡、蜜汁鸡。鸡还有不同的口味,比如麻辣、蒜香。
-
抽象产品:鸡
-
具体产品:麻辣炸鸡、蒜香炸鸡
-
抽象工厂:CallChichen(由子类实现)
-
具体工厂:具体要做的鸡
类图
代码示例
/**
* @author yulecha
* @version 1.0.0
* @ClassName CallChichen.java
* @Description 叫了个鸡(抽象工厂)
* @createTime 2019年10月17日 17:06:00
*/
public abstract class CallChichen {
/**
* 定义一个抽象方法,由各个子类工厂实现
* @param type
* @return
*/
abstract Chichen createChichen(String type);
}
/**
* @author yulecha
* @version 1.0.0
* @ClassName FireChichen.java
* @Description 炸鸡(具体工厂)
* @createTime 2019年10月17日 17:20:00
*/
public class FireChichen extends CallChichen {
/**
* 根据炸鸡口味类型返回不同的炸鸡实例
* @param type
* @return
*/
@Override
public Chichen createChichen(String type) {
Chichen chichen = null;
if ("麻辣炸鸡".equals(type)) {
chichen = new SpicyFireChichen();
} else if ("蒜香炸鸡".equals(type)) {
chichen = new GarlicFireChichen();
}
return chichen;
}
}
/**
* @author yulecha
* @version 1.0.0
* @ClassName HoneyChichen.java
* @Description 蜜汁鸡(具体工厂)
* @createTime 2019年10月17日 17:22:00
*/
public class HoneyChichen extends CallChichen {
/**
* 根据蜜汁鸡口味类型返回不同的实例
* @param type
* @return
*/
@Override
public Chichen createChichen(String type) {
Chichen chichen = null;
if ("麻辣蜜汁鸡".equals(type)) {
chichen = new SpicyFireChichen();
} else if ("蒜香蜜汁鸡".equals(type)) {
chichen = new GarlicFireChichen();
}
return chichen;
}
}
/**
* @author yulecha
* @version 1.0.0
* @ClassName Chichen.java
* @Description 鸡(抽象产品)
* @createTime 2019年10月17日 16:54:00
*/
public abstract class Chichen {
/**
* 产品名
*/
protected String name;
/**
* 制作什么鸡都需要准备一只鸡,默认实现准备鸡
*/
public void prepare() {
System.out.println(name + ":准备鸡中。。。。。");
}
/**
* 不同的鸡烹饪手法不一样,由子类实现
*/
abstract void cook();
/**
* 制作完鸡后打包,打包流程一样,默认实现打包鸡
*/
public void box() {
System.out.println(name + ":打包鸡中。。。。。");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/**
* @author yulecha
* @version 1.0.0
* @ClassName GarlicFireChichen.java
* @Description 蒜香炸鸡(具体产品)
* @createTime 2019年10月17日 17:01:00
*/
public class GarlicFireChichen extends Chichen {
/**
* 这里直接输出一句话表示蒜香炸鸡烹饪过程
*/
@Override
void cook() {
setName("蒜香炸鸡");
System.out.println("蒜香炸鸡烹饪中");
}
}
/**
* @author yulecha
* @version 1.0.0
* @ClassName GarlicHoneyChichen.java
* @Description 麻辣蜜汁鸡(具体产品)
* @createTime 2019年10月17日 17:03:00
*/
public class GarlicHoneyChichen extends Chichen {
/**
* 这里输出一句话表示麻辣蜜汁鸡烹饪过程
*/
@Override
void cook() {
setName("麻辣蜜汁鸡");
System.out.println("麻辣蜜汁鸡烹饪中");
}
}
/**
* @author yulecha
* @version 1.0.0
* @ClassName SpicyFireChichen.java
* @Description 麻辣炸鸡(具体产品)
* @createTime 2019年10月17日 17:00:00
*/
public class SpicyFireChichen extends Chichen {
/**
* 这里直接输出一句话表示麻辣炸鸡的烹饪过程
*/
@Override
void cook() {
setName("麻辣炸鸡");
System.out.println("麻辣炸鸡烹饪中");
}
}
/**
* @author yulecha
* @version 1.0.0
* @ClassName SpicyHoneyChichen.java
* @Description 蒜香蜜汁鸡(具体产品)
* @createTime 2019年10月17日 17:04:00
*/
public class SpicyHoneyChichen extends Chichen {
/**
* 这里输出一句话表示蒜香蜜汁鸡的烹饪过程
*/
@Override
void cook() {
setName("蒜香蜜汁鸡");
System.out.println("蒜香蜜汁鸡烹饪中");
}
}
/**
* @author yulecha
* @version 1.0.0
* @ClassName Client.java
* @Description 叫了个鸡测试(工厂方法模式)
* @createTime 2019年10月17日 17:47:00
*/
public class Client {
public static void main(String[] args) {
System.out.println("********************************");
System.out.println("**** 欢迎使用叫了个鸡服务 ***");
System.out.println("********************************");
System.out.println("请输入您想叫的鸡(麻辣炸鸡,蒜香炸鸡,麻辣蜜汁鸡,蒜香蜜汁鸡)");
String type = new Scanner(System.in).nextLine();
Chichen fireChichen = new FireChichen().createChichen(type);
fireChichen.prepare();
fireChichen.cook();
fireChichen.box();
System.out.println("本次叫鸡服务结束");
}
}
********************************
***** 欢迎使用叫了个鸡服务 *****
********************************
请输入您想叫的鸡(麻辣炸鸡,蒜香炸鸡,麻辣蜜汁鸡,蒜香蜜汁鸡)
麻辣炸鸡
null:准备鸡中。。。。。
麻辣炸鸡烹饪中
麻辣炸鸡:打包鸡中。。。。。
本次叫鸡服务结束
总结
如果要创建的“产品”不多,只要一个工厂类就可以完成,这种模式叫“简单工厂模式”,它不属于 GoF 的 23 种经典设计模式,它的缺点是增加新产品时会违背“开闭原则”。