2014-05-17 2 views
2

MyObjects 목록에 저장된 parametres에 시간이 오래 걸리는 클래스를 작성하고 있습니다. List의 여러 기능에 쉽게 액세스 할 수 있기를 원했기 때문에 목록 유형을 확장하여 작성했습니다 (대안은 목록을 클래스에 포함하고 사용하려는 모든 메소드를 다시 작성하는 것입니다). , 그러나 그것은 overcomplication처럼 보입니다). 계산 결과는 꽤 복잡하고 시간 소모적이기 때문에 결과는 저장된 매개 변수 (시간 영향, 숨겨진 종속성 등 없음)에만 의존하지만 결과를 캐시하기로 결정했습니다. 그래서 내 코드는 더 많거나 적은 같은 외모 : 메소드 getResult를()가 처음 호출 될 때와일드 카드를 사용하는 클래스의 메서드를 "재정의"

public class Calculator extends ArrayList<MyObject> { 

    private double Result = Double.NaN; 

    public double getResult() { 
     if (Double.isNaN(Result)) { 
      Result = CalculateResult(); 
     } 
     return Result; 
    } 
} 

이 방법은 결과, 저장을 계산 한 다음 이후의 통화 중 다시 사용합니다.

이제 목록의 내용을 다양한 방법으로 수정할 수 있으며 많은 수정을 통해 캐시를 지워야합니다. "슈퍼"일반 ArrayList 클래스를 의미하므로 컴파일러가 타입 오류가 발생하기 때문에,

public void add(MyObject newvalue) { 
    super.add(newvalue); 
    Result = Double.NaN; 
} 

그러나, 그것은 작동하지 않습니다이를 달성하기 위해, 일반적으로 내가 좋아하는 뭔가를 작성합니다.

내 수준에 명백한 트릭을 MyObject되는 ArrayList를 구현하는 것이 임시 클래스를 생성하고 계산기이 임시 클래스를 확장 할 수 있도록하는 것입니다 :

public class MyArrayList extends ArrayList<MyObject> { 
} 

public class Calculator extends MyArrayList { 
} 

을하지만 다시 overcomplication 것 같습니다. 이 결과를 얻기위한보다 우아한 방법이 없습니까? 또는 SQL에서 트리거와 비슷한 메커니즘이있을 수 있습니다. 목록에 수정 사항이있을 때마다 클래스가 캐시를 지우도록 강요합니까?

+3

이리스트의 구현을 확장하지 마십시오입니다. 그러면 API가 오염되고 클래스가 특정 구현에 연결됩니다.이를 필드로 사용하고 클래스에'List' 인터페이스를 구현 한 다음 필요한 메소드를 필드로 사용 된 목록 구현의 인스턴스에 위임하십시오. 약간 자세한 정보이지만 클래스 사용자에게 훨씬 유연하고 깨끗합니다. – toniedzwiedz

+0

http://stackoverflow.com/questions/49002/prefer-composition-over-inheritance – Raedwald

+0

신속한 답변을 위해 모두에게 고마워요. 귀하의 예제가 실제로 컴파일 문제를 해결했습니다. 그러나 실제로 코드 디자인의 근거를 다시 생각해 볼 필요가 있습니다. – Jasio

답변

1

composition over inheritance이 코드 디자인에 실제로 적합한 경우의 좋은 예입니다. 클래스가 불필요한 작업으로 복잡해질 것입니다. List의 인스턴스가 실제로 부동 상태 일 때만 필요합니다. 또한 ArrayList 구현에 의존하지 않는다는 것을 의미합니다. 예를 들어 알고리즘에서 LinkedList을 대신 호출하면 어떻게 될까요?

하지만, 당신이 정말로 당신이 무엇을 해결하려면 ...

먼저하고, 지금까지 자바에 관한 한, 당신은 시도 이기 때문에 무엇보다도, 당신은 컴파일러 오류가 발생하고있는 이유는을 사용하여 add 메서드를 재정의 할 수 있지만 서명이 올바르지 않습니다.

올바른 서명은 boolean add(E)으로 지정되었지만 void add(E)의 서명으로 대체합니다. 형식이 일치하지 않으므로 성공적인 재정의를 얻지 못해 알 수 있듯 Java가 클래스를 컴파일하지 않습니다.

다음으로 상속하는 것과 동일한 일을 수행하기 위해 더 많은 클래스를 생성하면 ArrayList 클래스를 올바르게 재정 의하여 아무것도 얻지 못할 것입니다. 무엇이든간에, 그것은 입니다.은 과장되었습니다. 부울 값을 반환해야합니다 add

3

방법은, 그래서 모두 당신이해야 할 일을

public boolean add(MyObject newvalue) { 
    boolean retVal = super.add(newvalue); 
    Result = Double.NaN; 
return retVal ; 
} 
+0

이것은 컴파일러 오류를 수정하고 나는 upvoted. 그러나 상속에 비해 컴포지션을 선호한다는 다른 의견은 ArrayList를 수퍼 클래스가 아닌 멤버 변수로 사용하는 것이 좋습니다. –

관련 문제