Java设计模式之策略模式

定义

策略模式定义了一组算法,将它们逐个封装起来,并使它们可以相互替换。策略可以让算法独立于使用它们的客户而变化。

往往官方给的定义就是很难理解,其实就是定义一个接口,分别让具有相同行为的类去实现它,成为一种策略,然后根据不同需求调用不同类中的方法。通过不同的方式(算法)达到相同的目的(功能)。

说明

举个例子吧,我们在购物时,普通用户打9折,会员打8折,超级会员打6折。

此时我们就可以定义一个花费的接口 double cost(Double oldCost);作用就是计算出打折后应付的钱数。

然后我们设计不同的用户类来实现这个接口,比如普通用户类,如下代码:

	@Override
    public double cost(Double oldCost) {
        return oldCost * 0.9;
    }

然后会员和超级会员类似。这样就算配置了不同的策略

现在你一定会问:那怎么来区分当前用户属于哪一个用户呢?if-else吗?

当然不是,用策略模式的目的就是消除if-else带来的耦合,提高代码的扩展和维护性,所以此时我们就需要一个Context即上下文对象,说白了就是负责调用对应的算法,策略的类。有了这个类,它就可以自动的调用对应的策略从而完成费用的。

使用场景

什么时候使用:当你的if-else多余四个的时候就可以考虑使用策略设计模式了。

下面就将购物计算费用这个例子完整写出来。在写出来之前先来确定一下需要哪些类

  • Customer 消费的公共接口,计算打折后费用
  • Cashier 收银员,负责分级用户类型调用对应策略。
  • CommonCustomer 普通用户,即打0.9折,其他两个类似

例子

消费的公共接口 Customer.java

public interface Customer {
    /**
     * 计算折扣后的花费
     *
     * @param oldCost 原花费
     * @return 折扣后的花费
     */
    double cost(Double oldCost);
}

收银员类 Cashier .java

public class Cashier {
    private Customer customer;

    private double cost(Double oldCost) {
        return customer.cost(oldCost);
    }

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }
}

普通用户 CommonCustomer.java

public class CommonCustomer implements Customer {

    @Override
    public double cost(Double oldCost) {
        return oldCost * 0.95;
    }
}

会员 SuperCustomer.java

public class SuperCustomer implements Customer {
    @Override
    public double cost(Double oldCost) {
        return oldCost * 0.8;
    }
}

超级会员 VIPCustomer.java

public class VIPCustomer implements Customer {
    @Override
    public double cost(Double oldCost) {
        return oldCost * 0.6;
    }
}

测试类

/**
 * 举一个收银的例子,普通用户打95折,会员打8折,超级会员打6折。
 */
public class Test {
    public static void main(String[] args) {
        Cashier cashier = new Cashier();
        // 普通会员
        CommonCustomer commonCustomer = new CommonCustomer();
        cashier.setCustomer(commonCustomer);
        System.out.println("普通会员:" + commonCustomer.cost(100.0));

        // 一般会员
        SuperCustomer superCustomer = new SuperCustomer();
        cashier.setCustomer(superCustomer);
        System.out.println("普通会员:" + commonCustomer.cost(100.0));

        // 超级会员
        VIPCustomer vipCustomer = new VIPCustomer();
        cashier.setCustomer(vipCustomer);
        System.out.println("超级会员:" + commonCustomer.cost(100.0));
    }
}

优点

  • 算法可以自由切换
    • 改一下策略很方便
  • 扩展性良好
    • 增加一个策略,就多增加一个类就好了。

缺点

  • 策略类的数量增多
    • 每一个策略都是一个类,复用的可能性很小、类数量增多
  • 所有的策略类都需要对外暴露
    • 上层模块必须知道有哪些策略,然后才能决定使用哪一个策略
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值