구현하기 전에 인터페이스 API를 작성해야합니까?


14

최근에보다 "조직화 된"프로그래밍에 대해 연구하고 있으며 구현이 아닌 인터페이스로 프로그래밍해야한다는 것을 배웠습니다. 이를 염두에두고, 가능한 경우 구현을 작성하기 전에 인터페이스에서 프로젝트를 "스케치"하는 것이 더 좋을까요?

이 경우 타사 라이브러리 (예 : Lidgren)를 사용하는 경우 인터페이스로 랩핑하고 IOC 컨테이너를 통해 해결해야합니까? 아니면 인터페이스에 노출해도됩니까?


개인적인 경험에서-건축을 먼저 디자인하는 것이 좋습니다-각 수업의 책임. 당신은 그것을 적을 필요가 없습니다, 그냥 생각하거나 종이에 스케치하십시오. 그런 다음 개인적인 취향에 관한 것이지만 구현하기 시작하는 모든 방법에 대해 먼저 문서 주석을 작성하는 것이 좋습니다. 문서를 작성하면 실제로 코드 작성을 시작하기 전에 기능에 대해 생각하게됩니다.
Sulthan

예, 인터페이스를 구현하기 전에 인터페이스 (또는 해당 문제에 대한 추상 클래스)로 프로그래밍하십시오. 그것은 구현에서 혼란 (및 투자)하기 전에 클라이언트에서 서버로 또는 그 반대로 "올바른"메시지 흐름을 얻는 데 도움이됩니다. 이 문제에 아주 좋은 슬라이드 쇼 : 어떻게 좋은 API를 디자인하는 & 왜 사항
마르 얀 Venema의를

답변:


8

불행히도, 이것은 종종 개인 취향으로 요약됩니다.

그러나 지금까지 설명한 내용이 좋습니다. 실제로 원하는 경우 다음 방법을 사용할 수 있습니다.

  1. 애플리케이션 스켈레톤을 인터페이스, 추상 클래스 (스텁) 및 클래스 (또한 스텁)로 작성하십시오.
  2. 해당 인터페이스 및 스텁에 대해 테스트를 작성하십시오 (현재는 실패합니다).
  3. 구현을 작성하십시오 (구현이 끝나면 테스트가 통과하기 시작합니다)

보다 "조직화 된"코드를 작성하는 데 집중하고 있습니다. TDD를 따르는 것이 도움이 될 것입니다.

몇 가지 추가 사항 :

  • IoC 컨테이너가 편리합니다. 그들과 DI를 최대한 많이 사용하십시오.
  • 제 3의 라이브러리를 래핑. 이렇게하면 코드 (제어하는 코드)와 타사 코드 (제어하지 않는 코드) 사이의 연결이 느슨해집니다.

1
이것이 내가 원래 생각한 것이었지만 YAGNI 원칙을 위반한다고 들었습니다. 내가 끝내지 못한 많은 프로젝트에서 내가 발견하는 문제는 내가 작성한 블로 브 코드의 양으로 프로젝트를 신속하게 유지할 수 없다는 것입니다.
Dan Pantry

어느 부분이 YAGNI를 위반합니까?
MetaFight

타사 라이브러리 래핑.
Dan Pantry

2
제 3 자 라이브러리의 가능성은 무엇입니까? 이 확률이 0 %라면 반드시 YAGNI입니다. 그러나 거의 그렇지 않습니다. 또한, 귀하의 제 3 자 libs와 포장은 할 수있다 (예를 들어, 제 3 자 라이브러리를 조롱 수없는, 경우) 단위 테스트에 다른 코드를보다 쉽게
MetaFight

1
@DanPantry : 타사 라이브러리를 래핑하는 것은 YAGNI 위반이 아니지만 "타사 라이브러리가 자신의 코드에 침입"하는 것을 방지해야합니다. MetaFight는 라이브러리를 교체 할 수있을뿐만 아니라 최신 버전의 라이브러리 변경에 대한 방어책을 제시하므로 자체 코드 전체에서 변경이 필요합니다. 라이브러리 (특히 특정 유형 : 클래스, 열거 형, 구조체 등)를 줄임으로써 자신의 코드를 격리하고 라이브러리가 변경 될 때 (어떤 이유로 든) 변경할 단일 지점을 갖습니다.
Marjan Venema

13

그렇습니다. 알려진 구현이 아닌 인터페이스에 대해 코딩해야하며, 자신의 코드에서 인터페이스를 생성하지 않고 먼저 인터페이스를 구성해야합니다.

두 가지 권장 사항의 이유는 대체로 동일합니다. 컴퓨터 프로그래밍은 주로 인적 요소에 관한 것입니다. 많은 사람들이이 놀라운 사실을 알고 있지만 다음과 같은 점을 고려하십시오. 동일하게 작동하는 동일한 컴퓨팅 문제를 해결하는 방법은 거의 무한합니다. 거의 모든 사람들은 글을 쓰지 않은 사람 (또는 사실 저자에게 잠시 후)을 이해하는 것이 완전히 불가능합니다.

좋은 소프트웨어 엔지니어링은 소스 코드를 나중에 작업 할 수있는 방식으로 원하는 효과 (적절한 효율로 올바른 계산)를 얻는 방법에 관한 것입니다. 인터페이스와 API는 해당 분야의 중요한 부분입니다. 한 번에 한 수준의 설명으로 문제에 대해 생각할 수 있습니다. 이는 비즈니스 일관성 규칙 링크 된 목록 구현에 대해 생각하는 것보다 훨씬 쉬우 므로 클라이언트 프로그래머가 원하는 방식으로 코드를 사용하도록 허용하는 것보다 이러한 분리를 강제로 적용하는 것이 좋습니다 .

이것은 그들이 쓰는 모든 것을 이해하고 평범한 사상가보다 훨씬 뛰어나고 "더 적은"프로그래머에게 문제를 야기하는 모든 복잡성을 처리 할 수 ​​있다고 확신하는 많은 카우보이 프로그래머에게는 믿기 어렵습니다. 자신의인지 한계를 인식하지 못하는 것은 매우 흔한 현상입니다. 이것이 코드 구성의 모범 사례가 매우 중요하고 종종 무시되는 이유입니다.

반복하면 인터페이스와 API 장벽은 자신과 만 협력하는 경우에도 크게 좋습니다 . 외부 라이브러리의 경우 잘 생각한 API를 가져와도 라이브러리를 다른 라이브러리로 교체하지 않아도되는 한 API 사용에 아무런 문제가 없습니다. 그렇지 않으면 래퍼 또는 부패 방지 계층이 매우 좋습니다.


나는 SE가 나중에 소스 코드를 다루는 방식으로 원하는 효과를 얻는 것에 대해 당신의 요점을 좋아한다. 나는 항상 깨끗한 코드를 위해 싸우고있는 마지막 직장에서 잘 표현 할 수 있었으면 좋겠다!
MetaFight

어디서나 사용할 수있는 인터페이스 인 API에 대한 명명 규칙이 있습니까? 예를 들어, 명령 패턴을 수행하는 경우 "명령어"라고합니까?
스눕

@StevieV에 IBlah의해 구현 Blah되거나에 의해 구현되는 다양한 방법이 있습니다 . 나는 모두를 싫어하고 사용하는 경향 에 의해 구현 , 또는 . 그러나 평소와 같이 일반적인 표준보다 기존 코드 기반과 기대치를 따르는 것이 더 중요합니다. BlahBlahImplBlahOralBlahWrittenBlahASLBlah
Kilian Foth

4

인터페이스로 프로그래밍하는 것만으로도 TDD (Test Driven Development / Design)를 보지 않겠습니까?

많은 사람들이 TDD를 테스트 관행이라고 생각하지만 실제로 테스트를 통해 코드를 사용하는 방법 (초기 단위 테스트를 통하지 만 통합 테스트를 통할 수도 있음)을 테스트에 노출시키는 디자인 방식입니다.

인터페이스 프로그래밍은 툴셋에서 중요한 무기이지만 대부분의 경우처럼 항상 적절한 솔루션 / 기술 / 연습은 아닙니다. 필요한 인터페이스에 프로그래밍해야합니다.

TDD를 사용하면 그러한 인터페이스가 중요한 곳과 솔직히 중요하지 않은 곳을 탐색하게됩니다. 그리고 마지막에는 코드베이스에 걸쳐 꽤 좋은 단위 테스트 세트가 있어야합니다.

써드 파티 라이브러리를 사용하는 경우에는 적절한 경우 자신의 추상화로 랩핑하는 것이 좋습니다. 귀하의 API 클라이언트가 그들에 대해 "알도록"하지 마십시오

행운을 빕니다!

[편집 : megaflight의 답변을 보았습니다-완전히 동의합니다]


2
TDD는 공식적인 "인터페이스"선언이 아닐 수도 있지만 함축보다는 인터페이스 측면에서 암시 적으로 생각해야합니다.
DougM

1
이것은 좋은 대답입니다. 새 프로젝트에서 작업 할 때 시작 해야하는 OP의 실제 문제에 대한 해결책이라고 생각하는 TDD를 제안한 +1이며 , "TDD를 사용하면 그러한 인터페이스가있는 곳을 탐색하게됩니다. 중요하고 솔직히 중요하지 않은 곳입니다. "
Benjamin Hodgson

2

과잉이라고 생각합니다. API 사용자가 특정 방식으로 무언가를 구현 / 사용하도록 강요 할 필요가 없다면 나는 그것을 버릴 것입니다. 인터페이스는 계약입니다. 필요하지 않으면 왜 나에게 하나를 주시겠습니까?

사람들이 인터페이스를 과도하게 사용한다고 생각합니다. 대부분의 경우 필요하지 않은 복잡한 계층을 추가하고 있습니다.


내 생각에 사람들 인터페이스 사용하고 있다고 생각 합니다. 재사용 가능한 조각을 만들려면 인터페이스가 "좋아요"추가 될뿐만 아니라 처리해야 할 주요 요소입니다. 물론 실제 구현 외에.
JensG

1

계약에 대한 프로그래밍은 거의 항상 좋은 생각입니다. 그 계약은 인터페이스 일 필요는 없으며 대신 클래스에 의해 이행 될 수 있습니다. 내 의견으로는, 단위 테스트 문제와 모의 프레임 워크로 인해 인터페이스가 DI와 함께 다소 과용되었습니다.

개인적으로 계약을 한 번 이상 구현할 수 있거나 가질 가능성이있을 때만 인터페이스를 가져 오는 것을 선호합니다. 인터페이스는 데이터 액세스를 추상화하려는 리포지토리에는 유용하지만 상대적으로 융통성이없는 표준 비즈니스 로직에는 적합하지 않습니다.

인터페이스가 없으면 특히 순수 주의자에게 단위 테스트에 문제가 발생할 수 있습니다. 그러나 나는 내부 의존성이 아닌 내 프로그램의 외부 의존성을 조롱하는 데 관심이 있습니다. 테스트에서 코드 구조를 에코하지 않고 코드 유효성 검사를 수행하기를 원합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.