工厂模式和策略模式实践及比较

1 背景

看到一篇公账号文章https://mp.weixin.qq.com/s/ClesNl6doAPHTYXF8KQpGA,文章改标题很吸引人,主要内容是,在spring框架中实现了策略模式,但是,我个人认为文章中实际上是工厂模式,因此,回顾一下工厂模式和策略模式,并进行的比较。
工厂模式和策略模式的简单实践,都是以实现加减乘除等运算场景为目的,再通过“增加一个运算符号”这样的场景,来看看两种设计模式,在代码变动上的区别。
参考了文章https://blog.csdn.net/zwj_jyzl/article/details/80869905

2 工厂模式和策略模式代码实现

首选定义一个接口,不同的符号计算类型只需要实现计算接口即可:
Calculate.java

package default_package.工厂模式和策略模式;

public interface Calculate {
    public String geResult(int number1, int number2);
}

假设一开始只有加运算、减运算、乘运算这三种计算需求,因此,需要对计算接口分别实现这三种计算类:
Add.java

package default_package.工厂模式和策略模式;

public class Add implements Calculate {
    @Override
    public String geResult(int number1, int number2) {
        return String.valueOf(number1 + number2);
    }
}

Minus.java

package default_package.工厂模式和策略模式;

public class Minus implements Calculate {
    @Override
    public String geResult(int number1, int number2) {
        return String.valueOf(number1 - number2);
    }
}

乘法的实现类就不看了,大同小异。

2.1 简单工厂模式

既然是工厂模式,那肯定的要有一个工厂类,根据不同的输入,返回对应的类:
**CalculatorFactory.java **

package default_package.工厂模式和策略模式;

public class CalculatorFactory {
    public static Calculate getCalculator(String opType) {
        switch (opType) {
            case "+":
                return new Add();

            case "-":
                return new Minus();

            case "*":
                return new Multiple();

            default:
                return null;

        }
    }
}

我这里的返回的处理类每次都是new出来的,性能可能会稍微有点影响,但是没有线程安全问题;如果每个处理类都是实现new好放在map里面,如果存在共享数据,会存在线程安全问题,没有共享数据既不会有线程安全问题,比如我这里,每个处理类没有共享数据,new好好放进map,资源利用上更优;具体情况具体分析。
现在,通过工厂模式处理不同类型的运算:
调用

//需求,假设这里是动态变化的
        int number1 = 1;
        int number2 = 2;
        String operationSymbol = "+";


        //工厂模式示范
        Calculate addOptype = CommonUtil.checkNullAndReturn(CalculatorFactory.getCalculator(operationSymbol), Main.class);
        String result = addOptype.geResult(number1, number2);
        System.out.println(number1 + operationSymbol + number2 + "=" + result);

经过分析,当需要增加新的计算符号时,需要对代码做三件事:

  1. 增加一个实现了“Calculate”接口的类,与工厂的输出类型保持一致
  2. 在工厂中增加相应的响应代码,返回那个新增的类的实例
  3. 不需要修改调用处的源码

2.2 策略模式

定义上下文类,用来接受不同的策略:
Context.java

package default_package.工厂模式和策略模式;

import java.util.PrimitiveIterator;

public class Context {
    private Calculate calculate;

    public Context(Calculate calculate) {
        this.calculate = calculate;
    }


    public String getResult(int number1, int number2) {
        return calculate.geResult(number1, number2);
    }
}

通过策略模式进行调用:

 //策略模式
        Context context = new Context(new Add());//手动应用了计算策略,要应对不同的情况,此处需要switch或者if结构
        result = context.getResult(number1, number2);
        System.out.println(number1 + operationSymbol + number2 + "=" + result);

当需要增加新的计算符号时,需要对代码做两件事:

  1. 增加一个实现了“Calculate”接口的类
  2. 手动在调用处实现一个“应用计算策略”的情况

3 对比和总结

在代码层面进行对比,两者的共同点是,增加新的场景时,都需要额外新增实体类来应对增加的场景。
不同点在于两个方面,使用策略模式时,调用者/方法使用者,自己需要知道哪种策略对应了哪种情况,自己要在方法调用处实现选择结构或者判断结构,实现不同的策略应用;如果多处调用,则需要在多处实现的一堆策略选择代码;
使用工厂模式时,调用者/方法使用者只需要传入某种标记场景的参数,然后使用工厂给出的类即可,到处调用也不需要调用者实现多余的代码的,因为实现过程都已经放到工厂中了。
个人见解,肯定有不对的地方,请指正。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值