委派模式,策略模式
委派模式
特点:
-
类似于中介的功能(委托机制);
-
持有被委托人的引用。
-
不关心过程,只关心结果。(与代理模式的不同)
策略模式注重是可扩展(外部扩展),委派模式注重内部的灵活和复用
委派的核心:就是分发、调度、派遣
委派模式:就是静态代理和策略模式一种特殊的组合
隐藏具体实现逻辑,看上去是在做其实是别人在做,可以动态的指定让谁执行
工厂模式针对是bean,不是具体的方法
public interface IExe {
void doing();
}
/**
* 员工A
*/
public class StaffA implements IExe {
@Override
public void doing() {
System.out.println("doing....");
}
}
/**
* 经理
*/
public class Manager implements IExe{
private IExe iExe;
public Manager(IExe iExe) {
this.iExe = iExe;
}
@Override
public void doing() {
this.iExe.doing();
}
}
/**
*委派模式(delegate)
*
* 特点:
* 1、类似于中介的功能(委托机制);
* 2、持有被委托人的引用。
* 3、不关心过程,只关心结果。(与代理模式的不同)
* 隐藏具体实现逻辑,看上去是在做其实是别人在做,可以动态的指定让谁执行
* 工厂模式针对是bean,不是具体的方法
*/
public class Test {
public static void main(String[] args){
Manager manager = new Manager(new StaffA());
//看上去是manager在做其实是StaffA在做
manager.doing();
}
}
委派模式不属于 GOF23 种设计模式中。委派模式(Delegate Pattern)的基本作用就是 负责任务的调用和分配任务,跟代理模式很像,可以看做是一种特殊情况下的静态代理 的全权代理,但是代理模式注重过程,而委派模式注重结果。委派模式在 Spring 中应用 非常多,大家常用的 DispatcherServlet 其实就是用到了委派模式。
在 Spring 源码中,只要以 Delegate 结尾的 都是实现了委派模式
#### 策略模式
策略模式(Strategy Pattern)是指定义了算法家族、分别封装起来,让它们之间可以互 相替换,此模式让算法的变化不会影响到使用算法的用户
#####应用场景
1. 假如系统中有很多类,而他们的区别仅仅在于他们的行为不同。
2. 一个系统需要动态地在几种算法中选择一种。
/**
* 策略模式
* 过程不同,但结果一样
*/
public class Test {
public static void main(String[] args){
List<Long> nums = new ArrayList<>();
Collections.sort(nums, new Comparator<Long>() {
//返回值是固定的
//0 、-1 、1
//0 、 >0 、<0
@Override
public int compare(Long o1, Long o2) {
// 中间逻辑是不一样的
return 0;
}
});
}
}
策略模式 支付案例
/**
* 支付完成的状态
*/
public class PayState {
private int code;
private Object data;
private String msg;
public PayState(int code, Object data, String msg) {
this.code = code;
this.data = data;
this.msg = msg;
}
public String toString(){
return ("支付状态:[" + code + "]," + msg + ",交易详情:" + data);
}
}
/**
* 支付渠道
*/
public abstract class Payment {
//支付类型
public abstract String getName();
//查询余额
protected abstract double queryBalance(String uid);
//扣款支付
public PayState pay(String uid,double amount){
if (queryBalance(uid)<amount){
return new PayState(500,"支付失败","余额不足");
}
return new PayState(200,"支付成功","支付金额:" + amount);
}
}
public class AliPay extends Payment {
@Override
public String getName() {
return "支付宝";
}
@Override
protected double queryBalance(String uid) {
return 1000;
}
}
public class JDPay extends Payment {
@Override
public String getName() {
return "京东白条";
}
@Override
protected double queryBalance(String uid) {
return 500;
}
}
public class UnionPay extends Payment {
@Override
public String getName() {
return "银联支付";
}
@Override
protected double queryBalance(String uid) {
return 100;
}
}
public class WechatPay extends Payment {
@Override
public String getName() {
return "微信支付";
}
@Override
protected double queryBalance(String uid) {
return 200;
}
}
/**
* 支付策略管理
*/
public class PayStrategy {
public static final String ALI_PAY = "AliPay";
public static final String JD_PAY = "JdPay";
public static final String UNION_PAY = "UnionPay";
public static final String WECHAT_PAY = "WechatPay";
public static final String DEFAULT_PAY = ALI_PAY;
private static Map<String,Payment> payStrategy = new HashMap<>();
static {
payStrategy.put(ALI_PAY,new AliPay());
payStrategy.put(WECHAT_PAY,new WechatPay());
payStrategy.put(UNION_PAY,new UnionPay());
payStrategy.put(JD_PAY,new JDPay());
}
public static Payment get(String payKey){
if (payStrategy.containsKey(payKey)){
return payStrategy.get(payKey);
}
return payStrategy.get(DEFAULT_PAY);
}
}
/**
* 订单
*/
public class Order {
private String uid;
private double amount;
public Order(String uid, double amount) {
this.uid = uid;
this.amount = amount;
}
public PayState pay(){
return pay(PayStrategy.DEFAULT_PAY);
}
public PayState pay(String payKey){
Payment payment = PayStrategy.get(payKey);
System.out.println("欢迎使用" + payment.getName());
System.out.println("本次交易金额为:" + amount + ",开始扣款...");
return payment.pay(uid,amount);
}
}
测试
public class Test {
public static void main(String[] args){
Order order = new Order("1",210);
System.out.println(order.pay(PayStrategy.ALI_PAY));
//欢迎使用支付宝
//本次交易金额为:210.0,开始扣款...
//支付状态:[200],支付金额:210.0,交易详情:支付成功
}
}
策略模式的优缺点
- 优点:
1、策略模式符合开闭原则。
2、避免使用多重条件转移语句,如 if...else...语句、switch 语句
3、使用策略模式可以提高算法的保密性和安全性。 - 缺点:
1、客户端必须知道所有的策略,并且自行决定使用哪一个策略类。
2、代码中会产生非常多策略类,增加维护难度。