工厂模式
一、工厂模式介绍
工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种封装对象创建过程的方法,将对象的实例化过程延迟到子类或具体实现类中。
它在创建对象时提供了一种封装机制,将实际创建对象的代码与使用代码分离。
工厂模式有 3 种不同的实现方式
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
应用场景
- 解耦:分离职责,把复杂对象的创建和使用的过程分开
- 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化时。
- 复用代码,降低维护成本:
- 如果对象创建复杂且多处需用到,如果每处都进行编写,则很多重复代码,如果业务逻辑发生了改变,需用四处修改;
- 使用工厂模式统一创建,则只要修改工厂类即可,降低成本
二、工厂基类
不同的实现公共的对象
2.1 抽象产品(Abstract Product)
定义了产品的共同接口或抽象类。它可以是具体产品类的父类或接口,规定了产品对象的共同方法。
/**
* 笔接口
* @Author lcy
* @Date 2021/7/20 10:00
*/
public interface Pen {
/**
* 获取产品名称
* @return java.lang.String
* @author lcy
* @date 2021/7/20 10:07
**/
String getProductName();
/**
* 写字
* @author lcy
* @date 2021/7/20 10:07
**/
default void write(){
System.out.printf("The %s is writing%n",getProductName());
}
}
2.2 具体产品(Concrete Product)
实现了抽象产品接口,定义了具体产品的特定行为和属性。
/**
* 铅笔
* @Author lcy
* @Date 2021/7/20 10:08
*/
public class Pencil implements Pen {
@Override public String getProductName(){
return "铅笔";
}
}
/**
* 钢笔
* @Author lcy
* @Date 2021/7/20 10:09
*/
public class FountainPen implements Pen {
@Override public String getProductName(){
return "钢笔";
}
}
三、简单工厂模式
3.1 特点
- 包含一个工厂类,该工厂类负责根据传递的参数创建相应的对象。
- 客户端代码不需要关心具体实例的创建过程,只需通过工厂类获取所需对象即可。
核心类:
- 抽象产品(Abstract Product):抽象产品类,定义了产品的共同接口或抽象类。它可以是具体产品类的父类或接口,规定了产品对象的共同方法
- 具体产品(Concrete Product):实现了抽象产品接口,定义了具体产品的特定行为和属性
- 具体工厂(Concrete Factory):负责实际创建具体产品的对象
3.2 优缺点
优点:
- 封装了对象的创建过程,客户端代码无需关心具体实现类。
- 降低了客户端代码与具体实现类的耦合度。
缺点:
- 工厂类职责过重,一旦需要添加新的产品类型,就需要修改工厂类的代码,违背了开闭原则。
3.3 工厂实现类
/**
* 简单工厂模式
* @Author lcy
* @Date 2021/7/20 10:10
*/
public class SimplePenFactory {
/**
* 根据种类生产
* @param type 种类
* @return com.lcy.study.design.factory.Pen
* @author lcy
* @date 2021/7/20 10:11
**/
public static Pen factory(String type){
return switch (type) {
case "FountainPen" -> new FountainPen();
case "Pencil" -> new Pencil();
default -> null;
};
}
}
四、工厂方法模式
相比简单工厂而言,此种方法具有更多的可扩展性和复用性,同时也增强了代码的可读性,将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化哪一个类
4.1 特点
- 引入了抽象工厂接口,由具体子类负责实现工厂接口,每个子类对应一个具体产品的创建。
- 客户端通过调用工厂接口的方法来创建对象,具体实例化的过程由具体子类决定。
核心类
- 抽象产品(Abstract Product):抽象产品类,定义了产品的共同接口或抽象类。它可以是具体产品类的父类或接口,规定了产品对象的共同方法
- 具体产品(Concrete Product):实现了抽象产品接口,定义了具体产品的特定行为和属性
- 抽象工厂(Abstract Factory):声明了创建产品的抽象方法,可以是接口或抽象类。它可以有多个方法用于创建不同类型的产品。
- 具体工厂(Concrete Factory):负责实际创建具体产品的对象
4.2 优缺点
优点:
- 符合开闭原则,新增产品时无需修改已有代码,只需添加新的工厂和产品类。
- 避免了简单工厂模式的缺点,将创建过程分散到具体子类中。
缺点:
- 客户端需要知道所使用的具体工厂,存在一定的耦合。
4.3 抽象工厂(Abstract Factory)
/**
* 抽象工厂(Abstract Factory)
* @Author lcy
* @Date 2021/7/20 10:10
*/
public interface MethodPenFactory {
/**
* 生产
* @return com.lcy.study.design.factory.Car
* @author lcy
* @date 2021/7/20 10:11
**/
Pen factory();
}
4.4 具体工厂(Concrete Factory)
/**
* 简单工厂模式
* @Author lcy
* @Date 2021/7/20 10:10
*/
public class PencilFactory implements MethodPenFactory {
/**
* 生产铅笔
* @return com.lcy.study.design.factory.Pen
* @author lcy
* @date 2021/7/20 10:11
**/
@Override
public Pen factory(){
return new FountainPen();
}
}
/**
* 简单工厂模式
* @Author lcy
* @Date 2021/7/20 10:10
*/
public class FountainPenFactory implements MethodPenFactory {
/**
* 生产钢笔
* @return com.lcy.study.design.factory.Pen
* @author lcy
* @date 2021/7/20 10:11
**/
@Override
public Pen factory(){
return new Pencil();
}
}
五、抽象工厂模式
抽象工厂模式(Abstract Factory Pattern)用于创建一系列相关或依赖的对象,而无需指定其具体类。抽象工厂模式是工厂方法模式的推广,它关注一族产品的创建,而不仅仅是一个单一产品。
5.1 特点
- 引入了抽象工厂接口和抽象产品接口,具体工厂子类负责实现这两个接口。
- 一个抽象工厂可以创建一族相关的产品,而不仅仅是一个。
核心类
- 抽象工厂接口(Abstract Factory): 声明了创建一族产品的方法,每个方法对应一种产品。
- 具体工厂类(Concrete Factory): 实现了抽象工厂接口,负责创建一族相关的产品。
- 抽象产品接口(Abstract Product): 声明了一类产品的通用接口。
- 具体产品类(Concrete Product): 实现了抽象产品接口,是抽象工厂创建的具体产品。
5.2 优缺点
优点:
- 符合开闭原则,新增产品族时无需修改已有代码,只需添加新的工厂和产品类。
- 客户端代码与具体工厂和产品的耦合程度低,更易于替换和扩展。
缺点:
- 新增产品族时,需要修改抽象工厂接口和所有具体工厂的实现。
5.3 抽象产品(Abstract Product)
新增抽象产品
/**
* 颜色
* @Author lcy
* @Date 2021/7/20 12:00
*/
public interface Color {
/**
* 获取颜色
* @return java.lang.String
* @author lcy
* @date 2021/7/20 12:01
**/
String getColor();
}
5.4 具体产品(Concrete Product)
新增具体产品
/**
* 红色
* @Author lcy
* @Date 2021/7/20 12:01
*/
public class RedColor implements Color {
@Override public String getColor(){
return "red";
}
}
/**
* 蓝色
* @Author lcy
* @Date 2021/7/20 12:01
*/
public class BlueColor implements Color{
@Override public String getColor(){
return "blue";
}
}
5.5 抽象工厂(Abstract Factory)
抽象工厂升级
/**
* 抽象工厂
* @Author lcy
* @Date 2021/7/20 11:50
*/
public interface AbstractPenFactory {
/**
* 获取产品名称
* @param type 汽车品牌
* @return java.lang.String
* @author lcy
* @date 2021/7/20 11:55
**/
default Pen getProductName(String type){
return null;
}
/**
* 颜色
* @param color 颜色
* @return com.lcy.study.design.factory.Color
* @author lcy
* @date 2021/7/20 11:55
**/
default Color getColor(String color){
return null;
}
}
5.6 具体工厂(Concrete Factory)
/**
* 颜色工厂
* @Author lcy
* @Date 2021/7/20 11:56
*/
public class PenColorFactory implements AbstractPenFactory {
@Override public Color getColor(String color){
switch (color) {
case "red":
return new RedColor();
case "blue":
return new BlueColor();
default:
return null;
}
}
}
/**
* 笔工厂类
* @Author lcy
* @Date 2021/7/20 11:56
*/
public class PenProductFactory implements AbstractPenFactory {
@Override public Pen getProductName(String type){
return switch (type) {
case "FountainPen" -> new FountainPen();
case "Pencil" -> new Pencil();
default -> null;
};
}
}
5.7 工厂提供者
/**
* 工厂提供者
* @Author lcy
* @Date 2021/7/20 12:21
*/
public class FactoryProduct {
public static AbstractPenFactory getFactory(String factory){
switch (factory) {
case "color":
return new PenColorFactory();
case "pen":
return new PenProductFactory();
default:
return null;
}
}
}