委派模式
精简程序逻辑,便于阅读
其基本作用是负责任务的调度和分配任务,和代理模式很像,可以看做是一种特殊情况下的静态代理的全权代理,但是代理模式注重过程,但是委派模式注重结果。
是一种行为型模式。
一般Delegate,Dispatcher结尾的都是委派
案例-老板叫员工干活
老板叫经理干活,经理通过不同的内容叫不同的员工去做事情
首先定义接口,把干活的内容抽象出来
public interface IEmployee {
public void doing(String command);
}
接下来定义员工a和员工B
public class EmployeeA implements IEmployee {
@Override
public void doing(String command) {
System.out.println("我是员工A,我现在开始干" + command + "工作");
}
}
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);
}
}
老板叫经理干活
public class Boss {
public void command(String command,Leader leader){
leader.doing(command);
}
}
测试
public class DelegateTest {
public static void main(String[] args) {
//客户请求(Boss)、委派者(Leader)、被被委派者(Target)
//委派者要持有被委派者的引用
//代理模式注重的是过程, 委派模式注重的是结果
//策略模式注重是可扩展(外部扩展),委派模式注重内部的灵活和复用
//委派的核心:就是分发、调度、派遣
//委派模式:就是静态代理和策略模式一种特殊的组合
new Boss().command("登录",new Leader());
}
}
这种方式能够避免我们使用if或者switch去判断
案例-请求分发
public class MemberController {
public void getMemberById(String mid){
}
}
public class OrderController {
public void getOrderById(String mid){
}
}
public class SystemController {
public void logout(){
}
}
在dispathcerServlet中进行对应的委派
private void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception{
String uri = request.getRequestURI();
String mid = request.getParameter("mid");
if("getMemberById".equals(uri)){
new MemberController().getMemberById(mid);
}else if("getOrderById".equals(uri)){
new OrderController().getOrderById(mid);
}else if("logout".equals(uri)){
new SystemController().logout();
}else {
response.getWriter().write("404 Not Found!!");
}
}
类图
策略模式
能够帮助我们消除程序中大量的if else 和switch语句
能够消除程序中大量冗余代码和多重条件转移语句
是指定义了算法家族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化不会影响到使用算法的用户。
适用场景
如果系统中有有很多类,他们的区别仅仅在于他们的行为不同。
一个系统需要动态的在几种算法中选择一种
优点
- 符合开闭原则
- 能够避免使用多重条件转移语句,如if else switch语句
- 使用策略模式可以提高算法的保密性和安全性
缺点
- 客户端必须知道所有策略,并自行决定使用哪一个策略类
- 代码中会产生很多策略类,增加维护难度
案例
购买商品有多种优惠:
- 无优惠
- 现金优惠
- 拼团优惠
首先定义接口
public interface PromotionStrategy {
void doPromotion();
}
团购优惠
public class GroupBuyStrategy implements PromotionStrategy {
public void doPromotion() {
System.out.println("组团,满20人成团");
}
}
无优惠
public class EmptyStrategy implements PromotionStrategy {
public void doPromotion() {
System.out.println("无优惠");
}
}
购物券优惠
public class CouponStrategy implements PromotionStrategy {
public void doPromotion() {
System.out.println("优惠券");
}
}
优惠活动
public class PromotionActivity {
PromotionStrategy promotionStrategy;
public PromotionActivity(PromotionStrategy promotionStrategy) {
this.promotionStrategy = promotionStrategy;
}
public void execute() {
promotionStrategy.doPromotion();
}
}
测试
public class PromotionActivityTest {
public static void main(String[] args) {
PromotionActivity promotionActivity = null;
String promotionKey = "COUPON";
if (StringUtils.equals(promotionKey, "COUPON")) {
promotionActivity = new PromotionActivity(new CouponStrategy());
} else if (StringUtils.equals(promotionKey, "CASH")) {
promotionActivity = new PromotionActivity(new CashbackStrategy());
}
promotionActivity.execute();
}
}
上述方式封装改为工厂方法
public class PromotionStrategyFactory {
private static Map<String, PromotionStrategy> PROMOTION_STRATEGY_MAP = new HashMap<>();
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_PROMOTIO = new EmptyStrategy();
public static PromotionStrategy getPromotionStrategy(String promotionKey) {
PromotionStrategy promotionStrategy = PROMOTION_STRATEGY_MAP.get(promotionKey);
return promotionStrategy == null ? NON_PROMOTIO : promotionStrategy;
}
private interface PromotionKey {
String COUPON = "COUPON";
String CASHBACK = "CASHBACK";
String GROUPBUY = "GROUPBUY";
}
}
测试类使用
public static void main(String[] args) {
PromotionStrategy promotionStrategy = PromotionStrategyFactory.getPromotionStrategy("COUPON");
PromotionActivity promotionActivity = new PromotionActivity(promotionStrategy);
promotionActivity.execute();
}