设计模式之美: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 的示例实现。
namespace ProductTraderPattern.Implementation1
{
public class Specification
{
public string Criteria { get; set; } public bool IsSatisfiedBy(Product product)
{
return product.Criteria == this.Criteria;
} public override int GetHashCode()
{
return Criteria.GetHashCode();
} public override bool Equals(object obj)
{
return GetHashCode().Equals(obj.GetHashCode());
}
} public abstract class Product
{
public abstract string Criteria { get; }
} public class ConcreteProductA : Product
{
public override string Criteria
{
get
{
return "SpecForConreteProductA";
}
}
} public class ConcreteProductB : Product
{
public override string Criteria
{
get
{
return "SpecForConreteProductB";
}
}
} public abstract class ProductCreator
{
public abstract Product Create(Specification spec);
} public class ConcreteProductCreator : ProductCreator
{
public override Product Create(Specification spec)
{
if (spec.Criteria == "SpecForConreteProductA")
{
return new ConcreteProductA();
}
else if (spec.Criteria == "SpecForConreteProductB")
{
return new ConcreteProductB();
} // any factory you can use here
throw new NotSupportedException();
}
} public class ProductTrader
{
private Dictionary<Specification, ProductCreator> _dict
= new Dictionary<Specification, ProductCreator>(); public Product CreateFor(Specification spec)
{
ProductCreator creator = LookupCreator(spec);
Product product = creator.Create(spec);
return product;
} public ProductCreator LookupCreator(Specification spec)
{
return _dict[spec];
} public void AddCreator(Specification spec, ProductCreator creator)
{
_dict.Add(spec, creator);
} public void RemoveCreator(Specification spec, ProductCreator creator)
{
_dict.Remove(spec);
} public void SubstituteCreator(Specification spec, ProductCreator creator)
{
_dict[spec] = creator;
}
} public class Client
{
public void TestCase1()
{
Specification spec1 = new Specification();
spec1.Criteria = "SpecForConreteProductA"; Specification spec2 = new Specification();
spec2.Criteria = "SpecForConreteProductA"; ProductCreator creator = new ConcreteProductCreator(); ProductTrader trader = new ProductTrader();
trader.AddCreator(spec1, creator);
trader.AddCreator(spec2, creator); Specification spec3 = new Specification();
spec3.Criteria = "SpecForConreteProductA"; Product product = trader.CreateFor(spec3);
}
}
}
《设计模式之美》为 Dennis Gao 发布于博客园的系列文章,任何未经作者本人同意的人为或爬虫转载均为耍流氓。
设计模式之美:Product Trader(操盘手)的更多相关文章
- Product Trader(操盘手)
Product Trader(操盘手) 索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Product Trader 的示例实现. 意图 使客户程序可以通过命名抽象超类和给定规 ...
- 4星|《流量池》:Luckin Coffee营销操盘手经验谈
流量池:“急功近利”的流量布局.营销转化 作者是一线营销操盘手,全书是作者的经验总结,这样的作者在营销类图书中比较罕见,因此这本书非常有价值. 全书是写给巨头之外的企业营销人员看的,这样的企业的流量来 ...
- 一良心操盘手:我们是这样玩死散户的! z
做庄必须考虑很多问题: 第一是证监会的监控.操控股票不能让他们抓住把柄,这时候就要考虑多户头,或者拉几个私募大户集体作战. 第二要考虑产业资本的问题.如果我们拉的时候,他们看到利润可观,结果大量抛出筹 ...
- 怎样写一个PC端使用的操盘手软件(用来买卖股票,查看报表,行情)
我们想写一个操盘手软件,对于操盘而言,首先是快,然后是资料尽可能丰富,最好能看到行情,报表什么的.只是windows上写软件看似基础,实际上都不怎么好弄,用C++开发确实可以实现所有功能,估计光研发费 ...
- 设计模式之美:Factory Method(工厂方法)
索引 别名 意图 结构 参与者 适用性 缺点 效果 相关模式 命名约定 实现 实现方式(一):Creator 类是一个抽象类并且不提供它所声明的工厂方法的实现. 实现方式(二):Creator 类是一 ...
- 设计模式之美:Builder(生成器)
索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Builder 为每个构件定义一个操作. 实现方式(二):Builder 将构件返回给 Director,Director 将构 ...
- 设计模式之美:Prototype(原型)
索引 别名 意图 结构 参与者 适用性 缺点 效果 相关模式 命名约定 实现 实现方式(一):使用一个原型管理器. 实现方式(二):使用浅拷贝实现克隆(Clone)操作. 实现方式(三):使用深拷贝实 ...
- 《设计模式之美》 <01>为什么需要学习掌握设计模式?
1. 应对面试中的设计模式相关问 题学习设计模式和算法一样,最功利.最直接的目的,可能就是应对面试了.不管你是前端工程师.后端工程师,还是全栈工程师,在求职面试中,设计模式问题是被问得频率比较高的一类 ...
- 设计模式之美:Null Object(空对象)
索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Null Object 的示例实现. 意图 通过对缺失对象的封装,以提供默认无任何行为的对象替代品. Encapsulate t ...
随机推荐
- Linux 内核通知链随笔【中】
关于内核通知链不像Netlink那样,既可以用于内核与用户空间的通信,还能用于内核不同子系统之间的通信,通知链只能用于内核不同子系统之间的通信.那么内核通知链到底是怎么工作的?我们如何才能用好通知链? ...
- vs2015 command prompt here
网上搜的很多方法都不能用,比如:http://app.paraesthesia.com/CommandPromptHere/ 主要是都搞错了注册表路径,写成了: HKCR,Directory\Shel ...
- 硬浮点 VFP
http://blog.chinaunix.net/uid-27875-id-3449290.html 编译器对VFP的支持一个浮点数操作最后是翻译成VFP指令,还是翻译成fpa,或者是softf ...
- js性能优化
使用局部变量(尽量缩短作用域链)JavaScript引擎对变量的解析时间跟作用域链的深度有关.局部变量由于处于链尾,存取速度是最快的,因此,一个好的经验是:任何非局部变量使用超过一次时,请使用局部变量 ...
- win7下matplotlib安装(64位)
前段时间爬了一些数据,想着以后要将数据的分析结果什么的展示出来,就想着下个MATLAB,某天在微信上的一篇文章发现matplotlib库,是用于Python的一个不错的图形化库,就想着装上耍耍.不过安 ...
- C++内存分配及变长数组的动态分配
//------------------------------------------------------------------------------------------------ 第 ...
- ASP.NET MVC 部署全站HTTPS
什么是全站HTTPS 全站HTTPS就是指整个网站的所有页面,所有资源全部使用HTTPS链接. 当用户的某个请求是明文的HTTP时,应该通过HTTP状态码301永久重定向到对应的HTTPS链接. 为了 ...
- Python 4 —— 函数与模块
函数和模块的使用 一.函数 一个例子说明一切. def hello(): print "hello world" def increment(num): num += 1 retu ...
- js在head里插入style样式
代码如下: var nod = document.createElement('style'), str = 'body{background:#000;color:#fff} a{color:#ff ...
- BZOJ2683 简单题(CDQ分治)
传送门 之前听别人说CDQ分治不难学,今天才知道果真如此.之前一直为自己想不到CDQ的方法二很不爽,今天终于是想出来了一道了,太弱-- cdq分治主要就是把整段区间分成两半,然后用左区间的值去更新右区 ...