工厂方法模式(Factory Method Pattern)是创建型设计模式的一种,它定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类的实例化推迟到子类中进行。
组成结构
抽象产品(Product)
定义了工厂方法返回的对象的接口或抽象类。
具体产品(ConcreteProduct)
实现了抽象产品接口或继承了抽象产品类,是工厂方法实际返回的对象。
抽象工厂(Creator)
声明了返回抽象产品类型的工厂方法。抽象工厂也可以定义一个默认的实现,但通常是将工厂方法的实现推迟到其子类中。
具体工厂(ConcreteCreator)
继承了抽象工厂类,实现了工厂方法,返回具体产品的实例。
优点
开闭原则
工厂方法模式通过引入工厂等级结构,使得增加新的产品类时只需扩展工厂类,而不需要修改原有代码,符合开闭原则。
解耦
客户端代码与具体产品实现解耦,客户端只依赖抽象产品接口或抽象类,不依赖于具体的产品类。
扩展性
由于工厂方法模式将产品类的实例化推迟到子类中,因此可以通过扩展子类来轻松地增加新的产品类。
灵活性
工厂方法模式使得一个类的实例化延迟到其子类,这提供了一种在不修改原有代码的情况下引入新产品的方式。
缺点
类的个数增加
由于需要为每个具体产品类定义一个工厂类,因此类的个数会增加,这可能会增加代码的复杂性。
增加了系统的抽象性和理解难度
工厂方法模式引入了抽象层和接口,这可能会增加系统的抽象性和理解难度,尤其是对于初学者来说。
适用场景
创建逻辑比较复杂时:
如果产品的创建逻辑比较复杂,可以将其封装在一个工厂类中,使得客户端代码更加简洁和易于维护。
系统需要扩展时
如果系统预计需要扩展以包含新产品,工厂方法模式提供了一种灵活的方式来引入新产品,而不需要修改现有代码。
客户端需要只知道产品的接口或抽象类时
如果客户端代码只需要知道产品的接口或抽象类,而不需要知道具体的产品实现,那么工厂方法模式是一种很好的选择。
示例
使用简单工厂模式设计一个计算器,实现简单的加减乘除功能。
计算器类
父类
import lombok.Data;
@Data
public abstract class Operation {
private double numberA;
private double numberB;
abstract double getResult();
}
加法类
public class OperationAdd extends Operation{
@Override
double getResult() {
return this.getNumberA() + this.getNumberB();
}
}
减法类
public class OperationSub extends Operation{
@Override
double getResult() {
return this.getNumberA() - this.getNumberB();
}
}
乘法类
public class OperationMul extends Operation{
@Override
double getResult() {
return this.getNumberA() * this.getNumberB();
}
}
除法类
import lombok.SneakyThrows;
public class OperationDiv extends Operation{
@SneakyThrows
@Override
double getResult() {
if (this.getNumberB() == 0) {
throw new Exception("除数不能为0");
}
return this.getNumberA() / this.getNumberB();
}
}
工厂类
父类
public interface IOperationFactory {
Operation getOperation();
}
加法工厂
public class FactoryAdd implements IOperationFactory{
@Override
public Operation getOperation() {
return new OperationAdd();
}
}
减法工厂
public class FactorySub implements IOperationFactory{
@Override
public Operation getOperation() {
return new OperationSub();
}
}
乘法工厂
public class FactoryMul implements IOperationFactory{
@Override
public Operation getOperation() {
return new OperationMul();
}
}
除法工厂
public class FactoryDiv implements IOperationFactory{
@Override
public Operation getOperation() {
return new OperationDiv();
}
}
客户端
public class Caculator {
public static void main(String[] args) {
IOperationFactory operationFactory = new FactoryAdd();
Operation operation = operationFactory.getOperation();
operation.setNumberA(2);
operation.setNumberB(3);
System.out.println(operation.getResult());
}
}
总结
总的来说,工厂方法模式是一种灵活且可扩展的创建型设计模式,它使得类的实例化推迟到子类中,从而提供了更大的灵活性和可扩展性。然而,它也增加了系统的抽象性和类的个数,因此在实际应用中需要权衡其优缺点。