@[toc]

Delegate pattern

Delegate mode, can simplify the program logic, improve the readability of code. The basic function of the Delegate Pattern is to invoke and assign tasks. For example, when the Boss assigns tasks to the project manager, the project manager will assign tasks to each employee according to the actual situation. After the employee completes the tasks, the project manager will report the work progress and results to the Boss.

And proxy mode

Much like the proxy pattern, it can be thought of as a carte Blanche of a static agent in a special case, but the proxy pattern focuses on the process, while the delegate pattern focuses on the outcome. The delegate pattern is widely used in Spring and is used in dispatcherServlets.

case

public interface IEmployee {
    void doing(String command);
}
Copy the code
Public class EmployeeA implements IEmployee {@override public void doing(String command) {system.out.println (" EmployeeA implements IEmployee {@override public void doing(String command) {system.out.println (" I'm going to command now. } } ```java public class EmployeeB implements IEmployee { @Override public void doing(String command) { System.out.println(" I am employee B, I am now doing "+ command +" work "); }}Copy the code
public class Leader implements IEmployee { private Map<String, IEmployee> targets = new HashMap<>(); Public Leader() {targets. Put (" login ", new EmployeeA()); Targets. Put (" encrypt ", new EmployeeB()); } @Override public void doing(String command) { targets.get(command).doing(command); }}Copy the code
public class Boss { public void command(String command, Leader leader) { leader.doing(command); }}Copy the code

Testing:

Public class DelegateTest {public static void main(String[] args) {public static void main(String[] args) { // Delegate mode is process oriented, delegate mode is result oriented // strategy mode is extensible (external extension), delegate mode is internal flexibility and reuse // The core of delegation is dispatch, dispatch, dispatch // Delegate mode: New Boss().command(" login ",new Leader()); New Boss().command(" encrypt ", new Leader()); }}Copy the code

Application scenarios

Write a DispatcherServlet: The method method that DispatcherServlet assigns to the corresponding controller based on the URL represents the delegate pattern.


public class DispatcherServlet extends HttpServlet {


    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            doDispatch(req, resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    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!!");
        }

    }Copy the code
public class MemberController { public void getMemberById(String mid){ System.out.println(mid); }}Copy the code
public class OrderController {

    public void getOrderById(String mid){
    }

}Copy the code
public class SystemController {

    public void logout(){

    }

}
Copy the code

The strategy pattern

introduce

A Strategy Pattern defines a family of algorithms and encapsulates them separately so that they can be replaced with each other, so that the changes of the algorithm will not affect the users who use the algorithm.

Application scenario of policy Pattern 1. Suppose there are many classes in the system, and they differ only in their behavior. A system needs to dynamically choose one of several algorithms.

Case 1.

Courses often have preferential activities, and there are many possible preferential strategies, such as: receiving coupons, cash back promotion, group discount. To simulate this in code, we first create an abstract PromotionStrategy of a PromotionStrategy

public interface PromotionStrategy {
    void doPromotion();
}Copy the code
/** * Created by HFL */ public class CashbackStrategy implements PromotionStrategy {@override public void DoPromotion () {system.out.println (" cash back promotion, return the amount to alipay account "); }}Copy the code
Public implements PromotionStrategy {@override public void doPromotion() { System.out.println(" to receive coupons, the price of the course is directly deducted from the coupon face value "); }}Copy the code
** / public implements PromotionStrategy {@override public void doPromotion() { System.out.println(" no promotion "); }}Copy the code
/** */ public class GroupbuyStrategy implements PromotionStrategy{@override public void doPromotion() { System.out.println(" group, full 20 people group, whole group enjoy group purchase price "); }}Copy the code

Favourable activity

public class PromotionActivity { private PromotionStrategy promotionStrategy; public PromotionActivity(PromotionStrategy promotionStrategy) { this.promotionStrategy = promotionStrategy; } public void execute(){ promotionStrategy.doPromotion(); }}Copy the code

Test 1:

public class PromotionActivityTest {
    public static void main(String[] args) {
        PromotionActivity activity618 = new PromotionActivity(new CouponStrategy());
        PromotionActivity activity1111 = new PromotionActivity(new CashbackStrategy());

        activity618.execute();
        activity1111.execute();
    }Copy the code

Which strategy mode should be selected according to front-end conditions:

public static void main(String[] args) { PromotionActivity promotionActivity = null; String promotionKey = "CASHBACK"; if(StringUtils.equals(promotionKey,"COUPON")){ promotionActivity = new PromotionActivity(new CouponStrategy()); }else if(StringUtils.equals(promotionKey,"CASHBACK")){ promotionActivity = new PromotionActivity(new CashbackStrategy()); } / /... promotionActivity.execute(); }Copy the code

In form, this test class is similar to a simple factory based on conditions. So we can change the method of simple factory optimization: write a simple factory class. For production policy classes:

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"; }}Copy the code

Rewrite the test class:

  public static void main(String[] args) {
        String promotionKey = "GROUPBUY";
        PromotionActivity promotionActivity = new PromotionActivity(PromotionStrategyFactory.getPromotionStrategy(promotionKey));
        promotionActivity.execute();
    }Copy the code

Case 2: Order payment strategy case

/** * public abstract class Payment {// Public abstract String getName(); // queryBalance protected abstract double queryBalance(String uid); Public MsgResult pay(String uid, Double amount){if(queryBalance(uid) < amount){return new MsgResult(500," failed to pay "," insufficient balance "); } return new MsgResult(200," paid successfully "," paid amount: "+ amount); }}Copy the code
Public class JDPay extends Payment {public String getName() {return "JDPay "; } protected double queryBalance(String uid) { return 500; }}Copy the code
Public class extends Payment {public String getName() {return "AliPay "; } protected double queryBalance(String uid) { return 900; }}Copy the code
Public class UnionPay extends Payment {public String getName() {return "UnionPay "; } protected double queryBalance(String uid) { return 120; }}Copy the code
Public class WechatPay extends Payment {public String getName() {return "WechatPay "; } protected double queryBalance(String uid) { return 256; }}Copy the code

Policy Class (most important)

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<String, Payment>();

    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(DEFAULT_PAY);
        }
        return payStrategy.get(payKey);
    }
}Copy the code

Response object after payment:

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 (" status: [" + code + "]," + MSG + ", "+ data"); }}Copy the code

Testing:

Public class PayStrategyTest {public static void main(String[] args) { Order Order = new Order("1","20180311001000009",324.45); // MsgResult pay = order.pay(paystrategy.jd_pay); // MsgResult pay = order. // system.out.println (order.pay(paystrategy.ali_pay)); // System.out.println(order.pay(paystrategy.ali_pay)); System.out.println(pay); // arrays.sort (); //Resource // InstantiationStrategy } }Copy the code

Switch to Alipay payment: Just change one parameter:

MsgResult pay = order.pay(PayStrategy.JD_PAY);Copy the code

The policy pattern is reflected in the JDK source code

ParallelSort method of the Arrays class, etc

The compare() method is a policy abstraction implementation.

public class Arrays {
public static <T> void parallelSort(T[] a, int fromIndex, int toIndex,
Comparator<? super T> cmp) {
}
}Copy the code
public interface Comparator<T> {
int compare(T o1, T o2);
}Copy the code

Advantages and disadvantages of strategic patterns

Advantages: 1. The strategy mode conforms to the open and close principle. 2. Avoid multiple conditional statements such as if… else… 3. The use of policy mode can improve the confidentiality and security of the algorithm. Disadvantages: 1. The client must know all the policies and decide which policy class to use. 2. There will be many policy classes in the code, which will increase the maintenance difficulty.

Delegate pattern and policy pattern are applied comprehensively

There must be more than just a few controllers in the actual project, usually thousands of controllers, obviously, we can’t write thousands of if… else… . So how do we do it? We do it strategically:

public class DispatcherServlet extends HttpServlet { private List<Handler> handlerMapping = new ArrayList<Handler>(); @Override public void init() throws ServletException { try { Class<? > memberControllerClass = MemberController.class; handlerMapping.add(new Handler() .setController(memberControllerClass.newInstance()) .setMethod(memberControllerClass.getMethod("getMemberById", new Class[]{String.class})) .setUrl("/web/getMemberById.json")); } catch (Exception e) { } } @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { doDispatch(req, resp); } catch (Exception e) { e.printStackTrace(); } } private void doDispatch(HttpServletRequest request, HttpServletResponse Response) throws IOException {// if a Serlvet is set for each pair of urls, Url The browser enters String uri = request.getrequesturi (); // Based on the url requested by the user, // Find the url corresponding to a Java class method //3, get the URL to handlerMapping (we consider this as a policy constant) Handler handle = null; for (Handler h : handlerMapping) { if (uri.equals(h.getUrl())) { handle = h; break; } //4, assign the task to Method (by reflection) Object Object = null; try { object = handle.getMethod().invoke(handle.getController(), request.getParameter("mid")); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); Response.getwriter ().write(""); } class Handler { private Object controller; private Method method; private String url; public Object getController() { return controller; } public Handler setController(Object controller) { this.controller = controller; return this; } public Method getMethod() { return method; } public Handler setMethod(Method method) { this.method = method; return this; } public String getUrl() { return url; } public Handler setUrl(String url) { this.url = url; return this; }}}Copy the code

Summary: 1. Using the delegate pattern, you can write more elegant code. 2. Strategy mode, can eliminate a lot of redundant code and multiple conditional transfer statements in the program. 3. Delegation mode belongs to behavioral mode, and its basic function is to be responsible for the scheduling and assignment of tasks. Similar to the agent mode, delegation mode can be regarded as the full agent of a static agent in special cases, but the agent mode focuses on the process, while the delegation mode focuses on the results. 4. Strategy Pattern is behavioral Pattern :(Strategy Pattern) it defines algorithm families and encapsulates them separately so that they can be replaced with each other, so that the change of the algorithm will not affect the users who use the algorithm. Can avoid multiple branches of if… else… And switch statements.


Personal wechat public number: search: in full bloom de every day irregular push related articles, look forward to growing up with you!!


After the

Thank you for your support