委派模式及策略模式
目标:
- 掌握委派模式,精简程序逻辑,提升代码的可读性。
- 通过学习策略模式来消除程序中大量的if … else 和 switch 语句。
- 深刻理解策略模式的应用场景,提高算法的保密性和安全性
内容定位:
- 希望通过对委派模式的学习,让自己写出更加优雅的代码的人群
- 希望通过对策略模式的学习,来消除程序中大量的冗余代码和多重条件转移的语句
委派模式的基本作用就是负责任务的调度和分配任务,跟代理模式很像,可以看做是一种特殊情况下的静态代理的全权代理,但是代理模式注重过程,而委派模式注重结果
不属于GOF 23种设计模式之一
属于行为型模式。
BOSS
经理
员工A 员工B 员工C
代理更注重过程。 委派注重结果
delegate
// boss
public class Boss {
public void command(String command, Leader leader){
leader.doing(command);
}
}
// 经理
public class Leader{
// 预先知道每个员工的特长,特征,分发任务
private Map<String ,IEmployee> register = new HashMap();
public Leader() {
register.put("加密", new EmployeeA());
register.put("架构", new EmployeeB());
}
public void doing(String command) {
register.get(command).doing();
}
}
public interface IEmployee{
}
public class EmployeeA implements Iemployee {
public void doing(String command) {
System.out.println("员工Adoing");
}
}
1.Spring 中以Delegate结尾的一般都是委派,
2. DispatcherServlet
public class DispatcherServlet extends HttpServlet{
public void service(HttpServletRequest request,HttpServletResponse response) throws ServletException {
// 完成调度
doDispatch(request);
}
private void doDispatch(HttpServletRequest request) {
String uri = req.getRequestURI();
String mid = request.getParameter("mid");
// 调用到相应的Controller
if("getMemberById".equals(uri)) {
new MemberController().getMemberById(mid);
}
}
}
public class MemberController{
public void getMemberById(String mid) {
}
}
public class OrderController{
public void getOrderById(String oid) {
}
}
BeanDefinitionParseDelegate
策略模式:
是指定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化不会影响到使用算法的用户。
可以避免多重分支,if else
应用场景:
- 假如系统中有很多类,而他们的区别仅仅在于他们的行为不同
- 一个系统需要动态地在几种算法中选择一种
// 优惠策略的抽象
public interface PromotionStrategy{
void doPromotion();
}
// 无优惠
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 PromotiionActivity(PromotionStrategy promotionStrategy ) {
this.promotionStrategy =promotionStrategy;
}
public void execute(){
this.promotionStrategy.doPromotion();
}
}
public classs PromotionActivityTest{
public static void main(String[] args) {
PromotionActivity activityCoupon = new PromotionActivity(new CouponStrategy );
activityCoupon.execute();
PromotionActivity activityEmpty = new PromotionActivity(new EmptyStrategy() );
activityEmpty.execute();
}
}
public class PromotionStrategyFactory{
private static Map<String, PromotionStrategy> map = new ..;
static{
map.put();
// ...
}
public static PromotionStrategy get(String key){
return map.get(key);
}
}
public class Order {
private String uid.
private String orderId;
private double amount;
public Order(String uid, String orderId,double amount) {
this.uid = uid;
this.orderId= orderId;
this.amount = amount;
}
public MsgResult pay(String payKey) {
return null;
}
}
public class MsgResult {
private int code;
private Object data;
private String msg;
// all args cons..
}
public abstract class Payment {
public abstract String getName();
protected abstract double queryBalance(String uid);
public MsgResult pay(String uid,double amount) {
if(queryalance(uid) < amount) {
return new MsgResult(500,"支付失败,余额不足");
}
}
}
策略模式在源码中的体现
int Comparator.compare(T o1, T o2);
Arrays.sort();
TreeMap(Compa rator comparator){
}
spring core io包中的 Resource 接口
InstantiationStrategy
cglib
simpleInstantiation
策略模式的优点:
-
策略模式符合开闭原则
-
避免使用多重条件转移语句 如 if … else … 语句 、switch语句
-
使用策略模式可以提高算法的保密性和安全性
缺点: -
客户端必须知道所有的策略,并且自行决定使用哪一个策略类。
-
代码中会产生非常多的策略类,增加维护难度
springmvc 一个url对应一个controller
private List HandlerMappting = new ArrayList();
doDispatch {
String uri = request.getRequestURI();
}
init() {
try {
Class<?> memberController = MemberController.class;
handerMappring.add(new Handler().setController(memberController .newInstance()).setMethod(memberController .getMethod(“getMemberById”,new Classs[]{String.class})).setUrl(“getMemberById.json”));
}
}catch(Exeception e)
{
e.printStack();
}
class Handler {
private Object controller;
private Method method;
private String url;
// getter setter
}
欢迎入群技术交流: