简单工厂VS工厂方法

工厂方法模式–制造细节无需知

前面介绍过简单工厂模式,简单工厂模式只是最基本的创建实例相关的设计模式。在真实情况下,有更多复杂的情况需要处理。简单工厂生成实例的类,知道了太多的细节,这就导致这个类很容易出现难维护、灵活性差的问题。就像我们去饭店吃饭,只需要付钱,等成品,不需要了解这盘菜是怎么做的,如何加工的。

简单工厂

再来回顾下简单工厂模式的计算器功能的工厂类。

在这里插入图片描述

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;
}

客户端调用时

Operation operate = OperationFactory.createOperate(strOperate);
double result = operate.getResult(numberA, numberB);

当使用工厂方法模式实现

实际就是对简单工厂中的细节部分进行再封装,让这个工厂类不需要知道很多的实现细节。是这样子吗,体验一下子。

结构图如下:

在这里插入图片描述

先构建一个工厂接口

public interface IFactory {
    Operation createOperation();
}

然后加减乘除的工厂都去实现这个接口,并实现自己的createOeration()方法

// 加法工厂
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();
    }
}

那么在对外工厂类中就可以这么实现

public class OperationFactory {

    public static Operation createOperate(String operate) {
        Operation oper = null;
        IFactory factory = 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;
    }

}

当我需要增加新的运算功能时,需要增加运算类,运算工厂类,一下增加了好几个类,这样是不是变得更麻烦了?

简单工厂VS工厂方法

简单工厂模式的最大优点在于工厂类中包含必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。

就像计算器工厂类,客户端只需要传入一个"+"或别的,就能得到想要的功能算法。

但是当我们继续增加计算器功能时,比如增加一个指数运算,增加一个对数运算,要去不断修改OperationFactory类,就违背了开放-封闭原则。那我们该如何降低这种风险呢?就需要使用到工厂方法模式

我们应该尽量将长的代码分派切割成小段,再将每一小段封装起来,减少每段代码之间的耦合,这样风险就分散了,需要修改或扩展的难度就降低了。

再以计算器功能为例,项目起初,我们只知道加减乘除的功能,那我们就可以将这四个功能定义为基础运算工厂,也就是说前期功能是确定的,作为基础功能,我们就没有必要给加减乘除类增加冗余的工厂了。

后来增加了指数、对数运算,我们定义为高级运算工厂

那么其实并不是如上面的代码所讲,加减乘除功能每一个功能需要一个工厂类。而是将加减乘除用一个基础工厂来创建,而后面增加新的产品功能,又不想影响原有的工厂代码,于是就扩展一个新的工厂来处理即可。

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

修改结构图:

在这里插入图片描述

新增两个运算类(指数和对数)

// 指数
public class Pow extends Operation {
    @Override
    public double getResult(double numberA, double numberB) {
        return Math.pow(numberA, numberB);
    }
}

// 对数运算
public class Log extends Operation {
    @Override
    public double getResult(double numberA, double numberB) {
        return Math.log(numberB) / Math.log(numberA);
    }
}

工厂接口不变

public interface IFactory {
    Operation createOperation(String operType);
}

基础运算工厂类,此类已经比较成熟稳定,实现后应该封装到位,不建议轻易修改此类

public class FactoryBase implements IFactory {

    @Override
    public Operation createOperation(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 class FactoryAdvanced 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 operate) {
        Operation oper = null;
        IFactory factory = null;
        switch (operate) {
            case "+":
            case "-":
            case "*":
            case "/":
                factory = new FactoryBase();
                break;
            case "pow":
            case "log":
                factory = new FactoryAdvanced();
        }
        oper = factory.createOperation(operate);
        return oper;
    }

}

总结

工厂方法模式是简单工厂模式的进一步抽象和推广。工厂方法模式本质就是对获取对象过程的抽象。

对于复杂的参数的构造对象,可以很好地对外层屏蔽代码的复杂性,有很好的解耦能力。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值