Program Tip

스칼라의 믹스 인 vs 컴포지션

programtip 2020. 10. 17. 12:05
반응형

스칼라의 믹스 인 vs 컴포지션


자바 세계에서 (더 정확하게는 다중 상속 / 혼합이없는 경우) 경험 법칙은 매우 간단합니다. "클래스 상속보다 객체 구성을 선호"합니다.

믹스 인, 특히 스칼라도 고려한다면 어떻게 변경되는지 알고 싶습니다.
믹스 인은 다중 상속 또는 더 많은 클래스 구성의 방법으로 간주됩니까?
"수업 구성보다 객체 구성 선호"(또는 그 반대) 지침도 있습니까?

나는 사람들이 믹스 인을 사용 (혹은 남용) 할 때 많은 예를 보았는데, 오브젝트 컴포지션도 그 일을 할 수있을 때 어떤 것이 더 좋은지 항상 확신하지 못합니다. 그들과 매우 비슷한 것을 얻을 수있는 것 같지만 몇 가지 차이점이 있습니다.

  • 가시성-mixin을 사용하면 모든 것이 공용 API의 일부가되며 구성에서는 그렇지 않습니다.
  • 장황함-대부분의 경우 믹스 인은 덜 장황하고 사용하기가 조금 더 쉽지만 항상 그런 것은 아닙니다 (예 : 복잡한 계층 구조에서 자체 유형을 사용하는 경우).

짧은 대답은 "상황에 따라 다름"이라는 것을 알고 있습니다.하지만 이것이 더 나은 경우에는 일반적인 상황이있을 수 있습니다.

지금까지 생각해 낼 수있는 지침의 몇 가지 예 (내가 두 가지 특성 A와 B가 있고 A가 B에서 몇 가지 방법을 사용하고 싶다고 가정) :

  • B의 메소드로 A의 API를 확장하려면 mixins, 그렇지 않으면 구성. 그러나 내가 만드는 클래스 / 인스턴스가 공용 API의 일부가 아닌 경우에는 도움이되지 않습니다.
  • 믹스 인이 필요한 패턴 (예 : Stackable Trait Pattern )을 사용하려면 쉬운 결정입니다.
  • 순환 종속성이있는 경우 자체 유형이있는 믹스 인이 도움이 될 수 있습니다. (나는 이런 상황을 피하려고 노력하지만 항상 쉬운 것은 아닙니다)
  • 구성을 수행하는 방법에 대한 동적 런타임 결정을 원한다면 개체 구성을 수행하십시오.

많은 경우 믹스 인이 더 쉬운 것 같지만 (그리고 / 또는 덜 장황한) "신 클래스"와 같은 몇 가지 함정과 두 개의 아티 마 기사에 설명 된 다른 것들이 있다고 확신합니다 : 파트 1 , 파트 2 (BTW it 대부분의 다른 문제는 스칼라와 관련이 없거나 심각하지 않은 것 같습니다.)

이와 같은 힌트가 더 있습니까?


사람들이 믹스 인과 관련된 많은 문제를 스칼라에서 피할 수 있습니다. 추상 특성을 클래스 정의에 혼합 한 다음 객체 인스턴스화 시간에 해당하는 구체적인 특성을 혼합하면 스칼라에서 피할 수 있습니다. 예를 들어

trait Locking{
   // abstract locking trait, many possible definitions
   protected def lock(body: =>A):A
}

class MyService{
   this:Locking =>
}

//For this time, we'll use a java.util.concurrent lock
val myService:MyService = new MyService with JDK15Locking 

이 구성에는 몇 가지 권장 사항이 있습니다. 첫째, 특성 기능의 다양한 조합이 필요하기 때문에 클래스가 폭발하는 것을 방지합니다. 둘째, 모의 객체와 유사한 "아무것도하지 않는"구체적인 특성을 만들고 혼합 할 수 있기 때문에 쉽게 테스트 할 수 있습니다. 마지막으로, 우리는 우리 서비스 소비자로부터 사용 된 잠금 특성을 완전히 숨겼습니다.

믹스 인의 단점을 대부분 극복 했으므로 믹스 인과 컴포지션 사이의 절충안이 여전히 남아 있습니다. 나는 일반적으로 가상의 델리게이트 객체가 포함 된 객체에 의해 완전히 캡슐화되는지 또는 잠재적으로 공유 될 수 있고 자체 라이프 사이클을 가질 수 있는지 여부에 따라 결정을 내립니다. 잠금은 완전히 캡슐화 된 대리자의 좋은 예를 제공합니다. 클래스가 내부 상태에 대한 동시 액세스를 관리하기 위해 잠금 개체를 사용하는 경우 해당 잠금은 포함하는 개체에 의해 전적으로 제어되며 해당 잠금과 해당 작업은 클래스 공용 인터페이스의 일부로 광고되지 않습니다. 이와 같이 완전히 캡슐화 된 기능을 위해 믹스 인을 사용합니다. 데이터 소스와 같은 공유 항목의 경우 구성을 사용하십시오.


언급하지 않은 다른 차이점 :

  • 특성 클래스는 독립적 인 존재가 없습니다.

( 스칼라 프로그래밍 )

특정 트레이 트가 다른 클래스의 부모로 가장 자주 사용되어 자식 클래스가 부모 트레이 트로 동작하는 것을 발견 한 경우,이 논리적 관계를보다 명확하게 만들기 위해 트레이 트를 클래스로 정의하는 것이 좋습니다.
( 예를 들어 [Martin2003] 참조) 전자는 Liskov Substitution Principle을 기반으로 한 상속에 대한보다 정확한 정의이기 때문에 는 a가 아니라으로 동작 한다고 말했습니다 .

[Martin2003] : Robert C. Martin, Agile 소프트웨어 개발 : Prentice-Hall, 2003 년 원리, 패턴 및 관행

  • mixins ( trait)에는 생성자 매개 변수가 없습니다.

따라서 Programming Scala조언은 다음과 같습니다.

Avoid concrete fields in traits that can’t be initialized to suitable default values.
Use abstract fields instead or convert the trait to a class with a constructor.
Of course, stateless traits don’t have any issues with initialization.

It’s a general principle of good object-oriented design that an instance should always be in a known valid state, starting from the moment the construction process finishes.

That last part, regarding the initial state of an object, has often helped decide between class (and class composition) and trait (and mixins) for a given concept.

참고URL : https://stackoverflow.com/questions/3422606/mixins-vs-composition-in-scala

반응형