我可以使用什么设计模式来完成以下任务
本文关键字:任务 可以使 什么 设计模式 我可以 | 更新日期: 2023-09-27 18:18:30
在我的代码中,我希望能够"构建"这样的对象。
// 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);
上述代码的目标是构建一个添加了多种类型的基对象 - 领导者、秘书和父级。具体来说,我的目标是能够构建一个基本对象 (Person(,并使该对象能够同时采用多种类型,以便以下条件返回 true:
((人是领导者(&&(人是秘书(&&(人是父母(( <<<-- 返回 True
是否有可用于完成此操作的设计模式?
上述示例的问题在于,person 对象一次只能是一个子类型,并且显然,所有以前的实例化都被覆盖了。换句话说,唯一会返回 true 的条件是 (person is Parent)
,因为它是最后一个。
注意:我最初认为装饰器模式听起来像我需要的,但从我读到的内容来看,装饰器模式似乎更多的是向对象添加行为,以扩展其类型。
更新
为了清楚起见 - 我想我应该在我的 OP 中提到我正在尝试用我的类创建一个反映我的 RDBM 设计的设计。
所以,继续使用原始示例 -
我的 RDBM 包含"人员"、"领导"、"秘书"和"家长"表。"人员"表具有PersonId PK
,其他表具有PersonId FK
。
当我执行联接所有表的查询时,我可以确定哪些人员记录在子表中具有非空 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
----------------------------------------------------------------------------------------------
上面的结果表向我们表明,弗兰克是领导者和父母;Dweezil是领导者,秘书和父母,艾哈迈德只是父母。
在我的数据访问层中,我使用一个查询来检索所有 Person 记录及其关联的 FK'd 表,实例化 Person 对象,然后将 List 返回给调用方。
然后,调用方可以对 Person 对象执行任何需要执行的操作,但他能够通过 (person is Leader)
检查 Person 对象的所有类型。
我认为策略模式应该符合您的需求。
您的问题没有指定您的所有要求,但是您可以拥有一个组合类型的对象,例如 Secretary
Leader
和 Parent
,然后在运行时,您必须选择其中哪一个是目前选择的策略。
此外,假设所有类型都有某种通用接口,组合对象也将实现该接口,您可以将实例保留在数组中,如下所示:
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*/
}
((人是领导者(&&(人是秘书(&&(人是父母(( <<<-- 返回 True
从技术上讲,这是可能的,但前提是领导者是另外两个领导者之一,并且其他两个中的一个始终是其他领导者之一。
public Leader : Person { }
public Secretary : Leader { }
public Parent : Secretary/Leader { }
如果情况并非总是如此,则无法使用该特定代码进行特定请求。
如果您死心塌地地使用 is
,那么或者,您可以使用接口:
((person is ILeader( && (person isISecretary( && (person is IParent(( <<<-- 返回 True
public inteface IPerson;
public inteface ILeader : IPerson;
public interface ISecretary : IPerson;
public interface IParent : IPerson;
public Leader : ILeader;
public Secretary : ISecretary;
public Parent : IParent;
public LeaderSecretary : ILeader, ISecretary;
public LeaderParent : ILeader, IParent;
public SecretaryParent: ISecretary, IParent,
public LeaderSecretaryParent: ILeader, ISecretary, IParent;
但认真地不要这样做。
第一。OOP 中的类主要用于表达行为。你说"似乎更多的是关于向对象添加行为"意味着你的类与行为无关。如果不是,那么它们是关于什么的?
((person is Leader) && (person is Secretary) && (person is Parent))
OOP 中的类型用于编译器。在 OOP 编程中使用类型作为程序逻辑的一部分被认为是错误的做法。此外,遵循此代码显然是一种行为。因此,与其试图弄乱类型,不如总结您的需求并找出一个确实满足您要求的设计。在您的情况下,第一个要求是能够在运行时更改人员的"角色"。如果这不会改变行为,简单的Enum
就足够了。如果有行为,那么战略,也许与复合相结合是可能的。第二个要求是具有行为,只有当人有多个角色时才执行。如果您使用的是枚举,那么它很简单。但是当你使用策略时,它会变得更加复杂。虽然我没有确切的解决方案,但我认为如果您要进行类型检查,那么它应该封装在某种"工厂"中,该工厂根据人及其角色创建行为。
我认为你需要的是装饰器模式,你可以使用工厂和策略来帮助你。 希望这能给你一个想法