【设计模式】 工厂方法模式

发布于:2025-09-07 ⋅ 阅读:(22) ⋅ 点赞:(0)

系列文章目录


需要了解工厂制造细节吗?

我们在前面的文章中为大家介绍了简单工厂模式,我们知道 简单工厂模式是最基本的创建实例相关的设计模式, 但是在真实情况中,有更多复杂的情况需要处理。简单工厂生成实例的类,知道了太多的细节,这就导致这个类很容易出现难维护、灵活性差的问题。

现实中我们要想过好生活,是不太需要也不太可能知道所有细节的。比如说,我们知道猪长什么样子,也知道红烧肉很好吃,但一头猪是通过怎么样的过程变成红烧肉的呢?我们并不需要关注。所以如果将来能生产出这样一台机器,送进去的是猪,出来的就是红烧肉,貌似就好多了。

在我们的程序中,确实存在封装实例创建过程的模式----工厂方法模式,这个模式可以让创建实例的过程封装到工厂类中, 避免耦合,它与简单工厂模式是一个体系的。

简单工厂模式实现

下面我们以简单工厂模式的计算器为例,工厂类和客户端代码如下:

 public class OperationFactory{
        public static Operation createOperate(String operate){
            Operation oper = null;
            switch(operate){
                case "+":
                    oper = new Add();
                    break;
                case "-":
                    oper = new Sub();
                    break;
                case "*":
                    oper = new Mul();
                    break;
                case "/":
                    oper = new Div();
                    break;
            }
            return oper;
        }
    }

    public static void main(String[] args) {
        Operation oper = OperationFactory.createOperate(strOperate);
        double result = oper.getResult(numberA,numberB);
    }

工厂方法模式的实现

如果换成工厂方法模式写这个计算器,代码如下:

public interface IFactory{
       public Operation createOperation();
   }
   public class AddFactory implements IFactory{

       @Override
       public Operation createOperation() {
           return new Add();
       }
   } 
   public class SubFactory implements IFactory{

       @Override
       public Operation createOperation() {
           return new Sub();
       }
   }
   public class MulFactory implements IFactory{

       @Override
       public Operation createOperation() {
           return new Mul();
       }
   }
   public class DivFactory implements IFactory{

       @Override
       public Operation createOperation() {
           return  new Div();
       }
   }
   //此时我们的OperationFactory类代码
    public class OperationFactory{
       public static Operation createOperation(String operate){
           IFactory factory = null;
           Operation oper = null;
           switch(operate){
               case "+":
                   factory = new AddFactory();
                   break;
               case "-":
                   factory = new SubFactory();
                   break;
               case "*":
                   factory = new MulFactory();
                   break;
               case "/":
                   factory = new DivFactory();
                   break;
           }
           oper = factory.createOperation();
           return oper;
       }
   }

简单方法? 工厂方法?

以前我们说过,如果我们现在需要增加其他运算,比如求x的n次方,或者求以a为底b的对数,这些功能的增加哎,在简单工厂里,我们是先去加求x的n次方运算指数类,然后去更改OperationFactory类,当中加Case语句分支判断即可,现在用了工厂方法,加指数运算没问题,去改OperationFactory类的分支也没问题,但又增加了一个指数工厂类,这不等于不但没有降低难度,反而增加类,把复杂性增加了吗?

简单工厂模式的最大优点在于工厂类中包含必要的逻辑判断,根据客户端的选择条件动态的实例化相关的类,对于客户端来说,去除了与具体产品的依赖。 就像计算器这个实例,让客户端不用管应该用哪个类的实例,只需要把“+”给工厂,工厂就自动的给出了相应的实例,客户端只需要去运算就可以了。但是我们要增加一个X的n次方的操作的话,我们需要给OperationFactory类的方法里加Case条件,这就是说,我们不但对扩展开放了,对修改也开放了,这违背了开放-封闭原则。 也就是说这个OperationFactory类承载了太多功能。

但是在我们上述的工厂方法中好像也没有做到这一点,他比原来多出了四个运算工厂类和一个工厂接口,其实是因为我们上述代码并没有体现工厂模式的优点,举个例子:我们公司原来只有一家工厂,生产四种不同的产品。后来发展比较好,需要增加两种产品放在另一个地方开设新的工厂,新的工厂不应该影响原来工厂的运作。这样我们只需总公司那里再增加一下协调管理部门就好了。

就编程而言,我们应该尽量将长的代码分派切割成小段,再将每一小段‘封装’起来,减少每段代码之间的耦合,这样风险就分散了,需要修改或扩展的难度就降低了。 加减乘除四个类算是一个工厂的产品,不妨叫他们(基础运算工厂)类,现在增加指数、对数运算类,如果算是另一种工厂的两种产品,不妨称他们为‘高级运算工厂’类,就没必要去影响原有的基础运算工厂运作了。

代码实现:

public class Pow extends Operation {

    public double getResult(double numberA,double numberB){
        return Math.pow(numberA,numberB);
    }
}

public class Log extends Operation{
    public double getResult(double numberA,double numberB){
        return Math.log(numberB)/Math.log(numberA);
    }
}
public interface IFactory {
    public Operation createOperation();
}
//基础运算工厂类
public class basicFactory implements IFactory{

    public Operation createOperation(String operate) {
        IFactory factory = null;
        Operation oper = null;
        switch(operate){
            case "+" :
                factory = new AddFactory();
                break;
            case "-":
                factory = new SubFactory();
                break;
            case "*":
                factory = new MulFactory();
                break;
            case "/" :
                factory = new DivFactory();
                break;
        }
        oper = factory.createOperation();
        return oper;
    }
}
//高级运算工厂类
public class AdvancedOperationFactory implements IFactory{
    @Override
    public Operation createOperation(String operType) {
        Operation oper = null;
        switch(operType){
            case "pow":
                oper = new Pow();
                break;
            case "log":
                oper = new Log();
                break;
        }
        return oper;
    }
}



public class OperationFactory {
    public static Operation createOperate(String strOperate) {
        Operation oper = null;
        IFactory factory = null;
        switch (strOperate) {
            case "+":
            case "-":
            case "*":
            case "/":
                factory = new basicFactory();
                break;
            case "pow":
            case "log":
                factory = new AdvancedOperationFactory();
                break;
        }
        oper = factory.createOperation();
        return oper;
    }
}

这里我们新的OperationFactory类已经不存在运算子类实例化的代码了,也就是说,在这个代码里,全部都是借口与具体工厂类,并不存在具体的实现,与原来的OperationFactory类对比实例化的过程延迟到了工厂子类中。这里也是依赖倒转原则中的针对接口编程,不要针对实现编程。 注意到关键词 – 延迟到子类

工厂方法模式,定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类IDE实例化延迟到其子类

工厂方法克服了简单工厂违背开放-封闭原则的缺点,同样保持了封装对象创建过程的优点。工厂方法模式是简单工厂模式的进一步抽象和推广。 由于使用了多态性,工厂方法模式保持了简单工厂模式的优点克服了他的缺点。另外工厂方法模式本质就是对获取对象过程的抽象。

工厂模式好处:

  • 对于复杂的参数构造对象,可以很好的对外层屏蔽代码的复杂性,注意这里是指创建实例的构造对象。
  • 工厂方法模式有很好的解耦能力,这就是针对接口在编程,当我们要修改具体实现层的代码时,上层代码完全不了解实现层的情况,因此不会影响到上层代码的调用。达到解耦目的。

总结

以上就是本文全部内容,本文主要向大家介绍了设计模式中的工厂模式,通过对计算器简单工厂模式代码的修改扩展,一步一步引出工厂方法模式的代码,介绍工厂方法模式的优点和适用性。感谢各位能够看到最后,如有问题,欢迎各位大佬在评论区指正,希望大家可以有所收获!创作不易,希望大家多多支持!


网站公告

今日签到

点亮在社区的每一天
去签到