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

索引

  • 意图

  • 结构

  • 参与者

  • 适用性

  • 效果

  • 相关模式

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

时间: 2024-10-06 22:30:27

设计模式之美:Role Object(角色对象)的相关文章

设计模式之美:Null Object(空对象)

索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Null Object 的示例实现. 意图 通过对缺失对象的封装,以提供默认无任何行为的对象替代品. Encapsulate the absence of an object by providing a substitutable alternative that offers suitable default do nothing behavior. In short, a design where "nothing w

角色对象模式

意图 单个对象透过不同的角色对象来满足不同客户的不同需求.每一个角色对象针对不同的客户内容来扮演其角色.对象能够动态的管理其角色集合.角色作为独立的对象是的不同的内容能够简单的被分离开来,系统间的配置也变得容易. 译注:为了行文的流畅性及内容意思的准确性,尽量贴近原文使用英文单词标记特定内容, 如Customer表示客户,Client表示客户端,Component表示组件等.因为有各种图例说明,所以在图例说明时,使用原题中的英文单词对应图中内容.有时也中英文交叉使用.因为网页显示的问题,中文黑体

设计模式之美:Manager(管理器)

索引 意图 结构 参与者 适用性 效果 实现 实现方式(一):Manager 模式的示例实现. 意图 将对一个类的所有对象的管理封装到一个单独的管理器类中. 这使得管理职责的变化独立于类本身,并且管理器还可以为不同的类进行重用. Encapsulates management of a class's objects into a separate manager object. This allows variation of management functionality independ

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

索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Product Trader 的示例实现. 意图 使客户程序可以通过命名抽象超类和给定规约来创建对象. Product Trader 让客户程序与 Product 类解耦,从而使得类的层级结构.框架和应用程序易于改写.配置和演进. Let clients create objects by naming an abstract superclass and by providing a specification. A Pr

设计模式 ( 十三 ) 命令模式Command(对象行为型)

设计模式 ( 十三 ) 命令模式Command(对象行为型) 1.概述 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活. 例子1:电视机遥控器 : 遥控器是请求的发送者,电视机是请求的接收者,遥控器上有一些按钮如开,关,换频道等按钮就是具体命令,不同的按钮对应电视机的不同操作. 2.问题

设计模式之美:Dynamic Property(动态属性)

索引 别名 意图 结构 参与者 适用性 效果 实现 实现方式(一):Dynamic Property 的示例实现. 别名 Property Properties Property List 意图 使对象可以为客户提供广泛且可扩展的属性集合. Lets an object provides a generic and extensible set of properties to clients. 结构 参与者 Object 目标对象可存储 Property 列表. 可使用不同的类型来作为 Pro

Objective -C Object initialization 对象初始化

Objective -C Object initialization 对象初始化 1.1 Allocating Objects  分配对象 Allocation is the process by which a new object is born. allocation 是新对象诞生的过程. Sending the alloc message to a class causes that class to allocate a chunk of memory large enough to

Qt Meta Object System-元对象系统

Qt Meta Object System-元对象系统 元对象系统的构成 QObject为所有需要利用元对象系统的对象提供一个基类. Q_OBJECT宏,在类的声明体内激活meta-object功能,比如动态属性.信号和槽. Meta Object Compiler(MOC),为每个QObject派生类生成代码,以支持meta-object功能. QObject定义了从一个QObject对象访问meta-object功能的接口,Q_OBJECT宏用来告诉编译器该类需要激活meta-object功

C# 将object类型对象(注:必须是可序列话的对象)转换为二进制序列字符串

1 public string SerializeObject(object obj) 2 { 3 //将object类型对象(注:必须是可序列化的对象)转换为二进制序列字符串 4 IFormatter formatter=new BinaryFormatter(); 5 string result=string.Empty; 6 using(MemoryStream stream=new MenmoryStream()) 7 { 8 formatter.Serialize(sream.obj)