c# - 我可以使用什么设计模式来完成以下任务

标签 c# design-patterns decorator

在我的代码中,我希望能够“构建”这样的对象..

// Build a Person instance and add types that the person is
Person person = new Person(); 
person = new Leader(person);
person = new Secretary(person);
person = new Parent(person);

上述代码的目标是构建一个添加了多种类型的基础对象 - 领导者、秘书和 parent 。具体来说,我的目标是能够构建一个基础对象 (Person) 并使该对象能够同时采用多种类型,以便以下条件返回 true:

((人是领导) && (人是秘书) && (人是家长)) <<<-- 返回真

有没有我可以用来完成此任务的设计模式?

上述示例的问题在于 person 对象一次只能是一个子类型,并且所有先前的实例化显然都被覆盖了。换句话说,唯一会返回 true 的条件是 (person is Parent)。因为它排在最后。

注意:我最初认为装饰器模式听起来正是我所需要的,但从我读到的内容来看,装饰器模式似乎更多地是关于向对象添加行为与扩展其类型不同。

更新

为了清楚起见 - 我想我应该在我的 OP 中提到我正在尝试用我的类创建一个设计来反射(reflect)我的 RDBM 的设计。

所以,继续原来的例子——

我的 RDBM 包含表 Person、Leader、Secretary 和 Parent。 Person 表有 PersonId PK和其他人有一个 PersonId FK .

当我执行连接所有表的查询时,我可以确定哪些 Person 记录在子表中具有非空 FK。

展开后,查询结果可能如下所示:

PersonId | FirstName | LeaderId | LeaderApproved | SecretaryId | SecretaryFavPencil | ParentId  
----------------------------------------------------------------------------------------------
100      | Frank     | 34       | True           | Null        | Null               | 700
----------------------------------------------------------------------------------------------
743      | Dweezil   | 43       | False          | 343         | Ticon              | 654
----------------------------------------------------------------------------------------------
567      | Ahmet     | Null     | Null           | Null        | Null               | 123
----------------------------------------------------------------------------------------------

上面的结果表向我们展示了 Frank 是领导者和家长; Dweezil 是领导者、秘书和家长,Ahmet 只是家长。

在我的数据访问层中,我使用一个查询来检索所有 Person 记录及其关联的 FK'd 表,实例化 Person 对象,然后将一个 List 返回给调用者。

然后调用者可以对 Person 对象做任何他需要做的事情,但他可以通过 (person is Leader) 检查 Person 对象的所有类型。 .

最佳答案

我认为 Strategy模式应该符合您的需求。
您的问题并未指定您的所有要求,但您可以拥有一个对象,该对象是 Secretary LeaderParent 等类型的组合,然后在运行时,您将必须选择其中一个是当前选择的策略。

此外,假设所有类型都有某种公共(public)接口(interface),组合对象也将实现该接口(interface),您可以将实例保存在数组中,例如:

IPerson[] _rolles  = 
                 new IPerson[]{new Leader(this), new Secretary(this), new Parent(this)};

还有一个类型检查方法,看起来像这样:

        public bool Is(Type type)
        {
            return this.Is(new Type[]{type});
        }

        public bool Is(Type[] types)
        {
            bool isType = true;
            foreach (var type in types)
            {
                isType &= this._rolles.Any(r => r.GetType() == type);
            }
            return isType;
        }

编辑:

更完整的代码示例:

    public class Person : IPerson
    {

        List<IPerson> _rolles;
        IPerson _chosenStrategy;


        public Person()
        {
            this._rolles =
                new List<IPerson>() { new Leader(this), new Secretary(this), new Parent(this) };
            this._chosenStrategy = this._rolles[0];
        }

        public void AddRole(Func<Person, IPerson> creator) {
              IPerson newRole = creator(this)
              //You can choose to remove duplicate roles by uncommenting the following line:
              //this.RemoveRole(newRole.GetType());
              this._rolles.Add(newRole);
        }

        public void RemoveRole(Type type) {
              this._rolles.RemoveAll(r => r.GetType() == type);
        }


         public bool Is(Type type)
        {
            return this.Is(new Type[]{type});
        }

        public bool Is(Type[] types)
        {
            bool isType = true;
            foreach (var type in types)
            {
                isType &= this._rolles.Any(r => r.GetType() == type);
            }
            return isType;
        }

        private void SetStrategy(Type type)
        {
            this._chosenStrategy = this._rolles.Where(r => r.GetType() == type).FirstOrDefault();
        }

        /*Rest of Implementation goes here*/
    }

以及其他需要的类:

    interface IPerson
    {
        /*Implementation goes here*/
    }
    class Leader : IPerson
    {
        public Leader(IPerson p)
        {

        }
        /*Rest of Implementation goes here*/
    }

    class Parent : IPerson
    {
        public Parent(IPerson p)
        {

        }
    }

    class Secretary : IPerson
    {
        public Secretary(IPerson p)
        {

        }
        /*Rest of Implementation goes here*/
    }

关于c# - 我可以使用什么设计模式来完成以下任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25356672/

相关文章:

python - 装饰一个 python 类,使得大多数方法在有条件时引发异常

java - 复合模式/实体系统与传统 OOP

c# - C#中的类实例通信

c# - IServiceCollection 不包含 AddAzureClients 的定义

c# - ASP.NET Web API 上 HttpActionContext.RequestContentKeyValueModel 的替代方案

ios - Objective-C 和类集群模式

没有装饰器的reactjs mox无法工作

python - timeit.timeit 方法的装饰器?

c# - 使用信号量而不是 while 循环。这是好事还是坏事?

c# - 用于获取用户电子邮件的 Security.Principal.IIdentity 扩展方法