매우 유비쿼터스하고 찾기가 쉽기 때문에 조롱 프레임 워크를 찾고 있지 않다고 가정하면 미리 주목할만한 몇 가지 사항이 있습니다.
- "항상"해야 할 일은 "아무것도"없습니다.
항상 타사 라이브러리를 마무리하는 것이 가장 좋은 것은 아닙니다. 응용 프로그램이 본질적으로 라이브러리에 의존적이거나 문자 그대로 하나 또는 두 개의 핵심 라이브러리를 기반으로 구축 된 경우 시간을 낭비하지 마십시오. 라이브러리가 변경되면 응용 프로그램을 변경해야 합니다.
- 통합 테스트를 사용해도됩니다.
이는 응용 프로그램에 내재되어 있거나 내재되어 있거나 쉽게 조롱 할 수없는 경계에서 특히 그렇습니다. 이러한 조건이 충족되면 포장 및 조롱 이 복잡하고 지루합니다. 이 경우 두 가지를 피할 수 있습니다. 포장하지 말고 조롱하지 마십시오. 통합 테스트 만 작성하십시오. (자동 테스트가 목표 인 경우)
- 도구와 프레임 워크는 논리적 복잡성을 제거 할 수 없습니다.
원칙적으로 공구는 상용구 만 줄일 수 있습니다. 그러나 복잡한 인터페이스를 가져 와서 간단하게 만드는 자동화 가능한 알고리즘은 없습니다. 인터페이스 X를 가져와 사용자의 요구 에 맞게 조정하는 것은 물론 입니다. (당신은 그 알고리즘 을 알고 있습니다 !) 따라서, 얇은 래퍼를 생성 할 수있는 도구는 의심 할 여지 가 없지만, 결국에는 여전히 지능적으로 코딩해야하기 때문에 수동으로 랩퍼 뒤에 숨겨져 있어도 인터페이스에 대해
즉, 수업을 직접 언급하지 않기 위해 여러 언어로 사용할 수 있는 전술 이 있습니다. 경우에 따라 실제로 존재하지 않는 인터페이스 또는 씬 래퍼를 "숨길"수 있습니다. 예를 들어 C #에서는 다음 두 경로 중 하나를 사용합니다.
- 팩토리 및 암시 적 타이핑을 사용하십시오 .
이 작은 콤보로 복잡한 클래스를 완전히 감싸는 노력을 피할 수 있습니다.
// "factory"
class PdfDocumentFactory {
public static ExternalPDFLibraryDocument Build() {
return new ExternalPDFLibraryDocument();
}
}
// code that uses the factory.
class CoreBusinessEntity {
public void DoImportantThings() {
var doc = PdfDocumentFactory.Build();
// ... i have no idea what your lib does, so, I'm making stuff but.
// but, you can do whatever you want here without explicitly
// referring to the library's actual types.
doc.addHeader("Wee");
doc.getAllText().makeBiggerBy(4).makeBold().makeItalic();
return doc.exportBinaryStreamOrSomething();
}
}
보다 "기능적인"접근 방식을 통해 또는 사전 (또는 무엇이든 ) 에 저장하여 이러한 객체를 멤버로 저장하는 것을 피할 수있는 경우이 접근 방식은 핵심 비즈니스 엔터티가 정확히 알 필요없이 컴파일 타임 유형 검사의 이점을 갖습니다. 그들이 어떤 수업을하고 있는지
컴파일 타임에 팩토리가 리턴 한 클래스에는 실제로 비즈니스 오브젝트가 사용하는 메소드가 있어야합니다.
- 동적 입력을 사용하십시오 .
이것은 암시 적 타이핑 을 사용하는 것과 같은 맥락 이지만 또 다른 트레이드 오프가 필요합니다. 컴파일 형식 검사를 잃고 익명으로 외부 종속성을 클래스 멤버로 추가하고 종속성을 주입 하는 기능을 얻을 수 있습니다.
class CoreBusinessEntity {
dynamic Doc;
public void InjectDoc(dynamic Doc) {
Doc = doc;
}
public void DoImortantThings() {
Doc.addHeader("Wee");
Doc.getAllText().makeBiggerBy(4).makeBold().makeItalic();
return Doc.exportBinaryStreamOrSomething();
}
}
ExternalPDFLibraryDocument
앞서 언급 했듯이이 두 가지 전술을 모두 사용하여 조롱 할 때가되면해야 할 일이 있지만 어쨌든 해야 할 일 입니다 . 그리고이 구성으로 100 개의 얇은 작은 래퍼 클래스를 정의하는 것을 피할 수있었습니다. 라이브러리를 직접 보지 않고 단순히 대부분을 사용 했습니다 .
이 모든 것을 말하면서, 여전히 타사 라이브러리를 명시 적으로 래핑하는 것을 고려할 세 가지 큰 이유가 있습니다.
- 특정 라이브러리는 응용 프로그램에 고유 하지 않습니다 .
- 그것을 감싸지 않고 교환하는 것은 매우 비쌉니다.
- API 자체가 마음에 들지 않습니다.
내가 그 지역의 세에서 어느 정도의 우려가없는 경우에는 하지 않는 어떤 만드는 중요한 을 마무리하기 위해 노력합니다. 그리고 세 가지 영역 모두에 관심이 있다면 자동 생성 된 얇은 래퍼는 실제로 도움이되지 않습니다.
라이브러리를 마무리하기로 결정했다면 가장 효율적이고 효과적인 시간 사용은 원하는 인터페이스에 대해 애플리케이션 을 빌드하는 것입니다 . 기존 API에 반대하지 않습니다.
다른 방법으로, 고전적인 조언에 유의하십시오 . 가능한 모든 결정을 연기하십시오. 먼저 응용 프로그램의 "핵심"을 작성하십시오. 것이다 인터페이스에 대한 코드 결국 것이다 당신이 원하는 것을, 결국 아직 존재하지 않는 "주변 물건"에 의해 성취 될 수있다. 필요에 따라 간격을 메우십시오.
이러한 노력은 시간을 절약하는 것처럼 느껴 지지 않을 수 있습니다 . 그러나 랩퍼가 필요하다고 생각되면 이것이 가장 효율적인 방법 입니다.
이런 식으로 생각하십시오.
이 라이브러리에 대해 코드의 어두운 구석에서 코드를 작성해야 합니다. 테스트하는 동안 라이브러리를 조롱하면 포장이 끝난 경우라도 피할 수없는 수동 작업이 필요 합니다. 그렇다고 해서 대부분의 응용 프로그램에서 해당 라이브러리 를 이름 으로 직접 인식해야한다는 의미는 아닙니다 .
TLDR
라이브러리를 래핑 할 가치가있는 경우, 타사 라이브러리에 대한 광범위한 직접 참조를 피하기 위해 전술 을 사용 하지만 얇은 래퍼를 생성하기위한 바로 가기는 사용하지 마십시오. 비즈니스 로직을 먼저 구축하고, 인터페이스를 신중히 고려한 다음 필요에 따라 유기적으로 어댑터를 등장 시키십시오 .
또한 통합 테스트를 두려워하지 마십시오. 그것들은 약간 어지럽지만 여전히 작동 코드의 증거를 제공하며 회귀를 막기 위해 쉽게 만들 수 있습니다.