Product Trader(操盘手)
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(操盘手)的更多相关文章
- 4星|《流量池》:Luckin Coffee营销操盘手经验谈
流量池:“急功近利”的流量布局.营销转化 作者是一线营销操盘手,全书是作者的经验总结,这样的作者在营销类图书中比较罕见,因此这本书非常有价值. 全书是写给巨头之外的企业营销人员看的,这样的企业的流量来 ...
- 设计模式之美:Product Trader(操盘手)
索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Product Trader 的示例实现. 意图 使客户程序可以通过命名抽象超类和给定规约来创建对象. Product Trad ...
- 一良心操盘手:我们是这样玩死散户的! z
做庄必须考虑很多问题: 第一是证监会的监控.操控股票不能让他们抓住把柄,这时候就要考虑多户头,或者拉几个私募大户集体作战. 第二要考虑产业资本的问题.如果我们拉的时候,他们看到利润可观,结果大量抛出筹 ...
- 怎样写一个PC端使用的操盘手软件(用来买卖股票,查看报表,行情)
我们想写一个操盘手软件,对于操盘而言,首先是快,然后是资料尽可能丰富,最好能看到行情,报表什么的.只是windows上写软件看似基础,实际上都不怎么好弄,用C++开发确实可以实现所有功能,估计光研发费 ...
- 操盘策略:KDJ三线合一 必定孕育大牛股
日周月KDJ指标三周期合一是孕育大牛股的必要条件: 炒股看一下周.月线十分有必要,很多时候,周.月线已经死叉下行,中长线趋势走坏,但日线偏偏发出金叉,K线也走好,量价配合也好,而此时介入,多数情况下就 ...
- DAY TRADER
日内交易是一种交易模式,英文名字是daytrade,主要是指持仓时间短,不留过夜持仓的交易方式.日内交易捕捉入市后能够马上脱离入市成本的交易机会,入市之后如果不能马上获利,就准备迅速离场.因为这种交易 ...
- js地址下拉列表中全职工作
/******************************************************************* *输出全国各省辖市下拉列表项writeCitys() *输出企 ...
- 数据分析侠A的成长故事
数据分析侠A的成长故事 面包君 同学A:22岁,男,大四准备实习,计算机专业,迷茫期 作为一个很普通的即将迈入职场的他来说,看到周边的同学都找了技术开发的岗位,顿觉自己很迷茫,因为自己不是那么喜欢钻 ...
- 不care小米,梁军坦言微鲸才是乐视最大对手
除了每天毫无悬念地上头条和陷入困境的生态帝国之外,乐视还要继续操心着它的对手们."挑事儿"的小米已经不足为惧,后起之秀微鲸成了一个令它"头疼"的所在.因为,不仅 ...
随机推荐
- hdu2369 Broken Keyboard(类似dfs)
转载请注明出处:http://blog.csdn.net/u012860063 题目链接:pid=2369">http://acm.hdu.edu.cn/showproblem.php ...
- java json字符串转List、Map等对象
List<Map<String, Object>> map = g.fromJson(jsonStr, new TypeToken<List<Map<Stri ...
- Oracle内存管理(五)
[深度分析--eygle]学习笔记 1.4. 2其他内存组件 Large Pool-大池是SGA的一个可选组件,通经常使用于共享server模式(MTS). 并行计算或 RMAN的备份恢复等操作. J ...
- HDU 4303 Hourai Jeweled 树dp 所有权利和航点 dfs2次要
意甲冠军: long long ans = 0; for(int i = 1; i <= n; i++) for(int j = i+1; j <= n; j++) ans += F(i, ...
- js手机对应的多级导航分享
js移动导航对应,您可以使用自适应时屏幕,当小画面在一定程度上的网站.使导航出现,The navigation effects such as the following figures:多级导航! ...
- CSS hack 如何区分所有IE浏览器和非IE浏览器
网上方法很多,例如,测试后得出以下结论,多余的话不说了,直入主题: 1.所有的推理IE浏览器 正解:此写法仅仅被lE浏览器识别,非IE浏览器不识别. <!--[if IE]> <st ...
- Net开源网络爬虫
转载.Net开源网络爬虫Abot介绍 .Net中也有很多很多开源的爬虫工具,abot就是其中之一.Abot是一个开源的.net爬虫,速度快,易于使用和扩展.项目的地址是https://code.goo ...
- C# Parse和Convert的区别分析(转)
大家都知道在进行类型转换的时候有连个方法供我们使用就是Convert.to和*.Parse,但是疑问就是什么时候用C 什么时候用P 通俗的解释大家都知道: Convert 用来转换继承自object类 ...
- STL该反应堆运行
首先来看全然二叉树的定义: 若设二叉树的深度为h,除第 h 层外,其他各层 (1-h-1) 的结点数都达到最大个数,第 h 层全部的结点都连续集中在最左边,这就是全然二叉树.而将一维数组视为全然二叉树 ...
- winform屏幕截图
原文:winform屏幕截图 屏幕截图是一个比较常用的功能,在项目中出现的比例也比较高,至少我做过的每个项目都有屏幕截图这个功能,从全屏截图到区域截图都有出现过.当然区域截图已然包含了全屏截图. 全屏 ...