编程是一门艺术,大批量的改动显然是非常丑陋的做法,用心的琢磨写的代码让它变的更美观。
在现实生活中常常遇到实现某种目标存在多种策略可供选择的情况,例如超市促销可以釆用打折、送商品、送积分等方法。
在软件开发中也常常遇到类似的情况,当实现某一个功能存在多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能,如数据排序策略有快速排序、归并排序、选择排序、二叉树排序等。
如果使用多重条件转移语句实现(即硬编码),不但使条件语句变得很复杂,而且增加、删除或更换算法要修改原代码,不易维护,违背开闭原则。如果采用策略模式就能很好解决该问题。
策略(Strategy)模式:该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。
策略模式的主要优点:
策略设计模式的不足:
客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。
策略模式造成很多的策略类,增加维护难度。
策略模式是准备一组算法,并将这组算法封装到一系列的策略类里面,作为一个抽象策略类的子类。策略模式的重心不是如何实现算法,而是如何组织这些算法,从而让程序结构更加灵活,具有更好的维护性和扩展性。
策略设计模式涉及的角色:
抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。
环境(Context)类:持有一个策略类的引用,最终给客户端调用。
/**
* 折扣
*/
public interface Discount {
/**
* 计算价格
* @param money
* @return
*/
public int calculate(int money);
}
/**
* 满减策略
* 需要满200
*/
public class FullDiscount implements Discount{
@Override
public int calculate(int money) {
if (money>200){
System.out.println("符合满减策略,进行满减");
return money - 30;
}
return money;
}
}
/**
* 假日折扣
* 需要大于100
*/
public class HolidayDiscount implements Discount{
@Override
public int calculate(int money) {
if (money > 100){
return money - 10;
}
return money;
}
}
/**
* 新用户减免
* 但是也需要大于100
*/
public class NewerDiscount implements Discount{
@Override
public int calculate(int money) {
if (money>100){
return money-20;
}
return money;
}
}
/**
* 第二单8折优惠
*/
public class SecondDiscount implements Discount {
@Override
public int calculate(int money) {
Double balance = money * 0.8;
return balance.intValue();
}
}
public static void main(String[] args) {
List<Fruit> products = new ArrayList();
products.add(StaticFactory.getFruitApple());
products.add(StaticFactory.getFruitBanana());
products.add(StaticFactory.getFruitOrange());
ShoppingCart cart = new CartShopping(products);
/*注入优惠方案*/
cart.setDiscount(new FullDiscount());
cart.submitOrder();
}
在程序设计中,通常在以下几种情况中使用策略模式较多: