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
TreeMap.class
- 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
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
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:
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 .