Software_C#_grammer_Deletegate--Strategy

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 }
View Code

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 }
View Code

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 }
View Code
 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 }
View Code
NullObject 模式
View Code

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 }
View Code

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 }
View Code

 

posted @ 2018-04-30 19:12  君子之行  阅读(325)  评论(0编辑  收藏  举报