天天看點

設計模式:政策模式(Strategy Pattern)

政策模式定義:

政策模式定義了算法族,分别封裝起來,讓它們之間可以互相替換,此模式讓算法的變化獨立于使用算法的客戶。

樣例:

UML類圖

設計模式:政策模式(Strategy Pattern)

Java代碼實作:

Duck.java

/**
 * 鴨子超類
 * @author LiuJing
 *
 */
public abstract class Duck {

  FlyBehavior flyBehavior;
  QuackBehavior quackBehavior;
  
  public abstract void display();
  
  public void performFly(){
    flyBehavior.fly();
  }
  
  public void performQuack() {
    quackBehavior.quack();
  }
  
  public void swim(){
    System.out.println("All ducks float, even decoys!");
  }
  
  
  // 新加入2個設定行為的方法
  public void setFlyBehavior(FlyBehavior fb){
    flyBehavior = fb;
  }
  public void setQuackBehavior(QuackBehavior qb){
    quackBehavior = qb;
  }
}      

FlyBehavior.java

/**
 * 飛的行為 接口類
 * @author LiuJing
 *
 */
public interface FlyBehavior {
  public void fly();
}      

FlyWithWings.java

/**
 * 用翅膀飛的類
 * @author LiuJing
 *
 */
public class FlyWithWings implements FlyBehavior{
  public void fly(){
    System.out.println("I'm flying!!!");
  }
}      

FlyNoWay.java

/**
 * 不能飛的類
 * @author LiuJing
 *
 */
public class FlyNoWay implements FlyBehavior{
  public void fly() {
    // TODO Auto-generated method stub
    System.out.println("I can't fly");
  }
}      

FlyRocketPowered.java

/**
 * 用火箭飛的類
 * @author LiuJing
 *
 */
public class FlyRocketPowered implements FlyBehavior {

  public void fly() {
    // TODO Auto-generated method stub
    System.out.println("I'm flying with a rocket");
  }
}      

QuackBehavoir.java

/**
 * 叫的行為 接口
 * @author LiuJing
 *
 */
public interface QuackBehavior {
  public void quack();
}      

Quack.java

/**
 * 嘎嘎叫的類
 * @author LiuJing
 *
 */
public class Quack implements QuackBehavior{
  public void quack() {
    // TODO Auto-generated method stub
    System.out.println("Quack");
  }
}      

Squeak.java

/**
 * 吱吱叫的類
 * @author LiuJing
 *
 */
public class Squeak implements QuackBehavior{
  public void quack() {
    // TODO Auto-generated method stub
    System.out.println("Squeak");
  }
}      

MuteQuack.java

/**
 * 沉默不叫的類
 * @author LiuJing
 *
 */
public class MuteQuack implements QuackBehavior{
  public void quack() {
    // TODO Auto-generated method stub
    System.out.println("Silence");
  }
}      

MallardDuck.java

/**
 * 綠頭鴨
 * @author LiuJing
 *
 */
public class MallardDuck extends Duck {

  public MallardDuck(){
    quackBehavior = new Quack();
    flyBehavior = new FlyWithWings();
  }
  
  @Override
  public void display() {
    // TODO Auto-generated method stub
    System.out.println("I'm a real Mallard duck");
  }

}      

ModelDuck.java

/**
 * 模型鴨
 * @author LiuJing
 *
 */
public class ModelDuck extends Duck {
  
  public ModelDuck(){
    flyBehavior = new FlyNoWay();
    quackBehavior = new Quack();
  }
  
  @Override
  public void display() {
    // TODO Auto-generated method stub
    System.out.println("I'm a model duck");
  }
}      

現在寫一個測試類,用以測試:

Test.java

/**
 * 測試類
 * @author LiuJing
 *
 */

public class Test {

  /**
   * @param args
   */
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    
    // 測試綠頭鴨
    System.out.println("--------測試綠頭鴨--------");
    Duck mallard = new MallardDuck();
    mallard.performQuack();
    mallard.performFly();
    
    // 測試模型鴨
    System.out.println("--------測試模型鴨---------");
    Duck model = new ModelDuck();
    model.performQuack();
    model.performFly();
    // 改變其飛行行為
    model.setFlyBehavior(new FlyRocketPowered());
    model.performFly();
  }
}      

輸出:

--------測試綠頭鴨--------
Quack
I'm flying!!!
--------測試模型鴨---------
Quack
I can't fly
I'm flying with a rocket      

政策模式C#實作樣例:

UML類圖:

設計模式:政策模式(Strategy Pattern)

C#實作代碼:

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PatternTest
{
    // 政策抽象類
    abstract class Strategy
    {
        public abstract void AlgorithmInterface();
    }

    // 算法A
    class ConcreteStrategyA : Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("算法A實作");
        }
    }

    // 算法B
    class ConcreteStrategyB : Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("算法B實作");
        }
    }

    // 算法C
    class ConcreteStrategyC : Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("算法C實作");
        }
    }

    // 具體使用算法的類
    class Context
    {
        Strategy strategy;
        public Context(Strategy strategy)
        {
            this.strategy = strategy;
        }

        public void ContextInterface()
        {
            strategy.AlgorithmInterface();
        }
    }

    // 測試代碼
    class Program
    {
        static void Main(string[] args)
        {
            Context context;
            context = new Context(new ConcreteStrategyA());
            context.ContextInterface();

            context = new Context(new ConcreteStrategyB());
            context.ContextInterface();

            context = new Context(new ConcreteStrategyC());
            context.ContextInterface();

            Console.Read();
        }
    }
}      

輸出:

算法A實作
算法B實作
算法C實作      

C#具體執行個體:

設計模式:政策模式(Strategy Pattern)

代碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PatternTest
{
    // 現金收費抽象類
    abstract class CashSuper
    {
        public abstract double acceptCash(double money);
    }

    // 正常收費子類
    class CashNormal : CashSuper
    {
        public override double acceptCash(double money)
        {
            return money;
        }
    }

    // 打折收費子類
    class CashRebate : CashSuper
    {
        private double moneyRebate = 1d;

        public CashRebate(double moneyRebate)
        {
            this.moneyRebate = moneyRebate;
        }
        public override double acceptCash(double money)
        {
            return money * moneyRebate;
        }
    }

    // 返利收費子類
    class CashReturn : CashSuper
    {
        private double moneyCondition = 0.0d;
        private double moneyReturn = 0.0d;
        public CashReturn(double moneyCondition, double moneyReturn)
        {
            this.moneyCondition = moneyCondition;
            this.moneyReturn = moneyReturn;
        }
        public override double acceptCash(double money)
        {
            double result = money;
            if (money >= moneyCondition)
            {
                result = money - Math.Floor(money / moneyCondition) * moneyReturn;
            }

            return result;
        }
    }

    //class CashFactory
    //{
    //    public static CashSuper createCashAccept(int type)
    //    {
    //        CashSuper cs = null;
    //        switch (type)
    //        {
    //            case 1: // "正常收費"
    //                cs = new CashNormal();
    //                break;
    //            case 2: // "滿300返100"
    //                cs = new CashReturn(300, 100);
    //                break;
    //            case 3: // "打8折"
    //                cs = new CashRebate(0.8);
    //                break;
    //        }

    //        return cs;
    //    }
    //}

    // 改進CashFactory,請仔細對比上一個注釋的類,這麼做有什麼好處?
    // 好處:
    // 隐藏了 CashSuper 對象及其方法 acceptCash
    class CashContext
    {
        private CashSuper cs;
        public CashContext(int type)
        {
            switch (type)
            {
                case 1: // "正常收費"
                    cs = new CashNormal();
                    break;
                case 2: // "滿300返100"
                    cs = new CashReturn(300, 100);
                    break;
                case 3: // "打8折"
                    cs = new CashRebate(0.8);
                    break;
            }
        }

        public double getResult(double money)
        {
            return cs.acceptCash(money);
        }
    }


    // 測試代碼
    class Program
    {
        static void Main(string[] args)
        {
            //選擇一種折扣類型
            // 1,正常收費 2,滿300返100 3,打8折
            double total = 0.0d;
            double totalPrices = 0d;
            
            
            //CashSuper csuper = null;

            //Console.WriteLine("----------測試正常收費-----------");
            //csuper = CashFactory.createCashAccept(1);
            //totalPrices = csuper.acceptCash(500);//金額為客人在店裡消費的随機數額 單價*數額 多種
            //Console.WriteLine("消費總額為:"+ totalPrices);
            //total += totalPrices;

            //Console.WriteLine("----------測試滿300減100-----------");
            //csuper = CashFactory.createCashAccept(2);
            //totalPrices = csuper.acceptCash(1400);//金額為客人在店裡消費的随機數額 單價*數額 多種
            //Console.WriteLine("消費總額為:" + totalPrices);
            //total += totalPrices;

            //Console.WriteLine("----------測試8折-----------");
            //csuper = CashFactory.createCashAccept(3);
            //totalPrices = csuper.acceptCash(1000);//金額為客人在店裡消費的随機數額 單價*數額 多種
            //Console.WriteLine("消費總額為:" + totalPrices);
            //total += totalPrices;


            // 改進代碼後的再測試
            CashContext cc = null;

            Console.WriteLine("----------測試正常收費-----------");
            cc = new CashContext(1);
            totalPrices = cc.getResult(500);//金額為客人在店裡消費的随機數額 單價*數額 多種
            Console.WriteLine("消費總額為:" + totalPrices);
            total += totalPrices;

            Console.WriteLine("----------測試滿300減100-----------");
            cc = new CashContext(2);
            totalPrices = cc.getResult(1400);//金額為客人在店裡消費的随機數額 單價*數額 多種
            Console.WriteLine("消費總額為:" + totalPrices);
            total += totalPrices;

            Console.WriteLine("----------測試8折-----------");
            cc = new CashContext(3);
            totalPrices = cc.getResult(1000);//金額為客人在店裡消費的随機數額 單價*數額 多種
            Console.WriteLine("消費總額為:" + totalPrices);
            total += totalPrices;

            Console.WriteLine("總消費:" + total);

            Console.Read();
        }
    }
}      

輸出:

----------測試正常收費-----------
消費總額為:500
----------測試滿300減100-----------
消費總額為:1000
----------測試8折-----------
消費總額為:800
總消費:2300