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 发布于博客园的系列文章,任何未经作者本人同意的人为或爬虫转载均为耍流氓。

Product Trader(操盘手)的更多相关文章

  1. 4星|《流量池》:Luckin Coffee营销操盘手经验谈

    流量池:“急功近利”的流量布局.营销转化 作者是一线营销操盘手,全书是作者的经验总结,这样的作者在营销类图书中比较罕见,因此这本书非常有价值. 全书是写给巨头之外的企业营销人员看的,这样的企业的流量来 ...

  2. 设计模式之美:Product Trader(操盘手)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Product Trader 的示例实现. 意图 使客户程序可以通过命名抽象超类和给定规约来创建对象. Product Trad ...

  3. 一良心操盘手:我们是这样玩死散户的! z

    做庄必须考虑很多问题: 第一是证监会的监控.操控股票不能让他们抓住把柄,这时候就要考虑多户头,或者拉几个私募大户集体作战. 第二要考虑产业资本的问题.如果我们拉的时候,他们看到利润可观,结果大量抛出筹 ...

  4. 怎样写一个PC端使用的操盘手软件(用来买卖股票,查看报表,行情)

    我们想写一个操盘手软件,对于操盘而言,首先是快,然后是资料尽可能丰富,最好能看到行情,报表什么的.只是windows上写软件看似基础,实际上都不怎么好弄,用C++开发确实可以实现所有功能,估计光研发费 ...

  5. 操盘策略:KDJ三线合一 必定孕育大牛股

    日周月KDJ指标三周期合一是孕育大牛股的必要条件: 炒股看一下周.月线十分有必要,很多时候,周.月线已经死叉下行,中长线趋势走坏,但日线偏偏发出金叉,K线也走好,量价配合也好,而此时介入,多数情况下就 ...

  6. DAY TRADER

    日内交易是一种交易模式,英文名字是daytrade,主要是指持仓时间短,不留过夜持仓的交易方式.日内交易捕捉入市后能够马上脱离入市成本的交易机会,入市之后如果不能马上获利,就准备迅速离场.因为这种交易 ...

  7. js地址下拉列表中全职工作

    /******************************************************************* *输出全国各省辖市下拉列表项writeCitys() *输出企 ...

  8. 数据分析侠A的成长故事

    数据分析侠A的成长故事 面包君  同学A:22岁,男,大四准备实习,计算机专业,迷茫期 作为一个很普通的即将迈入职场的他来说,看到周边的同学都找了技术开发的岗位,顿觉自己很迷茫,因为自己不是那么喜欢钻 ...

  9. 不care小米,梁军坦言微鲸才是乐视最大对手

    除了每天毫无悬念地上头条和陷入困境的生态帝国之外,乐视还要继续操心着它的对手们."挑事儿"的小米已经不足为惧,后起之秀微鲸成了一个令它"头疼"的所在.因为,不仅 ...

随机推荐

  1. 创建和分析excel文件

    jxl.jar:下载地址:http://download.csdn.net/detail/xuxu198899223/7717737 package excel; public class BookV ...

  2. Codeforces 514 D R2D2 and Droid Army(RMQ+二分法)

    An army of n droids is lined up in one row. Each droid is described by m integers a1, a2, ..., am, w ...

  3. 自己写CPU第五级(5)——测试逻辑、实现移动和空指令

    我们会继续上传新书<自己写CPU>(未公布),今天是19片,我每星期试试4 5.6 測试程序1--測试逻辑操作实现效果 编写例如以下測试程序用于检验逻辑操作指令是否实现正确,文件名称命名为 ...

  4. php_json入库有关

    php入库json信息 有些字符需要特殊处理 //组装 $test=array(); $test["k1"]= urlencode($k1); $test["k2&quo ...

  5. Notification(一个)——使用演示样本的基础知识

    main.xml如下面: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" ...

  6. c++使用stmp协议发送电子邮件(163邮箱,TTL非SSL)

    0.有关TLS和SSL SSL/TLS是用来加密邮件流的. 假设不加密的话非常easy被人破解. 只是既然是要发送广告邮件,这个就不用在意了,使用没加密的即可. 另外在使用的时候,发现,qq的邮箱须要 ...

  7. Spring + Spring MVC + Hibernate项目开发集成(注解)

    在自己从事的项目中都是使用xml配置的方式来进行的,随着项目的越来越大,会发现配置文件会相当的庞大,这个不利于项目的进行和后期的维护.于是考虑使用注解的方式来进行项目的开发,前些日子就抽空学习了一下. ...

  8. POJ1258 基础最小生成树

    本文出自:http://blog.csdn.net/svitter 题意:给出一个数字n代表邻接矩阵的大小,随后给出邻接矩阵的值.输出最小生成树的权值. 题解: prime算法的基本解法: 1.选择一 ...

  9. jQuery插件编写及链式编程模型

    jQuery插件编写及链式编程模型小结 JQuery极大的提高了我们编写JavaScript的效率,让我们可以愉快的编写代码,做出各种特效.大多数情况下,我们都是使用别人开发的JQuery插件,今天我 ...

  10. Swift语言指南(五)--数字字面量和数字类型转换

    原文:Swift语言指南(五)--数字字面量和数字类型转换 数字字面量 整数字面量写法如下: · 十进制数,无前缀 · 二进制数,以 0b 为前缀 · 八进制数,以 0o 为前缀 · 十六进制数,以 ...