The design pattern under Linux-Strategy Pattern (StrategyPattern) explain in simple terms [Recommended for novice collection]

1. Introduction to Strategy Mode

Strategy mode definition : refers to the definition of the algorithm family, separately encapsulated, so that they can be replaced with each other, this mode makes the algorithm changes will not affect the users of the algorithm

Advantages of the strategy mode : multiple branches of if...else... and switch statements can be avoided

Use scenarios of strategy mode :

  • If there are many classes in the system, and their difference lies in their behavior.
  • A system needs to dynamically choose one of several algorithms.

Strategy mode case :

The int compare(T o1, T o2); method in the Comparator interface of JDK, the collation rules can be customized in Arrays and TreeMap

Arrays.class
Insert picture description here
TreeMap.class
Insert picture description here

  • Resource interface in Spring
  • The InstantiationStrategy interface in Spring mainly initializes the strategy for the class. There are two strategy implementation classes, which are not equal but inherited (different strategies in the strategy mode can also be inherited)

CglibSubclassingInstantiationStrategy : the initial way of
Cglib SimpleInstantiationStrategy : the initial way of JDK

Class Diagram
Insert picture description here

Two, simple code case

Case : When there are activities to purchase something, there will be strategies for reducing the amount of vouchers, cash back, group joining, etc.

Preferential strategy abstract interface


public interface PromotionStrategy {
    
    

    /**
     * 执行优惠
     */
    void doPromotion();
}

No discount

public class EmptyStrategy implements PromotionStrategy{
    
    
    @Override
    public void doPromotion() {
    
    
        System.out.println("无促销活动");
    }
}

Voucher

public class CouponStrategy implements PromotionStrategy {
    
    
    @Override
    public void doPromotion() {
    
    
        System.out.println("领取优惠券,课程的价格直接减去优惠券面值抵扣");
    }
}

Cash back

public class CashbackStrategy implements PromotionStrategy {
    
    
    @Override
    public void doPromotion() {
    
    
        System.out.println("返现促销,返回的金额转到支付宝账号");
    }
}

Join a group

public class GroupBuyStrategy implements PromotionStrategy{
    
    
    @Override
    public void doPromotion() {
    
    
        System.out.println("拼团,满20人成团,全团享受团购价格");
    }
}

Promotions

public class PromotionActivity {
    
    

    PromotionStrategy promotionStrategy;

    public PromotionActivity(PromotionStrategy promotionStrategy){
    
    
        this.promotionStrategy = promotionStrategy;
    }

    /**
     * 执行优惠活动
     */
    public void execute(){
    
    
        this.promotionStrategy.doPromotion();
    }
}

Test one

public static void main(String[] args) {
    
    
//        618优惠券活动
        PromotionActivity activity618 = new PromotionActivity(new CouponStrategy());
        activity618.execute();
//        双11返现活动
        PromotionActivity activity1111 = new PromotionActivity(new CashbackStrategy());
        activity1111.execute();

    }

Test two

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,"CASHBACK")){
    
    
            promotionActivity = new PromotionActivity(new CashbackStrategy());
        } // .......

        promotionActivity.execute();
    }

After simply implementing the discovery, you can also simplify the code through the singleton mode + simple factory mode, and use the unique sign to select the strategy

Factory class

public class PromotionStrategyFactory {
    
    

    private static final Map<String,PromotionStrategy> PROMOTION_STRATEGY_MAP = new ConcurrentHashMap<String,PromotionStrategy>();

    private static final PromotionStrategy NON_PROMOTION = new EmptyStrategy();

    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 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";

    }
}

test

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

Attach the class structure diagram
Insert picture description here

Three, simple code two case

Case : Users can choose multiple payment channels when placing orders

Payment abstract class

public abstract class Payment {
    
    

    /**
     * 支付信息
     * @return
     */
    public abstract String getName();

    /**
     * 余额
     * @param uid
     * @return
     */
    protected abstract double queryBalance(String uid);

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

Pay with Ali-Pay

public class AliPay extends Payment{
    
    
    @Override
    public String getName() {
    
    
        return "支付宝";
    }

    @Override
    protected double queryBalance(String uid) {
    
    
        return 900;
    }
}

Jingdong Baitiao

public class JDPay extends Payment{
    
    
    @Override
    public String getName() {
    
    
        return "京东白条";
    }

    @Override
    protected double queryBalance(String uid) {
    
    
        return 500;
    }
}

UnionPay payment

public class UnionPay extends Payment {
    
    
    @Override
    public String getName() {
    
    
        return "银联支付";
    }

    @Override
    protected double queryBalance(String uid) {
    
    
        return 120;
    }
}

WeChat Pay

public class WechatPay extends Payment {
    
    
    @Override
    public String getName() {
    
    
        return "微信支付";
    }

    @Override
    protected double queryBalance(String uid) {
    
    
        return 256;
    }
}

Return message

public class MsgResult {
    
    

    private int code;
    private Object data;
    private String msg;

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

    @Override
    public String toString() {
    
    
        return "MsgResult{" +
                "code=" + code +
                ", data=" + data +
                ", msg='" + msg + '\'' +
                '}';
    }
}

Order class

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){
    
    
        Payment payment = PayStrategy.get(payKey);
        System.out.println("欢迎使用" + payment.getName());
        System.out.println("本次交易金额为:" + amount + ",开始扣款...");
        return payment.pay(uid,amount);
    }

    @Override
    public String toString() {
    
    
        return "Order{" +
                "uid='" + uid + '\'' +
                ", orderId='" + orderId + '\'' +
                ", amount=" + amount +
                '}';
    }
}

Payment strategy factory

public class PayStrategy {
    
    

    public static final String ALI_PAY = "AliPay";
    public static final String JD_PAY = "JDPay";
    public static final String WECHAT_PAY = "WchatPay";
    public static final String UNION_PAY = "UnionPay";
    public static final String DEFAULT_PAY = "AliPay";

    private static Map<String,Payment> payStrategy = new HashMap<String,Payment>();

    static {
    
    
        payStrategy.put(ALI_PAY,new AliPay());
        payStrategy.put(JD_PAY,new JDPay());
        payStrategy.put(WECHAT_PAY,new WechatPay());
        payStrategy.put(UNION_PAY,new UnionPay());
        payStrategy.put(DEFAULT_PAY,new AliPay());
    }

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

    }
}

test

public class PayStrategyTest {
    
    

    public static void main(String[] args) {
    
    
        Order order = new Order("1", "2021110", 1342.45);
        MsgResult result = order.pay(PayStrategy.ALI_PAY);
        System.out.println(result);
    }

}

Attach the class structure diagram:
Insert picture description here

Four, summary

Advantages of strategy mode:

  • The strategy mode conforms to the principle of opening and closing.
  • Avoid using multiple conditional transfer statements, such as if...else...statements, switch statements.
  • Using strategy mode can improve the confidentiality and security of the algorithm.

Disadvantages of strategy mode:

  • The client must know all the strategies, and the user decides which strategy class to use.
  • There are many strategy classes in the code, which increases the difficulty of maintenance.

What are you waiting for? I recommend my linuxC/C++ language exchange group: [ 1106675687 ] I have compiled some learning books and video materials that I think are better to share in the group files, and you can add them if you need them! The top 100 enter the group to receive, an extra copy of C/C++, linux materials worth 199 is included (video tutorials, e-books, actual combat projects and codes), the following part is displayed .
Insert picture description here
Insert picture description here

Guess you like

Origin blog.csdn.net/m0_50662680/article/details/112474679