哲学上说存在即合理。一些初级程序员,包括笔者也曾经在内心说过:“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种算法是谁写的,完全不用去理会。
以上是笔者对 策略模式 的一点点理解,记录下来当做笔记使用,如有不正之处,恳请指正出来,共同进步。