Design patterns must know and know: strategy patterns

This article introduces the optimization of the strategy model to the if-else business dispatch logic

Application scenario

I recently wrote a service: query the grantType according to the coupon type resourceType and code resourceId

Method to realize:

  • Determine which data table to query according to the coupon type resourceType ->
  • According to the encoding resourceId -> query grantType

There are many types of coupons, corresponding to different database tables:

  • Red envelope
  • Shopping voucher
  • QQ member
  • Takeaway members

The actual coupons are much more than these, this demand is for us to write oneBusiness assignmentLogic of

The first idea is generally if-else, swtich case:

switch(resourceType){
    
    
	case "红包": 
		查询红包的派发方式 
		break;
	case "购物券": 
		查询购物券的派发方式
		break;
	case "QQ会员" :
		...
		break;
	case "外卖会员" :
		...
		break;
		
	......
	default : logger.info("查找不到该优惠券类型resourceType以及对应的派发方式");
		break;
}

There is a downside to writing if-else like this:

  • That is, if there are many judgments and the code of a single if statement block is too many lines , then the entire if-else code block is too long and the readability is reduced.
  • And because the entire if-else code has many lines, it is inconvenient to modify and maintainability is low.

Then we try to the if-elseBusiness assignment Logic optimization

Strategy mode

I don’t think about the definition. To speak, the structure of the strategy model is:

  • A public abstract class/interface that supports all algorithms : that is, after any if is judged, the method of the interface will be executed
  • The implementation class of the specific strategy: the logic for querying the red envelope distribution method is written in one class, and the shopping coupon is written in another class
  • The entrance of the client call: By holding a reference to a public interface , polymorphism is used to execute a specific strategy algorithm when creating an object.

Above code:

One, public interface

public abstract class Strategy{
    
    
    //定义支持所有算法的公共接口
    public abstract String query();
}

When the client executes a specific strategy,Strategy strategy = new ConcreteStrategy01()

Second, the specific strategy implementation class

Inherit the public interface and add content to the abstract methods inside:

Query the distribution method of red envelopes :

//查询红包redPaper 发放方式
class ConcreteStrategy01 extends Strategy{
    
    
    public  String query(){
    
    
    	return "每周末9点发放";
    }
}

Query the issuance method of shopping vouchers :

//查询购物券shopping的发放方式
class ConcreteStrategy02 extends Strategy{
    
    
    public  String query(){
    
    
    	return "每周三20点发放";
    }
}

Three, the entrance of the client call

To hold public interface reference, or can not pass polymorphism new ConcreteStrategy01() 或者 new ConcreteStrategy02()to achieve specific policy implementation [red envelopes of query, the query coupons]

class Context{
    
    
    //持有公共接口的引用,后续通过多态来获取[红包、购物券]的实现类
    Strategy strategy;
    public Context(Strategy strategy){
    
    
        this.strategy=strategy;
    }
    public String ContextInterface(){
    
    
        return strategy.query();
    }
}

The client implements specific strategies:

It’s worth noting that the strategy model isWhen the specific business is assigned, the if-else method is still used, It’s just that it is better than simple if-else in maintainability . If you want to change a certain business logic, you only need to modify the corresponding class.

For example: query grantType of red envelope distribution method :

Review the product requirements: query the distribution method grantType according to the coupon type resourceType and the coded resourceId

The specific operation is to determine which table to check by the coupon type resourceType, and then find out the corresponding distribution method grantType according to the coded resourceId

class Test{
    
    
	//客户端执行具体策略的测试方法
	public static void main(String[] args){
    
    
		String resourceType="红包";
		String grantType;
		switch(resourceType){
    
    
			case "红包":
				Context context01=new Context(new ConcreteStrategy01());
				grantType=context01.ContextInterface();
				break;
			case "购物券":
				Context context02=new Context(new ConcreteStrategy02());
				grantType=context02.ContextInterface();
				break;
		default:
                throw new IllegalStateException("Unexpected value: " + resourceType);
		}
	}
}

I simplified the specific implementation of the strategy

The result of execution:
Insert picture description here

Advantages and disadvantages of the strategy model

advantage

  • Maintainability is good. If you want to modify the red envelope distribution logic, you only need to modify the corresponding class ConcreteStrategy01.

Disadvantage

  • Can't overlook the entire business dispatch logic
  • More strategy classes

Guess you like

Origin blog.csdn.net/qq_44384533/article/details/109224694