2009-12-05 5 views
4

나는 이것을 누군가의 코드에서 보았는데,이 특별한 문제를 해결하는 우아한 방법이라고 생각했지만, 서사적 인 방법으로 좋은 OO 원칙을 위반했을 가능성이 큽니다.인스턴스화하는 객체에 대한 참조가 필요한 클래스를 갖는 것이 바람직하지 않습니까?

모두 공통 기본 클래스에서 파생 된 클래스 집합의 생성자에서 전달할 인스턴스 클래스에 대한 참조가 필요합니다. 예 :
Foo Foo_i = new (this);

나중에 Foo는 인스턴스 클래스의 메소드를 호출하여 인스턴스 클래스에 포함 된 다른 객체에 대한 정보를 가져옵니다.

한편으로 이것은 하드웨어의 5 계층 트리 구조를 모델링하는 코드 (TON)를 단순화합니다 (여러 스위치의 포트에 연결된 에이전트 등). 다른 한편으로는,이 객체들은 꽤 틀린 방식으로 서로 단단히 연결되어 있지만, OOA & D에 관해서는 충분히 알지 못한다.

그래, 괜찮습니까? 아니면 goto 문과 같은 OO입니까?

+0

나는 그것이 결코 좋지 않다고 들었지만 어떤 경우에는 매우 편리합니다. – Rob

답변

2

정보 숨기기의 관점에서 볼 때이 문제를 피하려고 노력합니다. 클래스가 가지고 있거나 필요로하는 정보가 적을수록 쉽게 테스트하고 검증 할 수 있습니다. 그것은 말하자면, 어떤 경우에는 더 우아한 해결책으로 이어집니다. 그렇게하지 않으면, 지나치게 많은 매개 변수가 포함되어 끔찍하게 복잡하게 뒤얽혀 있습니다. 내가 내 컨트롤러에있는 특정 리스너 및 어댑터를 서브 클래스 내 서브 클래스에 그 청취자와 어댑터를 추가하여 한 번이 문제를 피하는 기억, 자바에서는

public class Outer { 
    private class Inner { 
    public Inner() { 
     // has access to the members of Outer for the instance that instantiated it 
    } 
    } 
} 
1

: 예를 들어

자바 내부 클래스와이 많이 사용합니다.

은 즉 내 컨트롤러 내가이 더 느슨하게 결합 된 생각

class p { 

    private member x 

    private methods 

    private class q { 
    // methods referencing p's private members and methods 
    } 

    x.setListener(new q()); 

} 

했지만, 나 또한 몇 가지 확인하고 싶습니다.

1

이 디자인 패턴은 어떤 상황에서는 많은 의미를 가질 수 있습니다. 예를 들어, 반복자는 항상 특정 콜렉션과 연관되어 있으므로 반복자의 생성자가 콜렉션을 필요로하는 것은 당연합니다.

구체적인 예를 제공하지 않았지만 클래스에서 goto을 상기 시키면 나쁜 생각 일 수 있습니다.

새 오브젝트가 정보 용 인스턴스화 오브젝트를 조사해야한다고했습니다. 아마도 클래스가 환경에 대해 너무 많은 가정을하고 있을까요? 이러한 가정이 단위 테스트, 디버깅 또는 (가상의) 코드 재사용을 복잡하게하는 경우 리팩토링을 고려해야합니다.

그러나 디자인이 개발자의 시간을 전반적으로 절약하고 2 년 후에 유지할 수없는 짐승을 기대하지 않는다면 실제적인 관점에서는 완전히 받아 들일 수 있습니다.

2

인스 턴싱 수업에서 Foo가 알아야 할 사항에 따라 Law of Demeter을 위반하는 것 같습니다. 물체는 느슨하게 결합되어야합니다. 하나의 클래스가 다른 클래스의 구조에 대해 많은 것을 알 필요가 없다. 제가 몇 번 들었던 한 가지 예는 당신이 지갑을 가게 직원에게 넘겨주지 않고 그를 안으로 데려 가게한다는 것입니다.귀하의 지갑은 귀하의 비즈니스이고, 귀하는 서기에게주고 귀하 자신에게 넘기는 데 필요한 것을 발견하게 될 것입니다. 지갑을 재구성하면 아무도 현명하지 못합니다. 느슨한 결합은 테스트를 더 쉽게 만듭니다. Foo는 복잡한 컨텍스트를 유지할 필요없이 이상적으로 테스트 할 수 있어야합니다.

+0

+1 좋은 유추 – gtrak

5

당신은 상호 참조를 피하려고 노력하지만 (특히 삽입물을 구현할 때) 종종 피할 수없는 경우가 종종 있습니다. 나는. 부모 자식 관계 - 아이들은 종종 부모를 알아야하고 어떤 사건이 발생하면이를 알릴 필요가 있습니다. 당신이 정말로해야한다면 - 인터페이스 (또는 C++의 경우 추상 클래스)를 선택하십시오. 클래스를 인스턴스화하면 클래스를 구현해야하고 인스턴스화 된 클래스는 인터페이스로만 클래스를 인식해야합니다. 이는 커플 링을 크게 줄입니다. 이 접근법은 클래스의 일부만 노출하므로 중첩 된 리스너 클래스와 비슷하지만 유지 관리가 더 쉽습니다. 여기에 C# 예제가 조금 있습니다 :

interface IParent 
{ 
    //some methods here 
} 

class Child 
{ 
    // child will know parent (instancing class) as interface only 
    private readonly IParent parent_; 
    public Child(IParent parent) 
    { 
     parent_ = parent; 
    } 
} 

class Parent : IParent 
{ 
    // IParent implementation and other methods here 
} 
관련 문제