내가 작성한 모든 클래스가 인터페이스를 준수해야합니까?


10

저는 Typescript로 게임을 작성하고 있으며 " 인터페이스 기반 프로그래밍 " 이라는 아이디어를 고수하기로 결정했습니다 . 여기서는 인터페이스 대신 구현, 객체의 인터페이스를 기반으로 코드를 작성합니다.

나는 많은 수의 인터페이스와 인터페이스를 구현 한 클래스를 작성하고 한 걸음 물러서서 클래스가 단순하여 구현을 변경할 필요가 없을 정도로 간단하다는 것을 깨달았습니다. 수업은 ( Phaser.Sprite탱크처럼 행동하기 위해 제한된 방식으로 움직입니다).

그런 다음 몇 년 전에 YAGNI 의 아이디어에 대해 읽은 것을 기억합니다. YAGNI 는 기본적으로 사용하지 않을 수있는 것을 포함하도록 코드를 과도하게 엔지니어링해서는 안됩니다.

모범 사례에 따라 모든 클래스가 인터페이스를 구현해야합니까, 아니면 나중에 교체 될 것으로 예상되는 클래스로 제한해야합니까?


실제 클래스를 매개 변수로 사용하면 인터페이스 와이 클래스의 인터페이스로 코딩됩니다. 아무도 당신이 그 특정 클래스를 사용하도록 강요하지 않으며, 클래스를 상속하고 완전히 새로운 기능을 제공 할 수는 있지만 옳지 않은 것처럼 보입니다. 사람들이 아이디어를 쉽게 이해할 수 있도록 인터페이스가 존재합니다. 슬프지만, 실제로 모든 것을위한 인터페이스가 필요하지 않습니다.
Andy

답변:


6

인터페이스를 갖는 이유는 다형성을 단순화하기 때문입니다. 의미는 실제 구현을 알기보다는 계약별로 인스턴스를 보낼 수 있다는 의미입니다. 예를 들어, "Reader"를 메소드로 보내서 호출 된 메소드가 "read ()"메소드를 사용할 수 있도록합니다. "리더"인터페이스를 선언하면 지정된 메소드를 구현하여 모든 오브젝트가이 계약을 준수하도록 할 수 있습니다. 이런 식으로, 계약의 기본이되는 객체가 완전히 다를 수 있더라도 호출자는 특정 메소드가 존재한다고 가정 할 수 있습니다.

이것은 기본 클래스에서 다형성을 분리하고 계약을 암시하여 클래스 체인 경계 사이에서도 가능합니다.

자 ... 이것은 여러 상속 체인이 동일한 방식으로 작동해야하거나 다른 사용자에게 전달하려는 공통된 동작을 가진 많은 기본 클래스가있는 경우에만 유용합니다.

하나의 상속 체인 (baseclass-> subclass) 또는 base 만 가지고 있거나 실제로 관련 객체를 다른 사람에게 전달하거나 일반적으로 사용할 필요가 없다면 인터페이스 구현을 추가하지 않아도됩니다. 쓸모없는.


또한 인터페이스는 추상화를 모델링해야하므로 클래스의 모든 공개 멤버를 게양하여 만들지 마십시오. 해당 클래스가 무엇을 나타내는 지 생각하고 해당 유형의 모든 객체가 가져야하는 인터페이스에만 해당 항목을 넣습니다. 또한 여러 인터페이스 (예를 들면 만드는 바람 수 MovesShoots하나의 클래스에 대한 당신의 탱크 예를 들어).
TMN

7

실제로 인터페이스가 필요한지 확실하지 않으면 아마도 필요하지 않습니다. 이것이 YAGNI 원칙의 핵심입니다. 구현을 교체해야 할 때 인터페이스를 소개합니다.


6

모든 클래스에 대한 인터페이스를 만드는 것은 약간 과잉입니다. 순수한 객체 지향 관점에서 모든 클래스에는 이미 인터페이스가 있습니다. 인터페이스는 공용 메서드 및 클래스의 데이터 멤버에 지나지 않습니다.

일반적으로 "인터페이스"는 " interface키워드를 사용하여 정의 된 Java 클래스 "또는 "공용의 순수 가상 함수 만있는 C ++ 클래스 "를 의미 합니다. 이들은 클래스의 인터페이스를 구현에서 분리하기 때문에 유용한 추상화입니다.

이를 염두에두고 적절한 경우 인터페이스를 사용하십시오.

  • 인터페이스에 여러 가지 구현이 있습니까? 그렇다면,이 상황 일반적인 공용 방법을 인터페이스로 추출하는 후보 있습니다.

  • 내 모듈의 내부 작동을 알지 못하는 다른 모듈에 대한 잠재적 인 인터페이스 구현을 전달합니까? 인터페이스는 모듈 간 터치 포인트의 크기를 줄이기 때문에 유용 할 수 있습니다.

위의 족제비 단어를 주목하십시오. 주어진 상황에 대해 "예"또는 "아니오"라고 말하는 단단하고 빠른 규칙은 없습니다.

그러나 모든 것에 대한 인터페이스를 갖는 것은 과잉 일 가능성이 높습니다. 이 패턴이 보이면 멀리 갈 것입니다.

interface I {
  int getA()
  int getB()
  ...
  int getY()
  int getZ()
}

class C : I {
  int getA() { ... }
  int getB() { ... }
  ...
  int getY() { ... }
  int getZ() { ... }
}

인터페이스의 또 다른 이유는 테스트 시스템이 필요한 경우 언어 및 테스트 프레임 워크에 따라 달라질 수 있기 때문입니다. 희망 당신은 하지 않습니다 물론,이 작업을 수행해야합니다.
Darien

@Darien : 테스트 시스템이 인터페이스를 요구할 수있는 이유는 테스트가 실제로 다른 (모의 된) 구현을 사용하고 있기 때문에 인터페이스가 적절한시기의 첫 번째 글 머리 기호로 돌아 가기 때문입니다.
Bart van Ingen Schenau

여기 좋은 것들이 있습니다. 단지 이것을 숙고하십시오 : 인터페이스는 대중을 향한 메소드와 클래스의 데이터 멤버에 지나지 않습니다 . 이것이 인터페이스 구현 에서는 사실이지만, 결코 구현되지 않은 인터페이스 에서는 확실하게 유지되지는 않습니다. 물론 이것은 코드 냄새 일 수 있습니다.
로비 디

@RobbieDee 그것은 Java interface와 같은 것이 사실입니다. Java의 모든 것이 interface공용 인터페이스 (OO 개념)이기도합니다.

여러분! 답의 두 번째 & 세 번째 문장을 적어 두십시오. 라미네이트합니다. 지갑에 넣으십시오. 자주 참조하십시오.
radarbob 2016 년

5

신입 개발자는 인터페이스가 "모범 사례"라고 들었 기 때문에 단순히 추가하는 불편 함으로 생각하는 것은 매우 유혹적 일 수 있습니다. 당신이하면 된다 맹목적으로이 일을,이 난다 화물 숭배 프로그래밍 .

일련의 클래스를 함께 묶지 않고 더 큰 개발을위한 인터페이스를 고려해야하는 여러 가지 이유가 있습니다.

조롱 프레임 워크

다양한 레이어에 대한 객체를 만들지 않고 멀티 레이어 응용 프로그램을 테스트하려면 의심 할 여지없이 모의 프레임 워크를 사용하여 레이어를 조롱해야합니다. 인터페이스는 여기서 광범위하게 사용됩니다.

의존성 주입

그들이 부풀려서 다소 호의적이지 못했지만, 아이디어는 건전합니다. 인터페이스를 기반으로 간단히 콘크리트로 바꿀 수있는 능력입니다. 원리는 팩토리 패턴과 같은 많은 디자인 패턴에서도 찾을 수 있습니다.


이러한 접근은에 요약되어있다 D 에서 SOLID 원칙 . 이것의 문지름은 콘크리트가 아닌 추상화를 사용하는 것입니다.

디자인 패턴 자체와 마찬가지로 언제 사용해야하는지 판단해야합니다. 테이크 아웃 포인트는 인터페이스가 클래스에 붙어있는 것이 아니라 인터페이스가 유용한 방법을 이해하는 것입니다. 여기 DIP와 YAGNI의 다양한 장점에 대한 좋은 토론이 있습니다 .


의존성 주입과 IoC 컨테이너는 완전히 다른 두 가지입니다 (하나는 디자인 원칙이고 다른 하나는 다양한 프레임 워크를 사용하여 해당 원칙을 구체적으로 적용하는 한 가지 방법입니다). IoC 컨테이너를 사용하지 않고 DI를 사용할 수 있습니다.
sara

@kai "IoC 컨테이너를 사용하지 않고 DI를 사용할 수 있습니다" . 더 성숙한 개발 상점은 할 수 있다고 생각합니다. 단순한 개념 인 코드를 오염시킬 필요는 없습니다. 요엘 도 비슷한 견해를 가지고 있습니다.
로비 디

YAGNI는 매우 까다 롭습니다. 대부분의 경우 철학이 무엇이든 YAGNI는 모서리를 자르는 변명으로 사용됩니다. 더 심각하게 결합을 피하십시오. 많은 스크럼 회의에서 보는 것이 실망 스럽습니다. 다른 사람이 작업을 마치지 않아 개발자가 자신을 차단했다고합니다. 다른 개발자를 차단하면 어떻게 시간을 절약 할 수 있습니까? 내 제안은 연결을 피하기 위해 인터페이스를 사용하는 것입니다. 물론 Model 클래스를위한 인터페이스를 사용할 필요는 없습니다.
Ripal Barot 2018 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.