角色对象模式问题
本文关键字:问题 模式 对象 角色 | 更新日期: 2023-09-27 18:00:28
我正在看马丁·福勒写的一篇题为《处理角色》的论文。在这本书中,Fowler提出了三种处理组织中一个人角色的基本策略(即员工、工程师、经理、推销员),包括角色子类型、角色对象和角色关系。
这本书写于1997年,当然很老了,作为一本"工作草案",它也有一些错误,否则就不会出现。我对他所经历的角色对象的一个例子感到困惑,并在下面包含了我对他的一些java代码的c#解释。
我有三个问题:
(1) 有很多类型识别是用字符串来完成的,似乎它应该用泛型来替换,但我还不知道如何做到这一点。您将如何使用泛型实现这些代码
(2) JobRole在代码中作为类型的字符串名称,但它并没有与代码的其余部分一起具体定义。我不知道这是否是PersonRole的基类。JobRole的定义是什么?单元测试看起来像是模式用法的正确示例吗
(3) 是否有人链接到最近的实现和使用角色对象的示例?
干杯,
Berryl
public class PersonWithRoles : Person
{
private readonly IList<PersonRole> _roles = new List<PersonRole>();
public static PersonWithRoles CreatePersonWithRoles(string identifierName) {
...
}
public void AddRole(PersonRole role) { _roles.Add(role); }
public PersonRole RoleOf(string typeName) { return _roles.FirstOrDefault(x => x.HasType(typeName)); }
}
public class PersonRole
{
public virtual bool HasType(string typeName) { return false; }
}
public class Salesman : PersonRole
{
public override bool HasType(string typeName)
{
if (typeName.Equals("Salesman", StringComparison.InvariantCultureIgnoreCase)) return true;
if (typeName.Equals("JobRole", StringComparison.InvariantCultureIgnoreCase)) return true;
return base.HasType(typeName);
}
public int NumberOfSales { get; set; }
}
[TestFixture]
public class RoleUsageTests
{
[Test]
public void Test() {
var p = PersonWithRoles.CreatePersonWithRoles("Ted");
var s = new Salesman();
p.AddRole(s);
var tedSales = (Salesman) p.RoleOf("Salesman");
tedSales.NumberOfSales = 50;
}
}
我相信这些类型的应用程序非常适合使用装饰器设计模式,其中有一个Person基类,然后每个角色都扩展该基类。基类没有权限声明——只有扩展person的角色类才应该声明权限。
抱歉含糊其辞,但我希望你明白我想要描述的。
class programmer {
name ...
email ...
seat location ...
}
class html_coder extends programmer {
canCodeHTML ...
}
class script_coder extends programmer {
canCodeHTML ...
canCodeJavascript ...
}
class senior_developer extends programmer {
canCodeHTML ...
canCodeJavascript ...
canAccessDatabase ...
canEditProjectArchitectureFiles ...
canWearTennisShoesToWork...
}
这些都扩展了程序员的基类。。。注意,程序员类没有声明权限。。。仅属性
- c#中的泛型可以帮助实现更整洁
JobRole
是PersonRole
的子类型,是特定作业的超类型
我仍然想看看用法的例子,因为Fowler关于这个模式的观点之一是,打字的灵活性是以两步用法模式为代价的。使用Decorator模式实现这一点不会改变这一点。例如,要处理一个扮演推销员角色的人,首先需要获取一个人的实例,然后找到推销员的角色。
干杯,
Berryl
public class Person
{
public FullName FullName { get; set; }
public IList<IRole> Roles { get; private set; }
public Person(FullName fullName) => FullName = fullName;
public IRole GetRoleOf<T>() where T: IRole =>
Roles.FirstOrDefault(x => x.HasType(typeof(T)));
public void AddRole(IRole role) => Roles.Add(role);
public bool RemoveRole(IRole role) => Roles.Remove(role);
}
public interface IRole
{
bool HasType(Type type);
}
public abstract class Role : IRole
{
public virtual bool HasType(Type type) { return false; }
}
// Base type for any type of role for a person.
public class PersonRole : Role
{
public override bool HasType(Type type) => type.Equals(typeof(PersonRole));
}
// Base type for any type of role for a person.
public class JobRole : Role
{
public override bool HasType(Type type)
{
if (type.Equals(GetType())) return true;
return base.HasType(type);
}
}
// Behavior specific to a salesman
public class Salesman : JobRole, ISalesman
{
public override bool HasType(Type type)
{
if (type.Equals(GetType())) return true;
return base.HasType(type);
}
public int NumberOfSales { get; set; }
}
[TestFixture]
public class JobRoleTests : BaseTestFixture
{
private PersonEx _person;
protected override void OnFixtureSetUp()
{
_person = new PersonEx(new OneNameFullName("schmuck"));
// can be a Salesman
_person.AddRole(new Salesman());
}
[Test]
public void Salesman_CanGet()
{
var salesman = _person.GetRoleOf<Salesman>() as Salesman;
Assert.That(salesman, Is.Not.Null);
salesman.NumberOfSales = 50;
Assert.That(salesman.NumberOfSales, Is.EqualTo(50));
}
}