2018-04-30 18:59:04.
由 委托的 动态选择方法 联想到的 Strategy Pattern
一 :
策略模式 将 宿主 与 算法 分离, 算法被封装为对象, 客户端代码用 抽象类 或 接口来调用。实现运行时的动态选择。
二:
- 抽象算法接口的方法要引用 宿主。
- Factory Method 来实现正确的算法选择, 具体算法的枚举为其提供信息,在其静态方法中作为参数。Switch选择。
- 宿主引用 IStrategy ,
- 构造器注入并在其代码中 使用 Factory Method 静态方法选择算法。
- 宿主含有一个方法可以 让 IStrategy的私有变量 来根据 (this ) 计算想要的结果并返回。
以购物篮 根据不同的折扣 结算为例。
1. 购物篮:

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace Strategy.Model 8 { 9 public class Baskets 10 { 11 //引用 IStrategyMethod 抽象策略 12 private IStrategy_DiscountMoney _strategy; 13 14 //构造器注入 枚举 15 public Baskets(DiscountType type) 16 { 17 _strategy = StrategyFactory.DiscountBy(type); 18 } 19 20 // 自身给予strategy 判断的依据 21 public decimal OriginalPrice { get; set; } 22 23 // 获取所要的结果 动态选择 24 public decimal PriceAfterDiscount() 25 { 26 return _strategy.TotalAfterDisBy(this); 27 } 28 29 } 30 }
2. 策略接口,方法引用购物篮

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace Strategy.Model 8 { 9 public interface IStrategy_DiscountMoney 10 { 11 // 具体算法由变化的 Baskets 中的策略因素而决定 12 decimal TotalAfterDisBy(Baskets basket); 13 } 14 }
3. 具体策略的实现

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace Strategy.Model 8 { 9 public class DiscountByMoney : IStrategy_DiscountMoney 10 { 11 public decimal TotalAfterDisBy(Baskets basket) 12 { 13 if (basket.OriginalPrice < 100) 14 return basket.OriginalPrice - 20m; 15 else if (basket.OriginalPrice < 50) 16 return basket.OriginalPrice - 10m; 17 else 18 return basket.OriginalPrice; 19 } 20 } 21 }

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace Strategy.Model 8 { 9 public class DiscountByPercent : IStrategy_DiscountMoney 10 { 11 public decimal TotalAfterDisBy(Baskets basket) 12 { 13 return basket.OriginalPrice * 0.8m; 14 } 15 } 16 }
NullObject 模式

4. Factory Method 选择正确算法, 枚举要为其静态方法提供判断依据
枚举:还要为宿主的构造器注入

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace Strategy.Model 8 { 9 // 为了让 Factory Method 模式能够构建正确的折扣模式 10 // 需要以枚举形式提供一些信息 11 // 12 public enum DiscountType 13 { 14 DiscountByMoney = 0, 15 DiscountByPercent = 1, 16 NullObjectPattern = 2 17 } 18 }
Factory Method:

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace Strategy.Model 8 { 9 // 确定将哪种策略算法应用到basket => Factory Method 10 public class StrategyFactory 11 { 12 // 宿主引用了 抽象算法的接口 13 // 具体算法的枚举提供信息 14 public static IStrategy_DiscountMoney DiscountBy(DiscountType type) 15 { 16 switch (type) 17 { 18 case DiscountType.DiscountByMoney: 19 return new DiscountByMoney(); 20 case DiscountType.DiscountByPercent: 21 return new DiscountByPercent(); 22 default: 23 return new NullObjectPattern(); 24 } 25 } 26 } 27 }