상속과 구성이 아닌 특성을 언제 사용해야합니까?


9

OOP와 관련하여 재사용 성을 구현하는 세 가지 일반적인 방법 인 AFAIK가 있습니다.

  1. 상속 : 보통 is-a 관계를 나타내는 것 (오리 is-a 조류)
  2. 구성 : 일반적으로 Has-A 관계 (자동차 Has-A 엔진)를 나타냅니다.
  3. 특성 (예 : PHP의 특성 키워드) : ... 실제로 확실하지 않음

특성이 has-a와 is-a 관계를 모두 구현할 수 있다고 생각하지만, 어떤 모델링이 의도되었는지는 확실하지 않습니다. 특성은 어떤 상황에 맞게 설계 되었습니까?


특성에 대해 조금 더 설명 할 수 있지만 특성은 작곡의 또 다른 단어 일 수 있습니까?
Trilarion


1
왜 그런지 정말로 알고 싶습니다. 한 번도 사용하지 않았습니다.
Andy

답변:


6

특성은 작곡을 수행하는 또 다른 방법입니다. 컴파일 타임 (또는 JIT 컴파일 타임)에 클래스의 모든 파트를 작성하고 필요한 파트의 구체적인 구현을 구성하는 방법으로 생각하십시오.

기본적으로 다양한 기능 조합으로 클래스를 만들 때 특성을 사용하려고합니다. 이 상황은 다른 사람들이 사용할 수있는 유연한 라이브러리를 작성하는 사람들에게 가장 자주 나타납니다. 예를 들어, 최근에 ScalaTest를 사용하여 작성한 단위 테스트 클래스의 선언은 다음과 같습니다.

class TestMyClass
  extends WordSpecLike
  with Matchers
  with MyCustomTrait
  with BeforeAndAfterAll
  with BeforeAndAfterEach
  with ScalaFutures

단위 테스트 프레임 워크는이 t 다른 구성 옵션을, 모든 팀은 일을하는 방법에 대해 다른 설정을 가지고있다. withScalaTest는 (Scala 에서 사용 되는 혼합 된) 특성을 옵션에 넣음으로써 와 같은 클래스 이름을 만들 WordSpecLikeWithMatchersAndFutures거나 와 같은 런타임 부울 플래그 를 만들지 않고도 모든 옵션을 제공 할 수 있습니다 WordSpecLike(enableFutures, enableMatchers, ...). 이를 통해 Open / Closed 원칙을 쉽게 따를 수 있습니다 . 단순히 새로운 특성을 추가하여 새로운 기능과 새로운 기능 조합을 추가 할 수 있습니다. 또한 일반적으로 필요하지 않은 기능을 특성에 쉽게 넣을 수 있기 때문에 인터페이스 분리 원칙을 쉽게 따르기 쉽습니다 .

특성은 상속 계층 구조를 공유하는 것이 타당하지 않은 여러 클래스에 공통 코드를 넣는 좋은 방법입니다. 상속은 매우 밀접하게 연결된 관계이므로 도움이 될 수 있다면 그 비용을 지불하지 않아야합니다. 특성은 훨씬 더 느슨하게 결합 된 관계입니다. 위의 예에서, 나는 MyCustomTrait관련이없는 여러 테스트 클래스간에 모의 데이터베이스 구현을 쉽게 공유하는 데 사용 했습니다.

의존성 주입은 많은 동일한 목표를 달성하지만 프로그래머 입력에 기반한 컴파일 타임 대신 사용자 입력에 기반한 런타임에 달성됩니다. 특성은 의미 상 동일한 클래스의 일부인 종속성을위한 것입니다. 당신은 다른 책임을 가지고 다른 클래스를 불러 내지 않고 한 클래스의 일부를 모으는 것입니다.

의존성 주입 프레임 워크 는 프로그래머 입력을 기반으로 컴파일 타임에 많은 동일한 목표를 달성하지만, 적절한 특성 지원이없는 프로그래밍 언어에 대한 해결 방법입니다. 특성은 이러한 종속성을 컴파일러 유형 검사기의 영역으로 가져옵니다. 구문이 더 깔끔하고 빌드 프로세스가 단순하여 컴파일 시간과 런타임 종속성을보다 명확하게 구분할 수 있습니다.


안녕하세요, 좋은 답변입니다. 특성 사용시기와 의존성 주입시기를 결정하는 방법을 물어볼 수 있습니다. 같은 것을 달성하는 것 같습니다.
Extrakun

당당한 관찰. 내 편집을 참조하십시오.
Karl Bielefeldt

작성해 주셔서 감사합니다. 작곡 @KarlBielefeldt와 같은 특성에 대한 귀하의 답변이 궁금합니다. 당신의 클래스는 그 특성이 필요한 곳이라면 어디에서나 사용할 수 있으며, 여전히 일반적인 인터페이스와 같은 취약성으로 고통받을 것입니다. 서브 타입과 상속에 더 가까운 것 같습니다. 나는 그것이 DI와 어떻게 비슷한 지 잘 모르겠습니다 ... 특성을 확장하도록 정의 된 다양한 클래스가있는 경우 클래스의 최상위 / 진입 점이 아닌 계층 구조에서 클래스가 정의 된 곳마다 구체적인 종속성이 정의되지 않습니다 암호? 감사!
allstar

특색이 있습니다 자신의 상속 속성, 단지 인터페이스처럼 사용하지만 그들을 특별하게 만드는 게 아니에요된다. with연산자를 차별화하고, 무엇 with조성 작업입니다. 그렇습니다. 특성은 코드의 진입 점에서 정의 할 필요없이 DI를 대체합니다. 그것이 제 의견으로는 그들을 선호하게 만드는 것 중 하나입니다.
Karl Bielefeldt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.