角色对象模式问题

本文关键字:问题 模式 对象 角色 | 更新日期: 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...
}

这些都扩展了程序员的基类。。。注意,程序员类没有声明权限。。。仅属性

  1. c#中的泛型可以帮助实现更整洁
  2. JobRolePersonRole的子类型,是特定作业的超类型

我仍然想看看用法的例子,因为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));
    }
}