C# 具有多态对象的状态设计模式

C# 具有多态对象的状态设计模式,c#,design-patterns,.net-4.0,polymorphism,state-pattern,C#,Design Patterns,.net 4.0,Polymorphism,State Pattern,我有一个对象层次结构,所有对象都有类似的行为。我想将行为与POCO定义分开。由于这些行为表示将对象移动到不同的状态,因此在我看来,这就像是状态模式的工作。但是,这并不像每个函数都有一个单一的定义那么简单,因为每个对象可能有稍微不同的行为 例如,假设我有以下基于抽象基类的类: public abstract BaseClass { public int Property1 { get; set; } public int Property2 { get; set; } } pub

我有一个对象层次结构,所有对象都有类似的行为。我想将行为与POCO定义分开。由于这些行为表示将对象移动到不同的状态,因此在我看来,这就像是状态模式的工作。但是,这并不像每个函数都有一个单一的定义那么简单,因为每个对象可能有稍微不同的行为

例如,假设我有以下基于抽象基类的类:

public abstract BaseClass
{
    public int Property1 { get; set; }
    public int Property2 { get; set; }
}

public Class1 : BaseClass
{
    public string PropertyA { get; set; }
    public string PropertyB { get; set; }
}

public Class2 : BaseClass
{
    public string PropertyC { get; set; }
    public string PropertyD { get; set; }
}
层次结构表示不同类型的对象。也可以说,这些对象都遵循相同的基本工作流:提交、批准、执行、关闭

现在,每个函数的行为也是分层的,这意味着对Class1调用函数Approve()应该与从基类调用继承的行为相同,但是Class2将重写Approve()函数,因为该类型遵循不同的审批流程

我无法将状态模式应用于这些对象。我可以选择将函数放在对象本身上,并以这种方式继承它们,这很好,但它破坏了POCO设计。我还可以为每个对象类型使用switch语句来实现Approve()函数,但这破坏了我的多态设计

如何将状态模式应用于多层多态对象定义并与设计原则保持一致


更新:让我澄清一下,我认为除了作用于对象之外还做其他事情的函数不属于POCO。例如:Approve功能将发送电子邮件并触发其他系统中的事件,而不仅仅是修改对象的状态。也许这就是我。

只是想让您了解如何集中定义状态间转换的代码。那个时候泛型是相当新的,所以它有点重。无论哪种方式,它都可能为您提供关于如何实现状态模式的另一种视角。

在对象上添加方法并不会破坏“POCO设计”(没有标准的“POCO设计”),因为POCO只是一个术语,用于将您拥有的简单对象与使用更大框架的更复杂或更重的对象进行对比。该术语通常与ORM一起使用,用于区分简单CLR类型的对象(因此称为“普通旧CLR对象”首字母缩写)和从通用实现特定基类型继承的对象。类似地,POCO还可以用来表示类型本身与使用它的ORM或库没有直接连接,因此可以很容易地与其他类型一起使用

因此,简而言之,按照您描述的方法对类型执行

我可以选择将函数放在对象本身上,并以这种方式继承它们,这很好,但它破坏了POCO设计

所以我同意这里的每个人的观点,它不会破坏你的POCO设计。例如,它可能看起来像这样:

  public class BaseClass
  {
     public int Property1 { get; set; }
     public int Property2 { get; set; }
     public virtual bool Submitted() { return (Property1 != 0); }
     public virtual bool Approved() { return (Property2 != 0); }
     // ...
  }

  public class Class1 : BaseClass
  {
     public string PropertyA { get; set; }
     public string PropertyB { get; set; }
     public override bool Submitted() 
     { return !String.IsNullOrEmpty(PropertyA); }
     public override bool Approved() 
     // Or do specific Class1 Approval actions...
     { return !String.IsNullOrEmpty(PropertyB); }
     // ...
  }

  public class Class2 : BaseClass
  {
     public string PropertyC { get; set; }
     public string PropertyD { get; set; }
     public override bool Submitted()
     { return !String.IsNullOrEmpty(PropertyC); }
     public override bool Approved()
     { return !String.IsNullOrEmpty(PropertyD); }
     // ...
  }

  public abstract class WorkflowState<PocoType> 
     where PocoType : BaseClass
  {
     private WorkflowManager<PocoType> _workflowManger;
     private PocoType _pocoObject;

     public WorkflowManager<PocoType> Workflow
     {
        get { return _workflowManger; }
        set { _workflowManger = value; }
     }

     public PocoType PocoObject
     {
        get { return _pocoObject; }
        set { _pocoObject = value; }
     }

     public abstract void Submitted();
     public abstract void Approved();
     // ...
  }

  public class InitialState<PocoType> : 
     WorkflowState<PocoType> where PocoType : BaseClass
  {
     public InitialState(PocoType pocoObject)
     {
        base.PocoObject = pocoObject;
     }

     public override void Submitted()
     {
        if (PocoObject.Submitted())
        {
           // move to approved state if submitted is ok for the poco
           // definition
           Workflow.State = new ApprovedState<PocoType>(this);
        }
     }

     public override void Approved()
     {
        // Not supported state
        throw new InvalidOperationException();
     }

     // ...
  }

  public class ApprovedState<PocoType> :
     WorkflowState<PocoType> where PocoType : BaseClass
  {
     public ApprovedState(WorkflowState<PocoType> state)
     {
        base.PocoObject = state.PocoObject;
        base.Workflow = state.Workflow;
     }

     public override void Submitted()
     {
        // Not supported state
        throw new InvalidOperationException();
     }

     public override void Approved()
     {
        if (PocoObject.Approved())
        {
           // next state ...
           //Workflow.State = ...
           //Send emails
           //Do approval items
        }
     }
  }

  public class WorkflowManager<PocoType> where PocoType : BaseClass
  {
     WorkflowState<PocoType> _state;

     public WorkflowManager(PocoType pocoObject)
     {
        this._state = new InitialState<PocoType>(pocoObject);
        this._state.Workflow = this;
     }

     public WorkflowState<PocoType> State
     {
        get { return _state; }
        set { _state = value; }
     }

     public void RunWorkflow()
     {
        State.Submitted();
        State.Approved();
     }
  }
Class1 test = new Class1();
test.PropertyA = "hello";
WorkflowManager<Class1> work_flow_man = new WorkflowManager<Class1>(test);
work_flow_man.RunWorkflow();

Class2 test2 = new Class2();
test2.PropertyC = "cool";
test2.PropertyD = "dude";
WorkflowManager<Class2> work_flow_man2 = new WorkflowManager<Class2>(test2);
work_flow_man2.RunWorkflow();
公共类基类
{
公共int属性1{get;set;}
公共int属性2{get;set;}
公共虚拟bool Submitted(){return(Property1!=0);}
公共虚拟bool Approved(){return(Property2!=0);}
// ...
}
公共类1:基类
{
公共字符串属性{get;set;}
公共字符串属性b{get;set;}
公共覆盖bool已提交()
{return!String.IsNullOrEmpty(PropertyA);}
公共覆盖bool已批准()
//或执行特定的1类批准操作。。。
{return!String.IsNullOrEmpty(PropertyB);}
// ...
}
公共类2:基类
{
公共字符串PropertyC{get;set;}
公共字符串PropertyD{get;set;}
公共覆盖bool已提交()
{return!String.IsNullOrEmpty(PropertyC);}
公共覆盖bool已批准()
{return!String.IsNullOrEmpty(PropertyD);}
// ...
}
公共抽象类WorkflowState
其中PocoType:BaseClass
{
私人工作流管理器(WorkflowManager);;
私有PocoType_pocoObject;
公共工作流管理器工作流
{
获取{return\u workflowmanager;}
设置{u workflowManger=value;}
}
公共PocoType PocoObject
{
获取{return\u pocoObject;}
设置{u pocoObject=value;}
}
提交的公开摘要无效();
已批准的公开摘要无效();
// ...
}
公共类初始状态:
PocoType:BaseClass所在的WorkflowState
{
公共初始状态(PocoType pocoObject)
{
base.PocoObject=PocoObject;
}
已提交的公共覆盖无效()
{
if(PocoObject.Submitted())
{
//如果poco的“提交”符合要求,则移至“已批准”状态
//定义
Workflow.State=新批准的状态(此状态);
}
}
公共覆盖无效已批准()
{
//不支持状态
抛出新的InvalidOperationException();
}
// ...
}
公共类批准状态:
PocoType:BaseClass所在的WorkflowState
{
公共批准状态(WorkflowState状态)
{
base.PocoObject=state.PocoObject;
base.Workflow=state.Workflow;
}
已提交的公共覆盖无效()
{
//不支持状态
抛出新的InvalidOperationException();
}
公共覆盖无效已批准()
{
如果(PocoObject.Approved())
{
//下一个州。。。
//Workflow.State=。。。
//发送电子邮件
//是否批准项目
}
}
}
公共类WorkflowManager,其中PocoType:BaseClass
{
工作流程状态_状态;
公共工作流管理器(PocoType pocoObject)
{
此._状态=新初始状态(pocoObject);
this.\u state.Workflow=此;
}
公共工作流状态
{
获取{return\u state;}
设置{u state=value;}