索引

意图

使客户程序可以通过命名抽象超类和给定规约来创建对象。

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

最新文章

  1. 用户新加入Group
  2. 同 一个页面,不同请求路径,如何根据实际场景写JS
  3. Install Docker on Mac OS X(转)
  4. typedef struct 结构体
  5. 获取当前 Windows 的安装序列号
  6. jsonp实现原理详细介绍
  7. c# 清空txt文本文件的值
  8. 常用思科设备图标(JPG+矢量图)
  9. 非常出色的一款WinForm窗体重绘GUI类库源码
  10. linux下关于程序性能和系统性能的工具、方法
  11. hbase 无法操作与hadoop的安全模式的原因
  12. 用python实现对图像的卷积(滤波)
  13. Mybatis逻辑分页原理解析RowBounds
  14. 补习系列(18)-springboot H2 迷你数据库
  15. Java链接MySQL数据库的配置文件
  16. 三元运算和bytes数据类型笔记
  17. 浏览器端使用javascript调用腾讯翻译api
  18. SpringMVC MongoDB之“基本文档查询(Query、BasicQuery)”
  19. 基因组与Python --PyVCF 好用的vcf文件处理器
  20. svn 修改原来包名的方法和会报的错误

热门文章

  1. web测试方法总结
  2. arch 安装图形界面
  3. easyui form表单提交应注意的问题
  4. android sdk镜像站点
  5. 深入研究C语言 第一篇(续)
  6. pl/sql中文乱码问题解决
  7. OpenCV 学习之路(1)
  8. 小试牛刀--利用豆瓣API爬取豆瓣电影top250
  9. Unity 4.x Asset Bundle 重名
  10. 【转载】Android数据存储之SQLite