4.设计模式-委派模式以及策略模式

委派模式(Delegate Pattern)

  • 介绍:委派模式(Delegate Pattern)的基本作用就是负责任务的调度和分配任何,跟代理模式很像,可以看做是一种情况下的静态代理的的全权代理,但是代理模式注重过程,而委派模式注重结果
    不属于 23 中涉及模式之一
    属于行为型模式。
    java中Delegate 结尾的一般都是委派,包含Dispatcher 也是(spring 中DispatcherServlet就是使用委派模式)
  • 使用场景
    1. 一件事情(或一个请求)对象本身不知道怎样处理,对象把请求交给其它对象来做
  • 优点: 对内隐藏实现, 易于扩展; 简化调用。
  • 缺点:和静态代理的一样,当如果员工和leader类拓展的时候容易膨胀,难于管理。
//现实生活中也常有委 派的场景发生,例如:老板(Boss)给项目经理(Leader)下达任务,项目经理会根据 实际情况给每个员工派发工作任务,
//待员工把工作任务完成之后,再由项目经理汇报工 作进度和结果给老板。我们用代码来模拟下这个业务场景
public class Boss {

    public void command(String command,Leader leader){
        leader.doing(command);
    }

}


//实现一个接口,各自都有各自的工作
public interface ITarget {
    public void doing(String command);
}



public class Leader implements ITarget {

    private Map<String,ITarget> targets = new HashMap<String,ITarget>();
    // 初始化,会什么需要项目经理知道
    public Leader() {
        targets.put("加密",new TargetA());
        targets.put("登录",new TargetB());
    }

    //项目经理自己不干活
    public void doing(String command){
        targets.get(command).doing(command);
    }

}




public class TargetA implements ITarget {
    @Override
    public void doing(String command) {
        System.out.println("我是员工A,我现在开始干" + command + "工作");
    }
}



public class TargetB implements ITarget {
    @Override
    public void doing(String command) {
        System.out.println("我是员工B,我现在开始干" + command + "工作");
    }
}


// 客户端调用
public class DelegateTest {

    public static void main(String[] args) {

        //客户请求(Boss)、委派者(Leader)、被被委派者(Target)
        //委派者要持有被委派者的引用
        //代理模式注重的是过程, 委派模式注重的是结果
        //策略模式注重是可扩展(外部扩展),委派模式注重内部的灵活和复用
        //委派的核心:就是分发、调度、派遣

        //委派模式:就是静态代理和策略模式一种特殊的组合

        new Boss().command("登录",new Leader());
        //sout :我是员工B,我现在开始干登录工作

    }

}



策略模式(Strategy Pattern)

  • 介绍:策略模式(Strategy Pattern)是指定义了算法家族、分别封装起来,让它们之间可以互 相替换,此模式让算法的变化不会影响到使用算法的用户
  • 使用场景
    1. 假如系统中有很多类,而他们的区别仅仅在于他们的行为不同。
    2. 一个系统需要动态地在几种算法中选择一种。
  • 优点
    1. 策略模式符合开闭原则。
    2. 避免使用多重条件转移语句,如 if…else…语句、switch 语句
    3. 使用策略模式可以提高算法的保密性和安全性。
  • 缺点:
    1. 客户端必须知道所有的策略,并且自行决定使用哪一个策略类。
    2. 代码中会产生非常多策略类,增加维护难度。
// 以订单支付为例

//支付渠道 
public abstract class Payment {

    //支付类型
    public abstract String getName();

    //查询余额
    protected abstract double queryBalance(String uid);

    //扣款支付
    public MsgResult pay(String uid, double amount) {
        if(queryBalance(uid) < amount){
            return new MsgResult(500,"支付失败","余额不足");
        }
        return new MsgResult(200,"支付成功","支付金额:" + amount);
    }


}


// 多种支付
public class AliPay extends Payment {

    public String getName() {
        return "支付宝";
    }

    protected double queryBalance(String uid) {
        return 1998;
    }

}

public class JDPay extends Payment {

    public String getName() {
        return "京东支付";
    }

    protected double queryBalance(String uid) {
        return 998;
    }
}

//........



// 支付策略管理
public class PayStrategy {
    public static final String ALI_PAY = "AliPay";
    public static final String JD_PAY = "JdPay";
    public static final String DEFAULT_PAY = ALI_PAY;
    // ......

    private static Map<String,Payment> payStrategy = new HashMap<String,Payment>();
    static {
        payStrategy.put(ALI_PAY,new AliPay());
        payStrategy.put(JD_PAY,new JDPay());
        // .......
    }

    public static Payment get(String payKey){
        if(!payStrategy.containsKey(payKey)){
            return payStrategy.get(DEFAULT_PAY);
        }
        return payStrategy.get(payKey);
    }
}



// 支付完成以后的状态
public class MsgResult {
    private int code;
    private Object data;
    private String msg;

    public MsgResult(int code, String msg, Object data) {
        this.code = code;
        this.data = data;
        this.msg = msg;
    }

    public String toString(){
        return ("支付状态:[" + code + "]," + msg + ",交易详情:" + data);
    }
}


//订单
public class Order {
    private String uid;
    private String orderId;
    private double amount;

    // setget() \ constructron

    //完美地解决了switch的过程,不需要在代码逻辑中写switch了
    //更不需要写if    else if
    public MsgResult pay(){
        return pay(PayStrategy.DEFAULT_PAY);
    }

    public MsgResult pay(String payKey){
        Payment payment = PayStrategy.get(payKey);
        System.out.println("欢迎使用" + payment.getName());
        System.out.println("本次交易金额为:" + amount + ",开始扣款...");
        return payment.pay(uid,amount);
    }
}

//客户端调用
public class PayStrategyTest {

    public static void main(String[] args) {

        //省略把商品添加到购物车,再从购物车下单
        //直接从点单开始
        Order order = new Order("1","20180311001000009",324.45);

        //开始支付,选择微信支付、支付宝、银联卡、京东白条、财付通
        //每个渠道它支付的具体算法是不一样的
        //基本算法固定的

        //这个值是在支付的时候才决定用哪个值
        System.out.println(order.pay(PayStrategy.ALI_PAY));

        InstantiationStrategy

    }

}

// 策略模式 可以用以上的抽象类,也可以使用接口

//源码中涉及: Comparator接口   Arrays.parallelSort  \ TreeMap 构造方法等  
//策略模式还可以继承使用,请看:InstantiationStrategy\SimpleInstantiationStrategy\CglibSubclassingInstantiationStrategy


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值