[Design Mode] Strategic Factory - Use Case of Marketplace Discount Calculation System

Posted by kitchin on Sat, 27 Jul 2019 18:44:50 +0200

Strategy Pattern

The core of this design pattern is to encapsulate changes in algorithms so that they can be replaced by each other.

Say nothing more, demand first: Shop checkouts require a statistical total purchase price of goods, and discounts, rebates and other preferential activities appear on the basis of the original prices.

 

Policy Pattern Class Diagram

 

 

Several policy methods inherit from the same abstract class and are instantiated through the context interface.

 

CashSuper Policy Abstract Class

abstract class CashSuper {
    public constructor() {
    }

    public abstract acceptCash(money: number);  //Abstract Approach to Preferential Policies
}

CashNormal Normal Normal Policy Class

class CashNormal extends CashSuper {
    public constructor() {
        super();
    }

    public acceptCash(money: number): number {
        return money;
    }
}

CashRebate Discount Policy Class

class CashRebate extends CashSuper {
    private moneyRebate: number = 1;
    public constructor(moneyRebate: number) {
        super();
        this.moneyRebate = moneyRebate;
    }

    public acceptCash(money: number): number {
        money = money * this.moneyRebate;
        return money;
    }
}

CashReturn Return Policy Class

class CashReturn extends CashSuper {
    private moneyCondition: number = 0;
    private moneyReturn: number = 0;
    public constructor(moneyCondition: number, moneyReturn: number) {
        super();
        this.moneyCondition = moneyCondition;
        this.moneyReturn = moneyReturn;
    }

    public acceptCash(money: number): number {
        if (money >= this.moneyCondition) 
            money = money - this.moneyReturn * Math.floor(money / this.moneyCondition);
        return money;
    }
}

CashContext policy context interface (where different policy classes are instantiated in conjunction with simple factory mode)

class CashContext {
    public cs: CashSuper = null
    public constructor(type: string) {
        switch(type) {
            case "Normal":
            let cn: CashNormal = new CashNormal();
            this.cs = cn;
                break;
            case "Rebate":
            let cb: CashRebate = new CashRebate(0.8);
            this.cs = cb;
                break;
            case "Return":
            let ct: CashReturn = new CashReturn(300, 100);
            this.cs = ct;
                break;            
        }
    }

    public GetResult(money: number): number {
        return this.cs.acceptCash(money);
    }
}

Client Test

let total: number = 1000;  //Purchase original price
let cc_1: CashContext = new CashContext("Normal"); // Original price
let cc_2: CashContext = new CashContext("Return"); // Return strategy
let cc_3: CashContext = new CashContext("Rebate"); // Discount strategy

total = cc_1.GetResult(total); // 1000       
total = cc_2.GetResult(total); // 1000 -> 700
total = cc_3.GetResult(total); // 700 -> 560

 

Advantages and disadvantages

Advantage:

1. The strategy mode provides a way to manage the family of related algorithms.The hierarchy of policy classes defines an algorithm or family of behaviors.Proper use of inheritance can move common code into the parent class, thereby avoiding duplicate code.
2. The policy pattern provides a way to replace the inheritance relationship.Inheritance can handle a variety of algorithms or behaviors.If you are not using a policy pattern, then environment classes that use algorithms or behaviors may have subclasses, each of which provides a different algorithm or behavior.However, the user of the algorithm or behavior is then confused with the algorithm or behavior itself.The logic to decide which algorithm to use or which behavior to take is mixed with the logic of the algorithm or behavior, making it impossible to evolve independently.Inheritance makes it impossible to dynamically change an algorithm or behavior.
3. Multiple conditional transfer statements can be avoided by using the policy mode.Multiple transfer statements are not easy to maintain. They mix the logic of which algorithm or behavior to take with the logic of the algorithm or behavior and are all listed in a single multiple transfer statement, which is more primitive and backward than using inheritance.
 
Disadvantages:
1. The client must know all the policy classes and decide which one to use.This means that the client must understand the differences between these algorithms in order to select the appropriate algorithm class in time.In other words, the policy pattern only applies when the client knows all the algorithms or behaviors.
2. Policy patterns result in a large number of policy classes, each of which produces a new class.Sometimes policy classes can be designed to be shared by saving environment-dependent states to clients so that policy class instances can be used by different clients.In other words, you can use the share mode to reduce the number of objects.

Topics: PHP