This article has participated in the call for good writing activities, click to view: back end, big front end double track submission, 20,000 yuan prize pool waiting for you to challenge!

The strategy model is probably the first model that many of you learn. This mode is really suitable for the opening mode, mainly because it is simple, pure and does not have too many skills, but it well expresses the concept of the design mode, so that readers can intuitively feel the benefits of the design mode.

The core of the strategy pattern is the use of polymorphism, which is supported by the mainstream object-oriented languages.

UML class diagrams location: www.processon.com/view/link/6…

This article is linked to: github.com/shidawuhen/…

Definition 1.

1.1 Policy Mode

Strategy pattern: It defines a family of algorithms and encapsulates them so that they can be replaced with each other. This pattern allows changes to the algorithm without affecting customers who use the algorithm.

UML:

1.2 analysis

Looking at the strategy pattern alone, mainly using polymorphism. However, the policy pattern is often not used alone; it is used in conjunction with the Go Design Pattern (7) -Factory pattern. The policy pattern then decouples the definition, creation, and use of the policy.

Policy mode factory mode, can achieve the effect of removing if-else and switch, mainly rely on factory mode support, by “lookup table method” to find the specified policy for use.

2. Application scenarios

The application scenarios of the policy pattern are quite broad. If there are multiple algorithms for the same kind of problem, the policy pattern can be used. For example, preferential prices are calculated according to different activities and tax rates are calculated according to different types of goods.

A recent practical business scenario can use the policy model to calculate taxes and fees for cross-border goods.

The tax on cross-border goods is related to two aspects: one is whether the goods include tax, and the other is the type of goods. Different types of goods have different tax rates. For example, the tax rates of conventional goods and alcoholic goods are different, and the tax calculation methods are also different.

So as long as you know whether the goods include tax and the type of goods, you can find the corresponding calculation scheme. If we use if-else, it will not be elegant, because there are many types of goods, and the calculation logic is relatively complex, so we can use look-up table optimization.

The tax calculation interface is invoked by the transaction side. During the transaction invocation, whether the commodity includes tax will be transmitted, and the commodity type will be maintained by the project team. So let’s look at the implementation.

3. Code implementation

package main

import "fmt"

const (
   Common = "COMMON"
   Win    = "WIN"
)

/** * @author: Jason Pang * @description: Get the item type according to hsCode * @param hscode * @return string */
func getProductType(hscode string) string {
   if hscode == "11" {
      return Common
   } else {
      return Win
   }
}

/** * @author: Jason Pang * @description: Tax calculation function, the amount is divided * @param price * @param qty * @return taxPrice */
type TaxComputeFunc func(price int64, qty int64) (taxPrice int64)

/** * @author: Jason Pang * @description: Tax calculation policy store 0 is not tax inclusive 1 is tax inclusive */
var TaxComputeFuncMap = map[int]map[string]TaxComputeFunc{
   0: map[string]TaxComputeFunc{
      Common: common,
      Win:    win,
   },
   1: map[string]TaxComputeFunc{
      Common: common,
      Win:    win,
   },
}

/** * @author: Jason Pang * @description: Calculate common commodity tax * @param price * @param qty * @return taxPrice */
func common(price int64, qty int64) (taxPrice int64) {
   radio := 0.1
   fmt.Println("Calculation of general Commodity taxes and fees")
   return int64(float64(price*qty) * radio)
}

/** * @author: Jason Pang * @description: Calculate alcohol tax * @param price * @param qty * @return taxPrice */
func win(price int64, qty int64) (taxPrice int64) {
   radio := 0.2
   fmt.Println("Calculate the general alcohol tax.")
   return int64(float64(price*qty) * radio)
}

/** * @author: Jason Pang * @description: Calculate tax * @param withTax * @param productType * @param price * @param qty */
func ComputeTaxPrice(withTax int, productType string, price int64, qty int64) {
   if taxFunc, ok := TaxComputeFuncMap[withTax][productType]; ok {
      taxPrice := taxFunc(price, qty)
      fmt.Println("Tax at", taxPrice)
   } else {
      fmt.Println("Input error cannot be calculated.")}}func main(a) {
   // Get whether the commodity includes tax, commodity price, commodity quantity, commodity type
   withTax := 0
   var price, qty int64 = 10000.3
   productType := getProductType("11")
   // Calculate taxes
   ComputeTaxPrice(withTax, productType, price, qty)
}

Copy the code

Output:

➜ myproject go run main.go

Calculate general commodity taxes and fees

Tax and fee is 3000

What are the benefits of this? First, the code is very lean, without a bunch of judgments; Secondly, the main framework, namely main\ComputeTaxPrice, will not be affected either by adding or modifying strategies. It only needs to add new strategies in TaxComputeFuncMap, which is well open to expansion. Although there are some changes to TaxComputeFuncMap, the changes are not significant. Acceptable.

If you read the Go Design Pattern (18) I wrote about earlier, the Observer pattern, you will feel that the two implementations are similar. They are similar, but there is a core difference. The observer mode calls all policies, and the policy mode finds exactly the right one to call.

conclusion

The strategy mode is a good embodiment of the open and closed principle, and also shows that even a small optimization design can bring great convenience to project development. Of course, this convenience will be fully reflected in the maintenance of the time, after all, who maintenance who knows.

The last

If you like my article, you can follow my public account (Programmer Malatang)

My personal blog is shidawuhen.github. IO /

Review of previous articles:

  1. Design patterns

  2. recruitment

  3. thinking

  4. storage

  5. The algorithm series

  6. Reading notes

  7. Small tools

  8. architecture

  9. network

  10. The Go