2011-10-24 2 views
0

워크 플로 계층에 대한 저장소 솔루션을 작성 중입니다.데이터 컨테이너와 동작이 결합 된 개체

그림을 단순화하기 위해 워크 플로와 워크 플로우 스텝의 두 가지 유형의 개체가 있습니다.

WorkflowStep은 워크 플로 아래에서 계층 적으로 제공되지만 워크 플로는 이러한 개체를 데이터 컨테이너로보기 때문에 WorkflowStep을 집계하지 않습니다.

그래서이 다음과 같은 클래스로 날 나뭇잎 :

public class Workflow : Node { 
    public string UID; 
    public string parentID; 
} 

public class WorkflowStep : Node { 
    public string UID; 
    public string parentID; 
} 

public class WorkflowEngine { 
    public void Store(Workflow wf) { 
    } 

    public void Store(WorkflowStep wfs) { 
    } 
} 

(논리적으로 그에 맞는에도 불구하고) 워크 플로우 내에서 WorkflowStep를 집계하지 않는 추론 이러한 개체는 순수한 데이터 컨테이너로 간주하고 그들이 대상이 될 수 있다는 것이다 나중에 변경하기 위해 우리는 이러한 객체의 저장소를 객체 자체와 분리 된 상태로 유지하려고합니다.

물론 다른 대안이 그런 짓을하는 것입니다 :

public class Workflow : Node { 
    public List<WorkflowStep> steps; 
    public string UID; 
    public string parentUID; 

    public void Store() { } 
} 

public class WorkflowStep : Node { 
    public string UID; 
    public string parentID; 

    public void Store() { } 
} 

중 접근 방식의 장점과 단점은 무엇입니까? 두 가지 디자인에 대해 이야기하는 자료가 있습니까?

+0

정말 .. 데이터가 작동되는 방식과 전체적인 그림에 맞는 방식에 따라 다릅니다. – Ankur

답변

1

WorkflowWorkflowStep이 둘 다 데이터 컨테이너이지만 계층 적 조치를 따로 유지한다고해서 디커플링 문제가 해결되지는 않습니다.

Workflow의 계층에 WorkflowStep을 유지하고 디커플링에 부합하려면이 경우 IoC을 도입해야합니다.

IoC의 아름다움은 단지 당신의 IoC 용기에 유형을 등록하기 위해 고려 될 위치를 Workflow 클래스의 목록입니다 WorkflowStep의 정의를 변경하면 바로 투명해야한다는 것입니다.

NinjectIoC 컨테이너 프레임 워크를 예로 들어 보겠습니다.

인터페이스를 정의하고 그에 따라 데이터 컨테이너를 구현 :

public interface IWorkflow { 
    string UID { get; set; }  
    string parentID { get; set; } 
    IList<IWorkflowStep> Steps { get; set; } 
} 

public interface IWorkflowStep { 
    string UID { get; set; }  
    string parentID { get; set; } 
} 

public class Workflow : IWorkflow, Node { 

    public string UID { get; set; }; 
    public string parentID { get; set; }; 
    public IList<IWorkflowStep> Steps { get; set; } 
} 

public class WorkflowStep : IWorkflowStep, Node { 
    public string UID { get; set; }; 
    public string parentID { get; set; }; 
} 

그리고 지금이의 Ninject에 모듈 수 :

public class WorkflowModule : NinjectModule 
{ 
    #region Overrides of NinjectModule 

    public override void Load() 
    { 
     Bind<IWorkflow>().To<Workflow>(); 
     Bind<IWorkflowStep>().To<WorkflowStep>(); 
     Bind<IList>().To<List>(); 
    } 

    #endregion 
} 

이것은 당신이 구체적인 클래스와 인터페이스를 결합하는 단일 장소입니다. 그리고 나머지 세계에서는 정의 된 인터페이스의 인스턴스를 요청합니다.

당신의 유형을 해결하려면, 당신은 IKernel 종류와 정의 모듈를로드하여 StandardKernel의 구체적인 구현하는 Ninject에 Kernel을 작성해야합니다.뭔가처럼

지금

var kernel = new StandardKernel(new WorkflowModule()); 

, 당신이해야 할 같은 원하는 인터페이스, 해결되어, 당신은 걱정할 필요가 없습니다 여기

IWorkflow workflow = kernel.Get<IWorkflow>(); 
IWorkflowStep workflowStep = kernel.Get<IWorkflowStep>(); 

아름다움을 귀하의 구체적인 구현에 대해 그리고 귀하의 시스템 내에서 매우 밀접하게 결합되어 있습니다. 당신이 다루고 휴식하는 인터페이스는 IoC 컨테이너 구현의 걱정입니다.

WorkflowStep의 구현에 대해 걱정하고 있으므로 변경하지 말고 Workflow으로 연결하십시오. 제 생각에는 여기가 IoC입니다.

는 당신이 처럼 유니티, Spring.NET, StructureMap 어떤 IoC 컨테이너 프레임 워크를 사용할 수있는 등 내가 편안이기 때문에 내가 Ninject에 사용, 주목하시기 바랍니다.