策略模式是针对对象行为的一种模式。即将对象具有多种实现的行为单独抽取出来。实现行为的修改不会触及到原有对象的变动。
简单举个例子:
现在正在构建一个商城系统,我们有顾客对象,他拥有购买物品可以打折的行为;
public class Customer {
public void discount(){
System.out.println("给顾客打折");
}
}
但是我们知道所有顾客都可以打折,但不同顾客可打折额度是不同的,此时我们可将discount()方法抽取出来作为一个接口:
public interface DiscountRight {
void discount();
}
业务需求是共计有三种不同权限的折扣,所以我们接着分别实现这三种折扣权:
第一种钻石折扣权:
public class DiamondDiscountRight implements DiscountRight{
@Override
public void discount() {
System.out.println("给尊贵的钻石级会员打1折,亏本也愿意!");
}
}
第二种黄金折扣权:
public class GoldDiscountRight implements DiscountRight{
@Override
public void discount() {
System.out.println("给优秀的黄金会员打个6折,良心折扣,少赚多销");
}
}
第三种白银折扣权:
public class SilverDiscountRight implements DiscountRight{
@Override
public void discount() {
System.out.println("白银会员勉强给个折扣意思意思吧,打9折");
}
}
三种不同的折扣行为都实现好了,接下来我们重写Customer类:
public class Customer {
public void discountPerform(DiscountRight discountRight){
discountRight.discount();
}
}
在重写的代码里我们就已将对打折的这一具体行为,交给了DiscountRight处理,而不是最早的由Customer来实现了。
接下来实现不同的Customer类:
public class Begin {
public static void main(String[] args) {
FirstCustomer firstCustomer=new FirstCustomer();
SecondCustomer secondCustomer=new SecondCustomer();
ThirdCustomer thirdCustomer=new ThirdCustomer();
firstCustomer.discountPerform(new GoldDiscountRight());
secondCustomer.discountPerform(new DiamondDiscountRight());
thirdCustomer.discountPerform(new SilverDiscountRight());
}
}
class FirstCustomer extends Customer{}
class SecondCustomer extends Customer{}
class ThirdCustomer extends Customer{}
这样一样我们就简单实现了策略模式的编写;
总结:
1.既然每个人的打折不同,那在父类里将discount()写作抽象的,让继承的子类自行实现不就可以了么,何必要抽象成接口,然后又对接口写各自的实现类这么麻烦?
如果我们有更多的顾客量,例如一万个,但是打折的种类只有3中,通过继承实现,不就重复了很多相同的代码么;
2.那我在Customer的子类继承时,先实现三个针对不同打折的子类,在子类里实现三种对应的折扣。我再针对继承对应的子类不就避免了上面的重复了么?
在简单的只有打折这个行为变化时这么做是没问题的。但是实际上一个对象可能同时有多种行为变化。举例说:对象不仅具有打折,还具有抽奖。打折有三种,抽奖次数不同总计有五种。这时候如果通过子类扩展实现来分类,我们需要编写15种子类才能覆盖完全。。。。
策略模式缺点:
我们需要针对不同的行为实现多个具体类,类的数目大幅度增加。
并且我们将具体使用哪种策略的决定抛给了调用方。所以调用方必须要清楚实现的多种具体策略有何不同。
针对类数目大幅度增加,我们可以将一些共有的策略提供给其它对象使用。例如:这里商城客户可以打折,内部员工也可以打折。他们可以共用提取出的打折等级体系来打折