设计模式之美: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 的示例实现。
namespace RoleObjectPattern.Implementation1
{
public abstract class Customer
{
public abstract CustomerRole GetRole(string spec);
public abstract void AddRole(string spec);
public abstract void RemoveRole(string spec);
public abstract bool HasRole(string spec);
public abstract void SomeCommonOperation1();
} public class CustomerCore : Customer
{
private Dictionary<string, CustomerRole> _roles
= new Dictionary<string, CustomerRole>();
private CustomerRoleFactory _roleFactory; public CustomerCore(CustomerRoleFactory roleFactory)
{
_roleFactory = roleFactory;
} public override CustomerRole GetRole(string spec)
{
if (_roles.ContainsKey(spec))
return _roles[spec];
else
return null;
} public override void AddRole(string spec)
{
CustomerRole role = GetRole(spec);
if (role == null)
{
role = _roleFactory.CreateRole(spec, this);
if (role != null)
{
_roles.Add(spec, role);
}
}
} public override void RemoveRole(string spec)
{
_roles.Remove(spec);
} public override bool HasRole(string spec)
{
return _roles.ContainsKey(spec);
} public override void SomeCommonOperation1()
{
// do some business logic
}
} public class CustomerRole : Customer
{
private CustomerCore _decoratedCore; public CustomerRole(CustomerCore core)
{
_decoratedCore = core;
} public override CustomerRole GetRole(string spec)
{
return _decoratedCore.GetRole(spec);
} public override void AddRole(string spec)
{
_decoratedCore.AddRole(spec);
} public override void RemoveRole(string spec)
{
_decoratedCore.RemoveRole(spec);
} public override bool HasRole(string spec)
{
return _decoratedCore.HasRole(spec);
} public override void SomeCommonOperation1()
{
_decoratedCore.SomeCommonOperation1();
}
} public class Borrower : CustomerRole
{
public Borrower(CustomerCore core)
: base(core)
{
} public void SomeOperationForBorrower()
{
// do something for borrower
}
} public class Investor : CustomerRole
{
public Investor(CustomerCore core)
: base(core)
{
} public void SomeOperationForInvestor()
{
// do something for investor
}
} public class CustomerRoleFactory
{
public CustomerRole CreateRole(string spec, CustomerCore core)
{
CustomerRole newRole = null; if (spec == "Borrower")
{
newRole = new Borrower(core);
}
else if (spec == "Investor")
{
newRole = new Investor(core);
} return newRole;
}
} public class Client
{
public void TestCase1()
{
Customer customer = new CustomerCore(new CustomerRoleFactory());
customer.AddRole("Borrower");
customer.AddRole("Investor"); CustomerRole customerRole1 = customer.GetRole("Borrower");
Borrower borrower = (Borrower)customerRole1;
borrower.SomeCommonOperation1();
borrower.SomeOperationForBorrower(); CustomerRole customerRole2 = customer.GetRole("Investor");
Investor investor = (Investor)customerRole2;
investor.SomeCommonOperation1();
investor.SomeOperationForInvestor();
}
}
}
《设计模式之美》为 Dennis Gao 发布于博客园的系列文章,任何未经作者本人同意的人为或爬虫转载均为耍流氓。
设计模式之美:Role Object(角色对象)的更多相关文章
- 设计模式之美:Object Pool(对象池)
索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):实现 DatabaseConnectionPool 类. 实现方式(二):使用对象构造方法和预分配方式实现 ObjectPool ...
- Role Object(角色对象)
Role Object(角色对象) 索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Role Object 的示例实现. 意图 通过明确地附加角色对象到目标对象中,以使对象可以 ...
- 设计模式之美:Type Object(类型对象)
索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Type Object 的经典介绍. 实现方式(二):Type Object 在游戏设计中的使用. 意图 允许在运行时动态灵活的 ...
- 设计模式之美:Extension Object(扩展对象)
索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):使用示例结构实现 Extension Object. 实现方式(二):使用泛型实现 IExtensibleObject<T ...
- 设计模式之美:Null Object(空对象)
索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Null Object 的示例实现. 意图 通过对缺失对象的封装,以提供默认无任何行为的对象替代品. Encapsulate t ...
- 设计模式之美:Product Trader(操盘手)
索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Product Trader 的示例实现. 意图 使客户程序可以通过命名抽象超类和给定规约来创建对象. Product Trad ...
- 设计模式之美:Dynamic Property(动态属性)
索引 别名 意图 结构 参与者 适用性 效果 实现 实现方式(一):Dynamic Property 的示例实现. 别名 Property Properties Property List 意图 使对 ...
- 设计模式之美:Manager(管理器)
索引 意图 结构 参与者 适用性 效果 实现 实现方式(一):Manager 模式的示例实现. 意图 将对一个类的所有对象的管理封装到一个单独的管理器类中. 这使得管理职责的变化独立于类本身,并且管理 ...
- 设计模式之美:Visitor(访问者)
索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Visitor 模式结构样式代码. 实现方式(二):使用 Visitor 模式解构设计. 实现方式(三):使用 Acyclic ...
随机推荐
- 2. Abstract Factory(抽象工厂)
意图: 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 适用性: 一个系统要独立于它的产品的创建.组合和表示时. 一个系统要由多个产品系列中的一个来配置时. 当你要强调一系列相关 ...
- freeCodeCamp:Where do I belong
我身在何处? 先给数组排序,然后找到指定的值在数组的位置,最后返回位置对应的索引. 举例:where([1,2,3,4], 1.5) 应该返回 1.因为1.5插入到数组[1,2,3,4]后变成[1,1 ...
- SAAS在中国市场的发展前景
发展现状 2008年1-7月软件行业实现收入4199.1亿元,同比增长32.4%.2008年第一季度,业务管理软件市场总量达16.31亿元,同比增长17.8%.面对成本的上升,企业选择了向信息化要效率 ...
- adb unknown host service 这个问题的解决,转载
一直没搞明白这个问题咋出现的,但今天看到一个方法,搞定了!原来是豌豆荚占用了 5037 端口导致. 参见原文章:一个豌豆荚引发的血案——关于ADB server didn't ACK的问题 简单来讲, ...
- 【Java】JDBC连接数据库
JDBC介绍 JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言 ...
- 如何让你的UWP应用程序无缝调用几何作图
有时候需要编辑一些几何图形,如三角形,圆锥曲线等,在UWP应用中加入这些几何作图功能是件费时间又很难做好的事.其实Windows 10 应用商店中已有一些专业的几何作图工具了,那么能借来一用吗?答案是 ...
- VMware 12 的vmware tools安装和如何使用(系统是CENTOS6.5)
1.用了一下虚拟机vmware12,但是总是没法使用它的vmware Tool ,网上一直说在哪个哪个文件夹,其实并没有 2.于是我用命令行找到了在系统中的VMware Tools 3.首先,保证li ...
- git 笔记
查看某个提交的修改:git show commitID 查看某个提交修改涉及的文件:git show commitID --oneline --name-status 清理掉没有入库的文件,并把修改了 ...
- VS2010 网页错误
VS2010向导添加消息处理时,弹出以上错误,原因之一为: 类内没有定义IDD的宏
- Hyper-V初涉:功能的添加与虚拟机的创建
Hyper-V是微软提供的一款高效率的虚拟化管理软件,在早期的Windows服务器中配备Hyper-V组件,Windows 8是首次将企业用Hyper-V集成在个人系统中,可见虚拟化技术的发展之迅速. ...