Role Object(角色对象)

索引

意图

通过明确地附加角色对象到目标对象中,以使对象可以适配不同的客户需求。每个角色对象都代表着目标对象在客户上下文中的一种角色。每种上下文都存在于特定的应用程序中,因此可使对象在不同的应用程序间解耦。

Adapt an object to different client’s needs through transparently attached role objects, each one representing a role the object has to play in that client’s context. Each context may be its own application, which therefore gets decoupled from the other applications.

结构

参与者

Component

  • 定义关键的抽象接口。
  • 定义添加、删除、测试和查询角色对象的接口协议。Client 可以指定一个 specification 来获取一个 ConcreteRole 实例。

ComponentCore

  • 实现 Component 接口,包括角色管理协议。
  • 负责创建 ConcreteRole 实例。
  • 管理角色对象。

ComponentRole

  • 存储一个经过装饰的 ComponentCore 对象的引用。
  • 实现 Component 接口,并将接口请求转发到 ComponentCore 中。

ConcreteRole

  • 定义和实现特定上下文的 Component 接口的实现。
  • 构造函数包含一个 ComponentCore 参数。

Client

  • 请求协作对象。

适用性

当以下情况成立时可以使用 Role Object 模式:

  • 你需要在不同的客户上下文间保持关键的抽象定义,每种抽象定义的实现都存在于其特定的应用范围内,同时你不想将这些与客户上下文相关的接口耦合在同一个接口内。
  • 你需要能够动态的处理角色,以便可以在运行时按需的添加或移除角色,而不是在编译时使用固定的对象定义。
  • 你需要保持角色与客户成对儿关系,在不同的角色与客户对之间保持独立性,当更改一个角色时并不影响其他客户。

效果

  • 可以简洁地定义对象的关键抽象。Component 接口仅需关注必要的状态的行为,而不会涉及具体上下文中的职责。
  • 角色对象易于演进,彼此之间保持独立。
  • 角色对象可以动态的添加和移除。
  • 应用程序可以更好的解耦和。

相关模式

  • Decorator模式与 Role Object 模式有着类似的结构,但行为不同。Decorator 模式使开发人员可以对一个对象进行链式的装饰,而 Role Object 模式则不允许这样。并且,Decorator 通常不会扩大对象的功能,而 Role Object 会引入新的操作。
  • Extension Object 模式也在解决类似的问题,通过对对象的扩展来满足特定的客户上下文的需求。尽管如此,Extension Object 并没有考虑透明性(Transparently),即保持对象关键抽象(Key Abstraction)的定义,而 Role Object 则正是强调了这一点。

实现

实现方式(一):Role Object 的示例实现。

  1 namespace RoleObjectPattern.Implementation1
2 {
3 public abstract class Customer
4 {
5 public abstract CustomerRole GetRole(string spec);
6 public abstract void AddRole(string spec);
7 public abstract void RemoveRole(string spec);
8 public abstract bool HasRole(string spec);
9 public abstract void SomeCommonOperation1();
10 }
11
12 public class CustomerCore : Customer
13 {
14 private Dictionary<string, CustomerRole> _roles
15 = new Dictionary<string, CustomerRole>();
16 private CustomerRoleFactory _roleFactory;
17
18 public CustomerCore(CustomerRoleFactory roleFactory)
19 {
20 _roleFactory = roleFactory;
21 }
22
23 public override CustomerRole GetRole(string spec)
24 {
25 if (_roles.ContainsKey(spec))
26 return _roles[spec];
27 else
28 return null;
29 }
30
31 public override void AddRole(string spec)
32 {
33 CustomerRole role = GetRole(spec);
34 if (role == null)
35 {
36 role = _roleFactory.CreateRole(spec, this);
37 if (role != null)
38 {
39 _roles.Add(spec, role);
40 }
41 }
42 }
43
44 public override void RemoveRole(string spec)
45 {
46 _roles.Remove(spec);
47 }
48
49 public override bool HasRole(string spec)
50 {
51 return _roles.ContainsKey(spec);
52 }
53
54 public override void SomeCommonOperation1()
55 {
56 // do some business logic
57 }
58 }
59
60 public class CustomerRole : Customer
61 {
62 private CustomerCore _decoratedCore;
63
64 public CustomerRole(CustomerCore core)
65 {
66 _decoratedCore = core;
67 }
68
69 public override CustomerRole GetRole(string spec)
70 {
71 return _decoratedCore.GetRole(spec);
72 }
73
74 public override void AddRole(string spec)
75 {
76 _decoratedCore.AddRole(spec);
77 }
78
79 public override void RemoveRole(string spec)
80 {
81 _decoratedCore.RemoveRole(spec);
82 }
83
84 public override bool HasRole(string spec)
85 {
86 return _decoratedCore.HasRole(spec);
87 }
88
89 public override void SomeCommonOperation1()
90 {
91 _decoratedCore.SomeCommonOperation1();
92 }
93 }
94
95 public class Borrower : CustomerRole
96 {
97 public Borrower(CustomerCore core)
98 : base(core)
99 {
100 }
101
102 public void SomeOperationForBorrower()
103 {
104 // do something for borrower
105 }
106 }
107
108 public class Investor : CustomerRole
109 {
110 public Investor(CustomerCore core)
111 : base(core)
112 {
113 }
114
115 public void SomeOperationForInvestor()
116 {
117 // do something for investor
118 }
119 }
120
121 public class CustomerRoleFactory
122 {
123 public CustomerRole CreateRole(string spec, CustomerCore core)
124 {
125 CustomerRole newRole = null;
126
127 if (spec == "Borrower")
128 {
129 newRole = new Borrower(core);
130 }
131 else if (spec == "Investor")
132 {
133 newRole = new Investor(core);
134 }
135
136 return newRole;
137 }
138 }
139
140 public class Client
141 {
142 public void TestCase1()
143 {
144 Customer customer = new CustomerCore(new CustomerRoleFactory());
145 customer.AddRole("Borrower");
146 customer.AddRole("Investor");
147
148 CustomerRole customerRole1 = customer.GetRole("Borrower");
149 Borrower borrower = (Borrower)customerRole1;
150 borrower.SomeCommonOperation1();
151 borrower.SomeOperationForBorrower();
152
153 CustomerRole customerRole2 = customer.GetRole("Investor");
154 Investor investor = (Investor)customerRole2;
155 investor.SomeCommonOperation1();
156 investor.SomeOperationForInvestor();
157 }
158 }
159 }

设计模式之美》为 Dennis Gao 发布于博客园的系列文章,任何未经作者本人同意的人为或爬虫转载均为耍流氓。

 
 

Role Object(角色对象)的更多相关文章

  1. 设计模式之美:Role Object(角色对象)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Role Object 的示例实现. 意图 通过明确地附加角色对象到目标对象中,以使对象可以适配不同的客户需求.每个角色对象都代 ...

  2. js object(对象)

    http://www.cnblogs.com/pingchuanxin/p/5773326.html Object(对象)是在所有的编程语言中都十分重要的一个概念,对于事物我们可以把他们看作是一个对象 ...

  3. Objective -C Object initialization 对象初始化

    Objective -C Object initialization 对象初始化 1.1 Allocating Objects  分配对象 Allocation is the process by w ...

  4. 两种方式实现浅拷贝 for in实现和Object.assign({}, 对象1, 对象2);

    浅拷贝只拷贝对象的一层,如果对象的属性还是对象,那么user3和user4这两个对象对应的值都会发生改变 // 拷贝分为浅拷贝和深拷贝. // 浅拷贝的实现 通过for in实现 var user1 ...

  5. vue2.x版本中Object.defineProperty对象属性监听和关联

    前言 在vue2.x版本官方文档中 深入响应式原理 https://cn.vuejs.org/v2/guide/reactivity.html一文的解释当中,Object.defineProperty ...

  6. swift(Object Storage对象存储服务)(单节点)

    # 在部署对象存储服务(swift)之前,你的环境必须包含身份验证服务(keystone); # keystone需要MySQL数据库,Rabbitmq服务,Memcached服务; # 内存:4G ...

  7. [CareerCup] 14.5 Object Reflection 对象反射

    14.5 Explain what object reflection is in Java and why it is useful. Java中的对象反射机制可以获得Java类和对象的反射信息,并 ...

  8. Qt Meta Object System-元对象系统

    研一的时候开始使用Qt,感觉用Qt开发图形界面比MFC的一套框架来方便的多.后来由于项目的需要,也没有再接触Qt了.现在要重新拾起来,于是要从基础学起. Now,开始学习Qt事件处理机制. 元对象系统 ...

  9. object 属性 对象的继承 (原型, call,apply)

    object 为一切对象的基类! 属性:constructor: 对创建对象的函数的引用Prototype: 原型(类型) hasOwnProperty(property):判断对象是否有某个特定的属 ...

随机推荐

  1. Android项目打包成APK文件

    第一步:右键单击该项目选择Export项目 显演示样例如以下界面:选择Exprot Android Application 第二步:输入项目名称,默认的情况下是原始的项目名称 下一步: 点击 Crea ...

  2. Java中间MD5加密算法完整版

    携带Java软件开发过程.,因此Java中提供了自带的MessageDigest实现对文本的加密算法,以下是一个对文本进行加密的MD5加密工具类代码演示样例: package net.yuerwan. ...

  3. 十天学Linux内核之第九天---向内核添加代码

    原文:十天学Linux内核之第九天---向内核添加代码 睡了个好觉,很晚才起,好久没有这么舒服过了,今天的任务不重,所以压力不大,呵呵,现在的天气真的好冷,不过实验室有空调,我还是喜欢待在这里,有一种 ...

  4. sgu 194 被动散热器具有最大流量的上限和下限(最大流量模板dinic加上优化)

    模板类型的题详细參考国家集训队论文:http://wenku.baidu.com/view/0f3b691c59eef8c75fbfb35c.html 參考博客:http://blog.csdn.ne ...

  5. IronPython和C#交互

    IronPython和C#交互 IronPython是一个.NET平台上的Python实现,包括了完整的编译器.执行引擎与运行时支持,能够与.NET已有的库无缝整合到一起. IronPython已经很 ...

  6. INF 右安装驱动程序和卸载

    INF 右键安装驱动以及卸载 之前写过一篇文章是关于INF文件具体解释的.大家能够參看INF文件具体解释,这次写的是关于INF右键安装,这样比較方便. 卸载的话也是一句话.能够大大降低安装时间: 先将 ...

  7. 【百度地图API】暑假放假回老家——城市切换功能

    原文:[百度地图API]暑假放假回老家--城市切换功能 任务描述: 酸奶小妹放寒假啦,要从北京呼啦一下飞回重庆呢.现在百度地图API上不能直接切换城市,怎么办呢? 如何实现: 利用API先搜索到要去城 ...

  8. MapReduce 编程模型

    一.简单介绍 1.MapReduce 应用广泛的原因之中的一个在于它的易用性.它提供了一个因高度抽象化而变得异常简单的编程模型. 2.从MapReduce 自身的命名特点能够看出,MapReduce ...

  9. OracleServiceORCL服务不见了怎么办

    用管理员身份运行命令提示符(CMD) 然后输入“oradim -new -sid orcl”即可

  10. 如何使用Ubuntu online account API创建微博HTML5申请书

    在这篇文章中.我们将使用Ubuntu SDK提供online account API来訪问微博的API并显示所须要的内容.这篇文章的重点是展示怎样在HTML 5中使用online account AP ...