設計模式之美:Product Trader(操盤手)


索引

意圖

使客戶程序可以通過命名抽象超類和給定規約來創建對象。

Product Trader 讓客戶程序與 Product 類解耦,從而使得類的層級結構、框架和應用程序易於改寫、配置和演進。

Let clients create objects by naming an abstract superclass and by providing a specification.

A Product Trader decouples the client from the product and thereby eases the adaption, configuration and evolution of class hierarchies, frameworks and applications.

結構

參與者

Client

  • 為 ConcreteProduct 類創建 Specification。
  • 為 Product Trader 提供 Specification 以初始話構建過程。

Product

  • 定義類層次的接口。

ConcreteProduct

  • Product 抽象類的具體類。
  • 提供足夠的信息以判定是否滿足 Specification。

ProductTrader

  • 從 Client 接收一個 ConcreteProduct 對應的 Specification。
  • 映射 Specification 和 Creator。
  • 提供映射配置機制。
  • 調用 Creator 以生成符合 Specification 的 ConcreteProduct。

Creator

  • 定義創建 ConcreteProduct 實例的接口。
  • 知道如何根據 Specification 創建合適的 ConcreteProduct。

Specification

  • 一個 Specification 代表着一個 ConcreteProduct 類。
  • 作為映射和查詢 Creator 的條件參數。

適用性

當以下情況成立時可以使用 Product Trader 模式:

  • 當你想讓客戶程序完全獨立於 Product 實體類的實現時。
  • 你需要在運行時根據可用的規約條件動態的生成 Product 對象時。
  • 你需要為給定的規約條件配置相應的 Product 類對象。
  • 你需要在不影響客戶代碼的條件下修改和演進 Product 類的層次。

效果

  • Client 程序完全獨立於 ConcreteProduct 類層次。
  • 可以在運行時決定 Product 的具體類。
  • 可以根據特定的領域對 Product 進行配置。
  • Product 類層次更易於演進。
  • 衍生新的 ConcreteProduct 更加方便。
  • Product 類可以是負責的組件。

相關模式

  • 可以嘗試在 Factory Method 模式無法工作或不太適合時,嘗試使用 Product Trader。Factory Method 常使 Product 和 Creator 之間形成循環依賴。

實現

實現方式(一):Product Trader 的示例實現。

  1 namespace ProductTraderPattern.Implementation1
  2 {
  3   public class Specification
  4   {
  5     public string Criteria { get; set; }
  6 
  7     public bool IsSatisfiedBy(Product product)
  8     {
  9       return product.Criteria == this.Criteria;
 10     }
 11 
 12     public override int GetHashCode()
 13     {
 14       return Criteria.GetHashCode();
 15     }
 16 
 17     public override bool Equals(object obj)
 18     {
 19       return GetHashCode().Equals(obj.GetHashCode());
 20     }
 21   }
 22 
 23   public abstract class Product
 24   {
 25     public abstract string Criteria { get; }
 26   }
 27 
 28   public class ConcreteProductA : Product
 29   {
 30     public override string Criteria
 31     {
 32       get
 33       {
 34         return "SpecForConreteProductA";
 35       }
 36     }
 37   }
 38 
 39   public class ConcreteProductB : Product
 40   {
 41     public override string Criteria
 42     {
 43       get
 44       {
 45         return "SpecForConreteProductB";
 46       }
 47     }
 48   }
 49 
 50   public abstract class ProductCreator
 51   {
 52     public abstract Product Create(Specification spec);
 53   }
 54 
 55   public class ConcreteProductCreator : ProductCreator
 56   {
 57     public override Product Create(Specification spec)
 58     {
 59       if (spec.Criteria == "SpecForConreteProductA")
 60       {
 61         return new ConcreteProductA();
 62       }
 63       else if (spec.Criteria == "SpecForConreteProductB")
 64       {
 65         return new ConcreteProductB();
 66       }
 67 
 68       // any factory you can use here
 69       throw new NotSupportedException();
 70     }
 71   }
 72 
 73   public class ProductTrader
 74   {
 75     private Dictionary<Specification, ProductCreator> _dict
 76       = new Dictionary<Specification, ProductCreator>();
 77 
 78     public Product CreateFor(Specification spec)
 79     {
 80       ProductCreator creator = LookupCreator(spec);
 81       Product product = creator.Create(spec);
 82       return product;
 83     }
 84 
 85     public ProductCreator LookupCreator(Specification spec)
 86     {
 87       return _dict[spec];
 88     }
 89 
 90     public void AddCreator(Specification spec, ProductCreator creator)
 91     {
 92       _dict.Add(spec, creator);
 93     }
 94 
 95     public void RemoveCreator(Specification spec, ProductCreator creator)
 96     {
 97       _dict.Remove(spec);
 98     }
 99 
100     public void SubstituteCreator(Specification spec, ProductCreator creator)
101     {
102       _dict[spec] = creator;
103     }
104   }
105 
106   public class Client
107   {
108     public void TestCase1()
109     {
110       Specification spec1 = new Specification();
111       spec1.Criteria = "SpecForConreteProductA";
112 
113       Specification spec2 = new Specification();
114       spec2.Criteria = "SpecForConreteProductA";
115 
116       ProductCreator creator = new ConcreteProductCreator();
117 
118       ProductTrader trader = new ProductTrader();
119       trader.AddCreator(spec1, creator);
120       trader.AddCreator(spec2, creator);
121 
122       Specification spec3 = new Specification();
123       spec3.Criteria = "SpecForConreteProductA";
124 
125       Product product = trader.CreateFor(spec3);
126     }
127   }
128 }

設計模式之美》為 Dennis Gao 發布於博客園的系列文章,任何未經作者本人同意的人為或爬蟲轉載均為耍流氓。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM