문제

이것은 주로 사고 실험입니다. 그래서 이것은 모두 샘플 코드입니다. 저의 목표는 사양 패턴을 사용하여 공장 내에서 거대한 조건부 코드 블록을 제거하는 것이 었습니다. 따라서이 샘플을 사용하면 istatusupdate를 구현하고 싶은 상태 데이터 객체가 있습니다.

다음과 같은 테스트 세트가 있습니다.

    [TestMethod]
    public void Factory_Interface_Should_Return_IStatusUpdate()
    {
      var factory = MockRepository.GenerateMock<IUpdateFactory<StatusData>>();
      var obj = MockRepository.GenerateStub<IStatusUpdate>();

      var data = new StatusData();
      factory.Stub(x => x.Get(data)).Return(obj);

      var item = factory.Get(data);

      Assert.IsInstanceOfType(item, typeof(IStatusUpdate));
    }

    [TestMethod]
    public void StatusUpdateFactory_Should_Return_IStatusUpdate()
    {
      var factory = new StatusUpdateFactory();
      var data = new StatusData();

      var item = factory.Get(data);

      Assert.IsInstanceOfType(item, typeof(IStatusUpdate));   
    }

    [TestMethod]
    public void StatusUpdateFactory_Should_Return_NewStatusUpdate_When_Status_Is_New()
    {
      var data = new StatusData(Status.New);
      var factory = new StatusUpdateFactory();

      var item = factory.Get(data);

      Assert.IsInstanceOfType(item, typeof(NewStatusUpdate));
    }

지금까지의 공장 구현은 다음과 같습니다.

public class StatusUpdateFactory:IUpdateFactory<StatusData>
  {
    public IStatusUpdate Get(StatusData item)
    {
      IList<ISpecification<StatusData>> specs = GetSpecifications();

      foreach (var spec in specs)
      {
        if (spec.IsSatisfiedBy(item))
          //how do I do this?
           return new NewStatusUpdate();

      }
      return null;
    }

    private IList<ISpecification<StatusData>> GetSpecifications()
    {
      var returnList = new List<ISpecification<StatusData>>();
      var specTypes = this.GetType().Assembly.GetTypes()
                        .Where(z => z.IsInstanceOfType(typeof(ISpecification<StatusData>)))
                        .ToList();


      specTypes.ForEach(x => returnList.Add(Activator.CreateInstance(x) as ISpecification<StatusData>));

      return returnList;

    }
  }

내가 떨어지는 곳은 일단 상태 객체에 의해 만족되는 사양을 발견 한 후에, 그 사양을 istatusupdate를 구현하는 유형에 어떻게 매핑 하는가.

누군가가 IstatusUpdate 구현 자에게 사양 매핑이 필요하다고 제안했습니다. 이 매핑은 공장의 책임 인 것 같습니다. 사양에서 매달려 SRP 위반과 같은 냄새가납니다. 나는 그 책임이있는 맵퍼 클래스를 만들 수 있지만 그다지 일반적이지 않은 것처럼 보이며 맵퍼를 사양에 매핑하는 방법에 대한 질문을 제기 할 수 있습니다.

여기에 아직 약간의 도약이 있습니다.

도움이 되었습니까?

해결책

그래서 우리는이 라인 세트에 정말로 집중하고 있다고 가정합니다.

if (spec.IsSatisfiedBy(item))
          return new NewStatusUpdate();

그리고 나는 당신 이이 현재 형태에서 이것이 어떻게 이루어질 수 있는지 묻는다고 가정합니다. 품목이 지원해야 할 것 같습니다

interface ISpecSupport<T>
{
    bool ItemSpecsContain(ISpecification<T> spec);
}

그런 다음 Spec.IsatisfiedBy 메소드는이 인터페이스 유형을 사용하여 메소드를 실행할 수 있습니다.

다시 말해, 나는 객체가 그것이 무엇인지 (사양의 관점에서) 어떤 종류의 설명을 가지고 있어야한다고 말합니다. 나는 그것이 일종의 목록이라고 생각하지만 확실하지 않습니다. 나는 당신이 아마 이것에 대해 생각했을 것이라고 확신합니다. 그래서 당신이 도움이 될만한 것을 추가 할 수 있다면.

또한 위의 대신 아마도 다시 정렬 할 수 있습니다.

if (item.Satisfies(spec))
    return new NewStatusUpdate();

그런 다음 이런 식으로 당신은 많은 악성 방문자 패턴을 사용할 필요가 없습니다 (나는 이것이 내가 이것 전에 묘사 한 것이라고 생각합니다). 항목이 사양을 소유하는 것처럼 보이기 때문에 더 직접적입니다.이 방법으로 항목이 사양을 충족하는지 결정할 수 있습니다.

이 논리가 객체 안에 고정되어 싶지 않다면 (내가 이해할 것), 어떤 종류의 속성 가방을 사용하고 있다면 (또는 반사가 있거나 멋지게) 독립적 인 사양으로 객체의 세부 사항을 파헤칠 수 있습니다. 유효성 검사기. 실제로 독립적 인 유효성 검사기는 처음부터 나쁜 생각이 아닐 수도 있습니다. 사양이 항목과 일치하는지 알 수있는 능력이 개별 사양과 함께 유지되어야하는 책임이라는 것을 확실하지 않습니다.

다른 팁

내가 올바르게 이해 한 경우, istatusupdate를 구현하는 객체를 원하십니까?

샘플에서 이러한 유형 중 어느 것도 정의되지 않으므로 사용할 수있는 관계가 있는지 모르겠습니다.

그러나 코드를 보유하려면 약간의 공장이 필요하거나 객체 작성을 수행하기 위해 ispecification.getupdate ()가 필요할 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top