Java 设计模式-策略模式(Strategy)Android讲解

哲学上说存在即合理。一些初级程序员,包括笔者也曾经在内心说过:“XX这鸟毛东西有什么用啊,根本就没必要这么做,真不知道为什么会有这东西”,就拿着这设计模式来说,以前接触的时候总觉得好复杂,小小的功能要分好几层,随着项目经验的积累,才发现这话说出来真的是打脸啊。是自己的无知导致狂妄的想法。
不是设计模式没有用,而是你不会!(啊!又被打脸)
最近在写SDK,架构项目,项目写到一半,回头看看,总觉得自己的代码平平无奇。而且在一些优秀的开源框架中出现的代码写法,根本没有用过。于是尝试着看看开源代码,突然发现原来同一种功能有这么多种实现方式,而且觉得很帅。(所谓的很帅是个人的看法,作为一个程序员,尽量不要写出很挫的代码,类似一个方法里面有十几个 if 语句,或者4,5个类中,一半的代码是重复的,只是小部分代码是变动的,那么这时候,就应该停下来好好想想是不是自己代码写的有问题了,是不是还有更优秀的实现方式)。其实,代码繁杂还是一回事,对没有强迫症的人影响不大,但是,代码扩展性不好,不易维护,那就是对所有人都是致命的了。简直会让人抓狂。
今天记录一下 策略模式,博文作为笔记记录

策略模式:定义了算法族,分别封装起来,让它们之间可相互替换,此模式让算法的变化独立于使用算法的客户

什么意思?别问我,我也不知道。卧槽,那学个毛线,算了,先看看在Android中什么时候使用到了策略模式

listView.setAdapter(new BAdapter());

没错,所有Android程序员都是使用过的方法,对着这行代码,试着理解一下策略模式的定义:

  • 定义了算法族,分别封装起来

    new BAdapter() 继承 BaseAdapter 具体算法在 getView 中实现。不同的Adapter继承 BaseAdapter 实现自己的UI布局,相当于定义了算法族,分别封装起来。

  • 让它们之间可相互替换

    new AAdapter()new BAdapter()new CAdapter() 对于这些一个个独立封装起来的算法,他们之间可以相互替换,被设置到 listView 中。

  • 此模式让算法的变化独立于使用算法的客户

    这里客户是指这些算法的调用者 listView 。在A,B,CAdapter() 中的算法变化,完全独立于 listView ,对于新增的算法,不用再使用 if 语句判断该使用哪一种,客户直接使用算法就可以,算法的实现也是独立的。大大提高了程序的扩展性,和维护性。妈妈再也不用担心我修改一个小功能导致4,5个类的代码要修改了。

具体实现

在网上查阅资料的时候看到很多人以销售商品是结算价格举例,【输入商品的价格和数量,得出总价,现在商店促销搞活动,商品打折(7折,8折…),满减(满400立减40…)】,这里抛砖引玉,具体看看代码,这里就不贴参考的连接了,如有雷同,纯属巧合。直接看代码

  • 折扣方式接口,面向接口编程,保持了继承的优点(代码重用),比继承更灵活(算法独立,可以任意扩展)。
package cn.design.java.strategy;

public interface IDiscount {

    public double getPrice(double price, int quantity);

}
  • 折扣方式—打折,实现IDisCount,设置折扣值 setDiscount(double discount),(7折,8.8折,等等),重写 getPrice(double price, int quantity) 方法实现折扣算法。
package cn.design.java.strategy;

/**
 * 折扣方式-打折
 * 
 * @author Ruffian
 * @date 2016年5月11日
 * 
 */
public class RebateDis implements IDiscount {

    // 折扣
    private double discount;

    public double getDiscount() {
        return discount;
    }

    public void setDiscount(double discount) {
        this.discount = discount;
    }

    @Override
    public double getPrice(double price, int quantity) {

        double sellPrice = price * quantity;

        if (discount > 0) {
            sellPrice = sellPrice * discount;
        }

        return sellPrice;
    }

}
  • 折扣方式—满减,实现IDisCount,设置折扣消费条件 setCondition(int conditionMoney, int reduceMoney),(满400立减40,等),重写 getPrice(double price, int quantity) 方法实现折扣算法。
package cn.design.java.strategy;

/**
 * 折扣方式-满减
 * 
 * @author Ruffian
 * @date 2016年5月11日
 * 
 */
public class ReduceDis implements IDiscount {

    // 满减条件金额
    private int conditionMoney;
    // 立减金额
    private int reduceMoney;

    public void setCondition(int conditionMoney, int reduceMoney) {
        this.conditionMoney = conditionMoney;
        this.reduceMoney = reduceMoney;
    }

    @Override
    public double getPrice(double price, int quantity) {

        double sellPrice = price * quantity;

        if (sellPrice > conditionMoney) {
            sellPrice = sellPrice - reduceMoney;
        }

        return sellPrice;
    }
}
  • 客户类
    基本的算法写完了,接下来编写一个客户类,这里相当于,编写 listView 类,以及 setAdapter()
package cn.design.java.strategy;

/**
 * 客户使用类-策略模式
 * 
 * @author Ruffian
 * @date 2016年5月11日
 * 
 */
public class DiscountStrategy {

    // 折扣方式
    private IDiscount discount;

    public void setDiscount(IDiscount discount) {
        this.discount = discount;
    }

    // 计算价格
    public void calculatePrice(double price, int quantity) {

        double sellPrice = price * quantity;
        String discountName = "default";

        if (discount != null) {
            discountName = discount.getClass().getName();
            sellPrice = discount.getPrice(price, quantity);
        }

        System.out.println("折扣方式: " + discountName + "  折后价格: " + sellPrice);

    }

}
  • 测试类
package cn.design.java.strategy;

public class Test {

    public static void main(String[] args) {

        // 折扣方式
        IDiscount reduceDis = new ReduceDis();
        IDiscount rebateDis = new RebateDis();
        DiscountStrategy discountStrategy = new DiscountStrategy();

        // 满减(满400立减40)
        ((ReduceDis) reduceDis).setCondition(400, 40);
        discountStrategy.setDiscount(reduceDis);
        discountStrategy.calculatePrice(138.5, 3);

        // 8.8折
        ((RebateDis) rebateDis).setDiscount(0.88);
        discountStrategy.setDiscount(rebateDis);
        discountStrategy.calculatePrice(138.5, 3);

        // default
        discountStrategy.setDiscount(null);
        discountStrategy.calculatePrice(138.5, 3);

    }
}
  • 打印结果

这里写图片描述

一个流程测试下来了,有没有发现 策略模式 有什么奇妙的地方?当然有,多了去了!现在看看测试类,这里我只需要将我需要打折的方式设置进去,就可以调用对应的折扣算法,每一种折扣方式的算法独立,就算修改算法实现方式,不会影响到 客户 的调用方式。这还不算什么,假如客户提出新的需求,添加一种新的折扣方式,没问题,新增一种折扣类,实现算法,调用的时候,直接 new 然后 setDiscount() ,OK,搞定,完全不会影响到之前的代码,哪怕之前的2种算法是谁写的,完全不用去理会。

以上是笔者对 策略模式 的一点点理解,记录下来当做笔记使用,如有不正之处,恳请指正出来,共同进步。

源码下载

猜你喜欢

转载自blog.csdn.net/u014702653/article/details/51377772
今日推荐