简介

是一种创建型设计模式,定义一个 创建对象 的 接口 , 让 实现这个接口的子类 决定 实例化哪个类 , 工厂方法让 类的实例化 推迟到子类中进行 ;

主要组成部分:

  • 抽象产品接口(Product Interface):定义了工厂方法将要创建的产品对象的通用接口。

  • 具体产品类(Concrete Product Classes):实现了抽象产品接口,代表了具体的产品对象。

  • 抽象工厂接口(Factory Interface):定义了一个工厂方法,用于创建产品对象,客户端通过该接口与工厂进行交互。

  • 具体工厂类(Concrete Factory Classes):实现了抽象工厂接口,包含了工厂方法的实现,负责创建具体的产品对象。

工作流程

  • 客户端通过抽象工厂接口与具体工厂交互,请求创建产品对象。

  • 具体工厂类实现了工厂方法,根据客户端的请求创建具体产品对象。

  • 客户端得到产品对象,但并不需要知道具体产品对象的创建细节。

例子

结构

代码

抽象工厂接口

/**
 * @author: lpy
 * @Date: 2023/10/17
 */
public interface IFacatory {
    Operation createOperation(String optr);
}

具体工厂类

/**
 * @author: lpy
 * @Date: 2023/10/17
 */
public class BasicFactory implements IFacatory {
    @Override
    public Operation createOperation(String optr) {
        Operation op =null;
        switch (optr){
            case "+":
                op = new Add2();
                break;
            case "-":
                op = new Sub2();
                break;
            case "*":
                op = new Mul2();
                break;
            case "/":
                op = new Div2();
                break;
        }
        return op;
    }
}
/**
 * @author: lpy
 * @Date: 2023/10/17
 */
public class AdvancedFactory implements IFacatory {
    @Override
    public Operation createOperation(String optr) {
        Operation opt = null;
        switch (optr){
            case "pow":
                opt = new Pow();
                break;
            case "log":
                opt = new Log();
                break;
        }
        return opt;
    }
}

抽象产品接口

/**
 * @author: lpy
 * @Date: 2023/10/17
 */
public abstract class Operation {
    public abstract double getResult(double a, double b);
}

具体产品类

public class Add2 extends Operation {

    @Override
    public double getResult(double a,double b){
        return a+b;
    }
}
public class Div2 extends Operation {

    @Override
    public double getResult(double a,double b){
        return a/b;
    }
}
public class Mul2 extends Operation {

    @Override
    public double getResult(double a,double b){
        return a*b;
    }
}
public class Sub2 extends Operation {

    @Override
    public double getResult(double a,double b){
        return a-b;
    }
}
public class Pow extends Operation {
    @Override
    public double getResult(double a, double b) {
        return Math.pow(a,b);
    }
}
public class Log extends Operation {
    @Override
    public double getResult(double a, double b) {
        return Math.log(b)/Math.log(a);
    }
}

应用

点击跳转》》》Spring源码解析】FactoryBean-工厂方法模式的实现及使用

例子源码说明

IFactory工厂接口
Add2,Div2,Mul2,Sub2加减乘除都是基本运算,他们由BasicFactory来创建,就免得每一种运算都增加一个工厂了。(最基本的形式是加减乘除各构建一个工厂)
Pow,Log是高级运算,这样增加新功能比如取余,与或非等运算,就不用改原来的BasicFactory了,只需要新增一个新算法工厂

工厂方法模式优缺点

  • 优点:
    • 不关心创建细节 : 用户 只需要 关心 所需产品 对应的工厂 , 无需关心创建细节 ;

    • 符合开闭原则 : 加入 新产品 , 符合开闭原则 , 提高可扩展性 ;

工厂方法模式 中 , 使用 工厂类创建 产品对象 , 同时 隐藏了 具体的 产品类 被 实例化 的细节 ;

  • 缺点:
    • 增加复杂性 : 类的个数容易过多 , 增加系统复杂度 ;

    • 在 添加新产品 时 , 除了编写 新的产品类 之外 , 还要 编写该产品类对应的 工厂类 ;

    • 增加难度 : 增加了系统 抽象性 和 理解难度 ;

工厂方法本身 利用了抽象 , 该模式中会 引入抽象层 , 如果要动态创建产品类 , 还要 引入反射技术 ;

7 大设计原则

不能全部遵守 , 也不能不遵守 , 注意平衡 功能 和 系统复杂度 , 找到最合适的一个点 ;

- 单一职责原则(Single Responsibility Principle - SRP):
这个原则规定一个类应该只有一个改变的理由,也就是说,一个类应该只有一个单一的职责。这有助于保持类的简单性和可维护性,因为每个类只需关注一个特定的功能。

- 开放-封闭原则(Open-Closed Principle - OCP):
开放-封闭原则要求系统中的软件实体(类、模块、函数等)应该对扩展开放,对修改封闭。这意味着当需要添加新功能时,应该通过扩展现有代码来实现,而不是修改原有代码。

- 里氏替换原则(Liskov Substitution Principle - LSP):
里氏替换原则规定,子类应该能够替换其父类,而不会影响程序的正确性。也就是说,子类应该继承父类的行为,但可以扩展或修改该行为,但不应该改变父类的行为。

- 接口隔离原则(Interface Segregation Principle - ISP):
接口隔离原则要求一个类不应该强迫其客户端依赖于它们不需要的接口。应该根据客户端的需求定义小而精确的接口,而不是大而笨重的接口。

- 依赖倒置原则(Dependency Inversion Principle - DIP):
依赖倒置原则要求高级模块不应该依赖于低级模块,它们都应该依赖于抽象。具体来说,这意味着应该通过抽象接口或抽象类来定义模块之间的依赖关系,而不是直接依赖于具体实现。

- 迪米特法则(Law of Demeter - LoD):
迪米特法则也被称为最少知识原则,它要求一个对象应该只与其密切的朋友交互,而不应该暴露太多的信息给外部对象。这有助于减少对象之间的耦合度,提高系统的灵活性。

- 合成复用原则(Composite Reuse Principle - CRP):
合成复用原则鼓励通过组合(合成)已有的类来实现新功能,而不是通过继承现有的类。这样可以降低系统的耦合度,并且更加灵活。

源码位置

全部源码github.com/xs-alpha/designPattern

如有内容侵权,麻烦联系博主删除

参考文献


0 条评论

发表评论

Avatar placeholder

您的电子邮箱地址不会被公开。 必填项已用*标注

ICP备案号: 辽ICP备20003309号