一、委派模式
委派模式(Delegate Pattern)的基本作用就是负责任务的调用和分配任务,跟代理模式很像,可以看做是一种特殊情况下的静态代理的全权代理,但是代理模式注重过程,而委派模式注重结果。
举例:
老板(Boss)给项目经理(Leader)下达任务,项目经理会根据 实际情况给每个员工派发工作任务,待员工把工作任务完成之后,再由项目经理汇报工作进度和结果给老板。
创建员工IEmployee接口
public interface IEmployee {
public void doing(String command);
}
创建员工EmployeeA类
public class EmployeeA implements IEmployee {
@Override
public void doing(String command) {
System.out.println("我是员工A,我现在开始干" + command + "工作");
}
}
创建员工EmployeeB类
public class EmployeeB implements IEmployee {
@Override
public void doing(String command) {
System.out.println("我是员工B,我现在开始干" + command + "工作");
}
}
创建项目经理的类
public class Leader implements IEmployee {
private Map<String,IEmployee> targets = new HashMap<String,IEmployee>();
public Leader() {
targets.put("加密",new EmployeeA());
targets.put("登录",new EmployeeB());
}
//项目经理自己不干活
public void doing(String command){
targets.get(command).doing(command);
}
}
创建Boss类下达命令
public class Boss {
public void command(String command,Leader leader){
leader.doing(command);
}
}
测试代码类
new Boss().command("登录",new Leader());
上述代码能够很好的反映项目经理分配工作的场景,也是委派模式的体现。
二、策略模式
策略模式(Strategy Pattern)是指定义了算法家族、分别封装起来,让它们之间可以互 相替换,此模式让算法的变化不会影响到使用算法的用户。
应用场景
-
假如系统中有很多类,而他们的区别仅仅在于他们的行为不同
-
一个系统需要动态地在几种算法中选择一种
优点:
-
策略模式符合开闭原则。
-
避免使用多重条件转移语句,如if...else...语句、switch语句
-
使用策略模式可以提高算法的保密性和安全
缺点:
-
客户端必须知道所有的策略,并且自行决定使用哪一个策略类。
-
代码中会产生非常多策略类,增加维护难度
举例
京东商城有时候会有很多优惠活动,比如:领取优惠券抵扣、返现促销、拼团优惠
创建促销策略类
public interface PromotionStrategy {
void doPromotion();
}
然后分别创建优惠券抵扣策略 CouponStrategy 类、返现促销策略 CashbackStrategy 类、拼团优惠策略 GroupbuyStrategy 类和无优惠策略 EmptyStrategy 类:
public class CashbackStrategy implements PromotionStrategy {
public void doPromotion() {
System.out.println("返现促销,返回的金额转到支付宝账号");
}
}
public class CouponStrategy implements PromotionStrategy {
public void doPromotion() {
System.out.println("领取优惠券,课程的价格直接减优惠券面值抵扣");
}
}
public class EmptyStrategy implements PromotionStrategy {
public void doPromotion() {
System.out.println("无促销活动");
}
}
public class GroupbuyStrategy implements PromotionStrategy{
public void doPromotion() {
System.out.println("拼团,满20人成团,全团享受团购价");
}
}
创建促销活动类
public class PromotionActivity {
private PromotionStrategy promotionStrategy;
public PromotionActivity(PromotionStrategy promotionStrategy) {
this.promotionStrategy = promotionStrategy;
}
public void execute(){
promotionStrategy.doPromotion();
}
}
测试类
PromotionActivity activity618 = new PromotionActivity(new CouponStrategy());
PromotionActivity activity1111 = new PromotionActivity(new CashbackStrategy());
activity618.execute();
activity1111.execute();
上述代码验证没有问题,但是实际情况若是出现很多活动,那么我们就需要更改验证,所以我们可以优化下,结合单例和工厂模式做下重构
创建工厂类
public class PromotionStrategyFactory {
private static Map<String,PromotionStrategy> PROMOTION_STRATEGY_MAP = new HashMap<String, PromotionStrategy>();
static {
PROMOTION_STRATEGY_MAP.put(PromotionKey.COUPON,new CouponStrategy());
PROMOTION_STRATEGY_MAP.put(PromotionKey.CASHBACK,new CashbackStrategy());
PROMOTION_STRATEGY_MAP.put(PromotionKey.GROUPBUY,new GroupbuyStrategy());
}
private static final PromotionStrategy NON_PROMOTION = new EmptyStrategy();
private PromotionStrategyFactory(){}
public static PromotionStrategy getPromotionStrategy(String promotionKey){
PromotionStrategy promotionStrategy = PROMOTION_STRATEGY_MAP.get(promotionKey);
return promotionStrategy == null ? NON_PROMOTION : promotionStrategy;
}
private interface PromotionKey{
String COUPON = "COUPON";
String CASHBACK = "CASHBACK";
String GROUPBUY = "GROUPBUY";
}
客户端代码可以这样写
String promotionKey = "GROUPBUY";
PromotionActivity promotionActivity = new PromotionActivity(PromotionStrategyFactory.getPromotionStrategy(promotionKey));
promotionActivity.execute();
具体用到的哪一种活动是前端传入的参数,这样的话就不影响原来的处理逻辑了!