상속을 사용할 때 '부울 필드'만 사용하는 경우


18

Rails 애플리케이션에서 알림을 추가하고 있습니다. 이 중 일부는 다음과 같습니다 blocking. 자원에 대한 일부 정보가 누락되어 추가 된 자원의 진행을 중지합니다.

다른 알림은 간단한 알림이며 정보 만 제공합니다.

오늘 저는 우리 팀에서 다른 프로그래머와 토론했습니다. 다음과 같이 상속 구조를 만들었습니다.

여기에 이미지 설명을 입력하십시오

그러나 blocking각 알림에 부울 리턴 메소드로 추가 하고 알림 상위 클래스 내부에서 차단되는 서브 클래스 목록을 지정하고 싶습니다 .

이러한 접근 방식의 차이는 그리 크지 않습니다. 내 접근 방식에서는 루트 클래스를 더 깨끗하게 유지 하면서이 목록을 지정할 필요가 없습니다. 반면에 발생하는 특수 로직Notification::Blocking 지금 당장 는 그리 크지 않습니다.

이 문제에 어떤 종류의 추상화가 더 적합합니까?


11
부모 클래스는 자녀에 대해 절대 알 수 없습니다. 왜 하위 클래스 목록을 유지해야합니까?
coteyr

자원에 어떻게 추가되고 진행을 어떻게 중단합니까?
null

3
왜 그렇게 많은 알림 클래스가 필요합니까? 하나의 알림 클래스를 만든 다음 데이터가 데이터 유형 대신 작업을 수행하도록 할 수 있습니다.
Trisped

1
@Trisped : 오른쪽, 철저한 사례 목록을 사용하여 행동의 한 측면을 기본 클래스로 옮기는 것을 알게되면 신념에 용기를 내고 확장을 통해 사용자 정의 할 수있는 기본 클래스를 실제로 설계하지 않는다는 것을 인정하십시오. 모든 행동을 기본 클래스로 옮기십시오 !
Steve Jessop

답변:


35

파생 클래스에 대해 알고있는 기본 클래스를 피하려고합니다. 새로운 파생 클래스를 만들 때마다 목록에 추가해야한다는 점을 기억해야하므로 밀접한 연결이 필요하고 유지 관리 문제가 발생합니다.

또한이 프로젝트를 여러 프로젝트에서 사용하려는 경우 Notification 클래스를 재사용 가능한 패키지 / 조립품에 넣을 수 없습니다.

실제로 단일 기본 클래스를 사용하려는 경우이를 해결하는 또 다른 방법은 기본 Notification 클래스에 가상 속성 또는 메서드 IsBlocking을 추가하는 것입니다. 그러면 파생 클래스가이를 재정 의하여 true 또는 false를 반환 할 수 있습니다. 파생 클래스에 대한 기본 클래스를 모르는 단일 클래스 솔루션이 있습니다.


3
이. 한 곳에서 결정하십시오. 어떤 클래스가 클래스와 목록 사이에서 차단되는지에 대한 지식을 산포하지 마십시오.
candied_orange

이것은 내가하는 일이며, 잘 작동하며 재사용이 가능합니다.
coteyr

13

Notification 상위 클래스 내에서 차단되는 서브 클래스 목록을 지정하십시오.

그것은 매우 독창적이며 특정 코드 냄새입니다.

클래스 간 동작에 차이가있는 경우 서브 클래스를 제공하고 이러한 모든 알림을 동일한 방식으로 처리하려고합니다 (예 : 다형성 사용 ).


1
여기서 "행동"이 핵심이라고 생각합니다. 단지 데이터 일 때, 그 분야는 충분한 차별자가되어야합니다. 동작은 다형성을 사용하는 더 좋은 이유이지만 상속 계층을 만들 때는 항상 유지 관리 복잡성을 고려해야합니다. 읽기 en.wikipedia.org/wiki/Composition_over_inheritance
cottsak

7

기존 답변과 반대로, 사용되는 모드가 동적으로 변경되어야하는 경우 (예 : 차단 할 유형 목록을 제공하는 구성 파일을 통해) 부울 속성이 가장 좋습니다. 그리고 그렇지 않습니다).

즉,이 상황에서도 더 나은 디자인은 Decorator 객체를 사용하는 것일 수 있습니다.


1

나는 그것이 첫 번째 생각은 "둘 다"가는 것이지만, 차단 알림에 대해 다른 것이 얼마나 많은지에 달려 있다고 말합니다.

class Notification
 virtual Boolean Blocking{get return false;}

class BlockingNotification inherits Notification
 virtual overrides Boolean Blocking{get return true;}

그렇게 하면 클래스를 상황에 맞는 값 으로 구현하도록 허용 할 때마다 n.Blocking또는 n is BlockingNotification(모두 의사 코드로) 사용할 수 있지만 Blocking매번 해당 값을 확인 해야하는 경우 BlockingNotification클래스는 덜 유용합니다.

어쨌든, 나는 기본 클래스 구현 Blocking이 파생 클래스에 대해 알 필요가 없다는 다른 답변에 동의합니다 .


0

두 개의 기본 클래스와 각각의 여러 인스턴스를 만드는 대신 알림이 차단되는지 여부와 알림을 사용자에게 전달하는 데 필요한 기타 정보를 나타내는 부울을 사용하여 하나의 알림 클래스를 만듭니다.

이를 통해 알림을 처리하고 표시하기 위해 하나의 코드 세트를 사용할 수 있으며 코드의 복잡성이 줄어 듭니다.

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