当前位置: 代码迷 >> 综合 >> 设计模式之委派模式和策略模式
  详细解决方案

设计模式之委派模式和策略模式

热度:35   发布时间:2024-02-27 23:45:52.0

一、委派模式

        委派模式(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();

具体用到的哪一种活动是前端传入的参数,这样的话就不影响原来的处理逻辑了?!

  相关解决方案