设计模式(三)策略模式

版权声明:转载必须注明本文转自晓_晨的博客:http://blog.csdn.net/niunai112

目录

导航

设计模式之六大设计原则
设计模式(一)单例模式
设计模式(二)工厂模式
设计模式(三)策略模式
设计模式(四)适配器模式
设计模式(五)享元模式
设计模式(六)建造者模式
设计模式(七)原型模式
设计模式(八)桥接模式
设计模式(九)外观模式
设计模式(十)组合模式
设计模式(十一)装饰器模式
设计模式(十二)代理模式
设计模式(十三)迭代器模式
设计模式(十四)观察者模式
设计模式(十五)中介者模式
设计模式(十六)命令模式
设计模式(十七)状态模式
设计模式(十八)访问者模式
设计模式(十九)责任链模式
设计模式(二十)解释器模式
设计模式(二十一)备忘录模式
设计模式(二十二)模板模式
设计模式总结篇(为什么要学习设计模式,学习设计模式的好处)

前言

策略模式是一种非常常用的设计模式,而且我们日常生活中也经常会遇到,比如你到商店里去买东西的时候,可能会根据你会员卡等级的不一样而选择不同的优惠方案。

而在java中,策略模式广泛应用于代码开发中,就拿买东西举例子。
strategy
Normal,Vip,SuperVip是CalcPrice的实现类,用来实现具体的策略,Customer关联Calcprice接口,通过传入的参数,为其选择正确的策略

public interface CalcPrice {//定义优惠接口
    double calcPrice(double price);
}
public class Normal implements CalcPrice {
    @Override
    public double calcPrice(double price) {
        return price;//不优惠
    }
}
public class Vip implements CalcPrice {
    @Override
    public double calcPrice(double price) {
        return price * 0.9;//打9折
    }
}
public class SuperVip implements CalcPrice {
    @Override
    public double calcPrice(double price) {
        return price * 0.8;//打8折
    }
}
public class Customer {
    double totalConsume = 0;
    double currentConsume = 0;
    CalcPrice strategy;//具体使用的策略

    public double buy(double current){

        return strategy.calcPrice(current);

    }


}


public class Test {
    public static void main(String[] args) {
        Customer customer = new Customer();
        customer.setStrategy(new Normal());
        System.out.println("In Normal strategy 1000 need pay: " + customer.buy(1000));
        customer.setStrategy(new Vip());
        System.out.println("In Vip strategy 1000 need pay: " + customer.buy(1000));
        customer.setStrategy(new SuperVip());
        System.out.println("In SuperVip strategy 1000 need pay: " + customer.buy(1000));
    }
}


测试结果如下
------------------------------

In Normal strategy 1000 need pay: 1000.0
In Vip strategy 1000 need pay: 900.0
In SuperVip strategy 1000 need pay: 800.0

上面就是策略模式,当需要不同的策略的时候,就自己传入策略实现类,然后利用策略来进行计算。

策略模式的优点
  (1)策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免代码重复。

  (2)使用策略模式可以避免使用多重条件(if-else)语句。多重条件语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重条件语句里面,比使用继承的办法还要原始和落后。

策略模式的缺点
  (1)客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道算法或行为的情况。

  (2)由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观。

策略模式可以避免使用(if-else)语句是有问题的,因为假设我们需要客户总消费额到达2000时,就给客户打9折,到达3000,就打8折,这样的策略时,在程序选择使用哪个策略的时候是一定需要进行判断的,虽然不一定需要(if-else)来判断,但是说策略模式可以避免使用(if-else)语句这句话是绝对有问题的,在传入策略实现类的时候肯定进行了判断,如果是在程序中判断的话,那么大概率是使用了(if-else)语句,假如没在程序中使用,而是买东西的店员手动传入的话,那我………………无言以对,但是店员的脑子里肯定也用了类似(if-else)的转换。

作为写程序的,肯定要减少店员的压力,所以这部分的判断肯定是要写在程序中的。如下,使用的(if-else)结构,这里依然使用策略类,减少了(if-else)代码块中的代码,使程序逻辑清晰。

public class Customer {
    double totalConsume = 0;
    double currentConsume = 0;
    CalcPrice strategy;//具体使用的策略

    public double buy(double current){

        totalConsume += current;//总消费累加
        currentConsume = current;//当前消费的金额

        if (totalConsume >= 3000){//总消费超过3000,使用SuperVip策略
            strategy = new SuperVip();
        } else if (totalConsume >= 2000){//总消费超过2000,使用Vip策略
            strategy = new Vip();
        } else {//否则,使用Normal策略
            strategy = new Normal();
        }
        return strategy.calcPrice(current);

    }


}


public class Test {
    public static void main(String[] args) {
        Customer customer = new Customer();
        System.out.println("1000 need pay" + customer.buy(1000));
        System.out.println("Strategy:" + customer.strategy);
        System.out.println("1000 need pay" + customer.buy(1000));
        System.out.println("Strategy:" + customer.strategy);
        System.out.println("1000 need pay" + customer.buy(1000));
        System.out.println("Strategy:" + customer.strategy);
    }
}

---------------

1000 need pay1000.0
Strategy:Strategy.simple.Normal@1540e19d
1000 need pay900.0
Strategy:Strategy.simple.Vip@677327b6
1000 need pay800.0
Strategy:Strategy.simple.SuperVip@14ae5a5

当总消费未满2000不优惠,满2000打9折,满3000打8折。这样一个简单的策略模式就使用好了,当要加策略的时候就新建一个类实现CalcPrice接口,在Customer里加一个if else 的分支即可。

if else的分支是可以用注解(Annotation)的方法来解决的,之后在总结的时候我会把这个问题补上,让策略模式的耦合度更低,代码更加容易维护。
  
  
  

Git地址

本篇实例Github地址:https://github.com/stackisok/Design-Pattern/tree/master/src/Strategy

回到最上方


有什么不懂或者不对的地方,欢迎留言。
喜欢LZ文章的小伙伴们,可以关注一波,也可以留言,LZ会回你们的。
觉得写得不错的小伙伴,欢迎转载,但请附上原文地址,谢谢^_^!

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值