책임을 분담 할 때 단일 책임을 관리하는 방법은 무엇입니까? 다른 클래스에 명확하게

나는 기본 두 개의 클래스를 가지고 OperationTrigger. 각각에는 특정 유형의 작업 또는 트리거를 전문으로하는 여러 하위 클래스가 있습니다. A는 Trigger특정을 트리거 할 수 있습니다 Operation. 동안 Operation특정에 의해 트리거 될 수 있습니다 Trigger.

주어진 Operation것을 주어진 Trigger(또는 그 반대로) 매핑하는 코드를 작성해야 하지만 어디에 넣을 지 잘 모르겠습니다.

이 경우 코드는 한 클래스 또는 다른 클래스에 명확하게 속하지 않습니다. 따라서 단일 책임 원칙의 관점에서 코드가 어디에 속해 있는지 확실하지 않습니다.

모든 것이 작동하는 세 가지 옵션을 볼 수 있습니다. 1과 2는 의미론의 선택으로 보이지만 3은 완전히 다른 접근법을 나타냅니다.

  1. 예를 들어 트리거에서 bool Triggers(Operation o).
  2. 예를 들어 작업에서 bool TriggeredBy(Trigger t).
  3. 예를 들어, 매핑을 관리하는 완전히 새로운 클래스 bool MappingExists(Trigger t, Operation o).

단일 책임 원칙과 관련하여 공유 매핑 코드를 배치 할 위치를 어떻게 결정해야합니까?

책임을 분담 할 때 단일 책임을 관리하는 방법은 무엇입니까?


편집

실제 코드는 다음과 같습니다. 모든 속성이 있습니다 중 하나 string, Guid, collection<string>, 또는 enum. 기본적으로 작은 데이터 조각을 나타냅니다.

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

편집 2.

반환 유형이 bool 인 이유입니다. 다른 클래스는의 모음 Trigger과의 모음 을 사용할 것 입니다 Operation. Trigger와 a 사이에 매핑이 존재하는 위치를 알아야 합니다 Operation. 해당 정보를 사용하여 보고서를 작성합니다.



답변

나는 이런 식으로 생각할 것입니다 : 어떤 동작으로 인해 어떤 트리거가 트리거되는지는 어떻게 결정됩니까? 시간이 지남에 따라 변경되거나 여러 알고리즘으로 발전 할 수있는 알고리즘이어야합니다. 이를 Trigger 또는 Operation 클래스에 배치하면 해당 클래스가 향후 이러한 시나리오를 처리 할 수 ​​있음을 의미합니다. 더 많은 매핑이있을 수 있으므로 매핑만큼 간단하지는 않습니다.

GetOperationForTrigger (Trigger t)와 같은 적절한 메서드를 사용하여 클래스를 만드는 것이 좋습니다. 이를 통해 코드는 런타임 또는 기타 변수 (예 : 전략 패턴)에 따라 선택할 수있는 이러한 클래스 세트로 발전 할 수 있습니다.

이 사고 방식의 주요 가정은 최소한의 코드를 작성하는 것 (즉, 오늘 3 개의 클래스)이지만 앞으로 정확히 한 가지 방법이있을 것이라는 가정을하지 않음으로써 향후 기능을 확장해야하는 경우 주요 리팩토링을 피하는 것입니다. 어떤 트리거가 어떤 작업을 유발하는지 확인합니다.

도움이 되었기를 바랍니다. 응답은 user61852와 유사하지만 추론이 다릅니다. 결과적으로 구현이 달라집니다 (즉, 동등을 재정의하는 대신 명시적인 메소드를 가지므로 필요에 따라 메소드의 수가 시간이 지남에 따라 진화 할 수 있음).


답변

거기에 있었어요.

옵션 # 3.

어떤 언어를 사용할지 모르지만 Java와 매우 유사한 의사 코드를 사용합니다. 당신의 언어가 C #이라면 아마도 비슷한 인터페이스와 구조를 가지고있을 것입니다.

맵핑 클래스 또는 인터페이스가 있어야합니다.

public interface Mapping {
    public void setObject1(Object o);
    public void setObject2(Object o);
    public Object getObjecto1();
    public Object getObjecto2();
}
  • 컬렉션의 주어진 equals()메소드가 포함되어 있는지 조회 할 수 Mapping있도록 메소드를 대체하십시오 Mapping.
  • 특수화 된 객체에도 적절한 equals()방법이 있어야 합니다.
  • 또한 인터페이스를 구현하여 Comparable보고서를 정렬 할 수 있습니다.

당신은 단순히 컬렉션에 매핑을 넣을 수 있습니다

List<Mapping> list = new ArrayList<Mapping>();
Hat hat = new Hat();
Bag bag = new Bag();
list.add(new Mapping(hat,bag));

나중에 당신은 요청할 수 있습니다 :

// let's say you have a variable named x which is of type Mapping

if ( list.contains(x) ){
    // do some thing
}

답변

  1. 코드를 더 작은 비트로 나누십시오.

현재 클래스 B에 대해 알고있는 클래스 A와 클래스 A에 대해 알고있는 클래스 B가 있습니다. 많은 커플 링이 진행되고 있습니다.

정의에 의하면 A는 적어도 자신의 작업을하고있다 B를 실행할지 여부를 검사합니다. B의 경우에는 그 반대입니다. 처음 호출 한 클래스는 결과를보고 추가 작업을 수행해야하는지 확인할 수 있어야합니다.

클래스를 더 작은 구성 요소로 분할하여 해당 커플 링을 시도하십시오. 나는 각 수업의 상단에 평범한 영어로 무엇을 하는지를 설명하고 싶습니다. AND와 같은 단어를 사용해야하거나 한두 문장을 넘어서려면 세분화를 고려해야합니다. 일반적으로 “and”뒤의 항목은 자체 클래스에 있어야합니다.

또한 트리거 및 작업 기능을 다루는 인터페이스를 정의 할 수 있는지 확인하십시오. 그것이 당신의 수업이 너무 커지고 있다는 또 다른 표시입니다. 또한 수업 사이의 연결을 끊을 것입니다.