2009-03-31 4 views
8

나는 coolade를 마시고 있고 그것을 좋아하고있다 - 인터페이스, IoC, DI, TDD 등. 꽤 잘 작업 중이다. 하지만 나는 내가 만드는 경향과 싸워야한다는 것을 알고 있습니다. 모든 것 인터페이스! 나는 인터페이스 인 공장을 가지고있다. 이 메소드는 인터페이스가 될 수있는 객체를 반환합니다 (테스트를 더 쉽게 만들 수 있습니다). 이러한 객체는 필요한 서비스에 대한 DI' 인터페이스입니다. 내가 찾는 것은 인터페이스를 구현과 동기화하여 유지하는 것이 작업에 추가된다는 것입니다. 즉, 클래스에 메소드를 추가한다는 것은 클래스 + 인터페이스, 모의 등을 추가하는 것을 의미합니다.Interface Insanity

인터페이스를 고려하고 있습니까? 너무 일찍? 무엇이 인터페이스와 객체를 반환해야 하는지를 아는 가장 좋은 방법이 있습니까?

+0

이제 모두들 ... 컴퓨터를 전환하고 서로의 코드를 읽으십시오! –

답변

7

인터페이스는 객체와 공동 작업자 중 하나 사이에서 상호 작용을 조롱하고 싶을 때 유용합니다.그러나 내부 상태가있는 객체의 인터페이스에는 값이 적습니다.

예를 들어, 어떤 도메인 객체를 추출하기 위해 저장소와 대화하는 서비스가 있다고 가정 해 봅니다.

저장소에서 인터페이스를 추출 할 때 명확한 설계 값이 있습니다. 저장소의 구체적인 구현은 NHibernate 또는 ActiveRecord와 강하게 연결될 수 있습니다. 내 서비스를 인터페이스에 연결함으로써 구현 세부 사항을 명확하게 구분할 수 있습니다. 그것은 너무 일 어서 내 서비스를위한 초고속 독립형 유닛 테스트를 작성할 수있게되었습니다. 이제는 모의 IRepository를 넘겨 줄 수 있습니다.

리포지토리에서 돌아 왔고 내 서비스가 작동하는 도메인 개체를 고려할 때 값이 적습니다. 내 서비스 테스트를 작성할 때 실제 도메인 객체를 사용하고 상태를 확인하려고합니다. 예 : service.AddSomething() 호출 후 뭔가가 도메인 객체에 추가되었는지 확인하려고합니다. 도메인 객체의 상태를 간단히 검사하여이를 테스트 할 수 있습니다. 격리 된 상태에서 도메인 객체를 테스트 할 때 객체에 대한 작업을 수행하고 내부 상태를 퀴즈로 처리하기 때문에 인터페이스가 필요하지 않습니다. 예 : 잠든다면 내 양들이 풀을 먹는 것이 맞습니까?

첫 번째 경우 상호 작용 기반 테스트에 관심이 있습니다. 테스트중인 객체와 공동 작업자 사이에 전달되는 호출을 모의 객체로 가로 채기를 원하므로 인터페이스가 도움이됩니다. 두 번째 경우에는 상태 기반 테스트에 관심이 있습니다. 인터페이스는 여기서 도움이되지 않습니다. 상태 또는 상호 작용을 테스트하고 있는지 여부를 의식하여 인터페이스 또는 인터페이스 결정에 영향을 미치는지 확인하십시오.

(Resharper가 설치되어 있다면) 나중에 인터페이스를 추출하는 것이 매우 저렴하다는 것을 기억하십시오. 인터페이스를 삭제하고 결국 더 간단한 클래스 계층 구조로 돌아가려면 값이 싸다. 결국 인터페이스가 필요 없다고 결정하면된다. 내 충고는 인터페이스없이 시작하고 상호 작용을 조롱하고 싶을 때 필요할 때 추출하는 것입니다.

그림에 IoC를 가져 오면 더 많은 인터페이스를 추출하는 경향이 있습니다. 그러나 IoC 컨테이너에 몇 개의 클래스를 추가했는지에 대한 뚜껑을 유지하려고합니다. 일반적으로 이러한 제한된 주로 상태 비 저장 서비스 객체를 유지하려고합니다.

6

BDUF과 조금 비슷합니다.

냉각 장치로 쉽게 잡고 자연스럽게 흘려 보내십시오.

5

나는 "서비스"에 대한 인터페이스를 원한다는 것을 알지만, 주로 "데이터"에 관한 유형은 구체적인 클래스가 될 수 있습니다. 예를 들어 Authenticator 인터페이스가 있지만 Contact 클래스가 있습니다. 물론, 항상 명확한 것은 아니지만, 초기 경험 법칙입니다. 그래도 난 당신의 고통을 느끼게 할

- 그것은 조금 .H 및 .c 인 파일의 어두운 일에 돌아 가지처럼 ...

0

인터페이스 계약을 설립의 목적이 특히 유용 할 때를 즉시 작업을 수행하는 클래스를 변경하려고합니다. 클래스를 변경할 필요가 없으면 인터페이스가 방해가 될 수 있습니다.

인터페이스를 추출하는 자동 도구가 있으므로 나중에 프로세스에서 인터페이스 추출을 지연시키는 것이 좋습니다.

-1

먼저 인터페이스를 만들지 마십시오. 필요하지 않습니다. 어떤 클래스에 대한 인터페이스가 필요한지 추측 할 수 없습니다. 그러므로 쓸모없는 인터페이스로 코드를 부담시킬 시간을 낭비하지 마십시오.

그러나 리팩토링 단계에서 인터페이스의 필요성을 알게되면 그렇게 할 수 있습니다.

Those answers도 도움이됩니다.

+1

-1 디자인은 항상 인터페이스로 시작해야합니다. –

6

유연성은 가치있는 목표이지만 IOC 및 DI (어느 정도 TDD의 요구 사항 임)에 유연성이 추가되어 복잡성이 증가한다는 것을 기억하십시오. 유연성의 유일한 포인트는 다운 스트림을 더 빨리, 더 저렴하게 또는 더 나은 방향으로 변경하는 것입니다. 각 IoC/DI 포인트는 복잡성을 증가 시키므로 다른 곳에서 변경을 더 어렵게 만듭니다.

실제로 이것은 큰 디자인 업 프론트 일부 범위가 필요합니다. 변경 될 가능성이 가장 큰 영역을 식별하고 (또는 광범위한 단위 테스트가 필요함) 유연성을 고려하십시오. 변경 가능성이 희박한 유연성을 제거하기 위해 리팩터링하십시오.

이제 어떤 종류의 정확성으로 유연성이 필요한지 추측 할 수는 없습니다. 넌 틀릴거야. 그러나 당신이 옳은 것을 얻을 수있을 것 같습니다. 나중에 유연성이 필요하지 않다는 것을 알게되면 유지 보수시 고려할 수 있습니다. 필요한 곳에 기능을 추가 할 때 고려할 수 있습니다.

이제 변경 될 수도 있고 변경되지 않을 수도있는 영역은 비즈니스 문제 및 IT 환경에 따라 다릅니다. 다음은 몇 가지 반복되는 영역입니다.

  1. 난 항상 당신이 매우 변경할 수 다른 시스템에 통합 외부 인터페이스를 생각 하는데요.
  2. 에 백엔드를 제공하는 코드가 무엇이든간에 사용자 인터페이스는 UI의 변경을 지원해야합니다. 그러나 기능 변경 계획을 우선적으로 고려하십시오. 스마트 클라이언트와 웹 응용 프로그램을 모두 지원하는 등 다양한 UI 기술을 사용하지 말고 사용 계획을 너무 많이 달리하십시오. 다른 데이터베이스 및 플랫폼에 휴대 코딩 한편
  3. 는, 적어도 기업 환경에서 시간 낭비 보통 입니다. 주위를 물어보고 대체 할 계획이 있는지 확인하거나 소프트웨어의 내에서 업그레이드 기술을 확인하십시오. 데이터 내용과 형식에
  4. 변경 까다로운 사업입니다 데이터가 가끔 이렇게 가난하게, 대부분의 설계 내가 본 핸들 이러한 변화를 변경됩니다 동안 콘크리트 엔티티 클래스를 직접 사용 얻을.

하지만 변경할 수 있거나 변경해서는 안되는 점에 대해서만 판단 할 수 있습니다.

2

가장 중요한 "민첩한"원칙은 YAGNI ("너는 필요 없다")라고 생각합니다. 다시 말하면, 실제로 필요하기 전까지는 여분의 코드를 작성하지 마십시오. 미리 작성하면 요구 사항과 제약 조건이 변경되었을 수 있습니다.

인터페이스, 종속성 삽입 등 -이 모든 것들이 코드를 복잡하게하여 이해하고 변경하기가 더 어렵습니다. 나의 엄지 손가락 규칙은 물건을 가능한 한 간단하게 유지하면서 (단순하지는 않음) 부과하는 부담을 상쇄하기에 충분하지 않으면 복잡성을 추가하지 않는 것입니다.

실제로 테스트 중이며 mock 객체를 사용하면 모의 클래스와 실제 클래스가 구현하는 인터페이스를 매우 유용하게 사용할 수 있습니다. 그러나 어떤 시점에서 유용 할 수 있다는 전제하에 가상의 근거에 인터페이스를 만들거나 "올바른"객체 지향 설계가 아닌 인터페이스를 만들지 마십시오.

+0

"이 모든 것들이 코드에 복잡성을 더해 이해하고 변경하기가 더 어렵습니다"라는 말을 자세히 설명하십시오. 그것은 당신의 대답에 핵심이지만, * 왜 * 진실한 이유는 없습니다. –

0

당신이 제공하는 것에 매우 달려 있습니다 ... 내부 사물에 종사하고 있다면 "필요할 때까지하지 마십시오"라는 충고가 합리적입니다. 그러나 다른 개발자가 사용하는 API를 만든다면 나중에 인터페이스로 변경하는 것이 성가시다.

좋은 경험 법칙은 서브 클래스가 필요한 인터페이스를 만드는 것입니다. 이것은 "항상 그런 경우 인터페이스를 만드는"것이 아닙니다. 당신은 여전히 ​​그것에 대해 생각할 필요가 있습니다.

따라서 짧은 대답은 (내부적 인 것들과 API를 제공하는 둘 다 작동합니다.) 하나 이상의 구현이 필요할 것으로 예상되면 인터페이스로 만드십시오.

인터페이스가 아닌 인터페이스는 x 및 y를 처리하는 Location 클래스와 같이 데이터 만 보유하는 클래스입니다. 그 또 하나의 구현이 희박한 것은 희박합니다.