2010-07-27 2 views
2

:추가 데이터를 저장하기 위해 개체 계층 구조를 확장하는 방법은 무엇입니까? 나는 클래스 계층 구조를 가지고 C#을 코드베이스에서 일하고 있어요

class Animal { Animal prey; } 
class Mammal : Animal { Mammal[] livesAmicablyWith; } 
class Lion : Mammal { } 

는 바보 같은 예를 용서.

이 클래스 계층 구조를 동일한 정확한 개체 형식으로 표현할 수있는 것으로 재사용하고 싶지만 더 많은 데이터가 필요합니다. 내 이상적으로, 그 결과는 다음과 같습니다

class Animal { Animal prey; string moreAnimalData; } 
class Mammal : Animal { Mammal[] livesAmicablyWith; string moreMammalData; } 
class Lion : Mammal { string moreLionData; } 

그러나, 나는이 기존 계층 구조에 구성원을 추가 피하고 싶은, 그들은 기껏 낭비 공간, 최악의 버그가 발생하기 쉬운 방해가 될 것이기 때문에.

또한 작업을 계속하기 위해 모든 원래 기능이 필요합니다. 다음은 내가 생각한 것입니다.

class AnimalExtended : Animal { } 
class MammalExtended : Mammal { 
    public void UseLivesAmicablyWith() 
    { 
     foreach(Mammal m in livesAmicablyWith) 
     { 
      if(!(m is MammalExtended) 
       throw new Exception(); 

      // use the MammalExtended 
     } 
    } 
} 
class LionExtended : Lion { } 

여기에 어떤 의견이 있습니까?

+0

'if' 줄에 괄호가 없습니다. –

답변

0

"표준"추가 데이터를 원하는 방식에 따라 달라질 것입니다. 기본적으로

var mammal = getLion(); // Returns a lion...possibly an ExtendedLion, but possibly not 
var extended = mammal as IExtendedData; 
if (extended != null) 
{ 
    string mammalData = extended.GetMoreData<Mammal>(); 
    string lionData = extended.GetMoreData<Lion>(); 
} 
+0

내 입에서 말을 꺼냈다. –

+1

@ 헌터 : 어떤 종류의 코멘트입니까? 이것은 특별히 복잡한 해결책이 아닙니다 ... 명시 적으로 자신의 기존 클래스 계층 구조를 수정하지 않고 자신이 확장 유형을 선택할 수 있도록하려는 것입니다 (따라서 generics). 문 사람에게 당신의 태도를 확인하십시오. 그렇지 않으면 여기에서는 많은 존경심을 얻지 못할 것입니다. – jrista

+1

좋아요, 얘들 아, 한 단계 아래로 내려 가면 모드가 게시글을 잠글 수 있습니다. 또한, jrista, 나는 당신의 담당자를 비웃었습니다. 귀하의 담당자는 귀하의 neckbeard만큼 조바심입니다. Rep가 당신을 다른 사람보다 더 나은 사람으로 만드는 것은 아닙니다. Jon Skeet을 제외하고, 다른 모든 사람들보다 실제로 더 낫습니다. – Will

1

당신이 처리 하려는지 : 불가지론 여분의 데이터를 얻을 수

interface IExtendedData 
{ 
    string GetMoreData<T>(); 
} 

class ExtendedAnimal: Animal, IExtendedData 
{ 
    public virtual string GetMoreData<T>() 
    { 
     if (typeof(T) == typeof(Animal)) 
      return "Extra animal data"; 

     return String.Empty; 
    } 
} 

class ExtendedMammal: Mammal, IExtendedData 
{ 
    public override string GetMoreData<T>() 
    { 
     if (typeof(T) == typeof(Mammal)) 
      return "Extra mammal data"; 

     return base.GetMoreData<Animal>(); 
    } 
} 

class ExtendedLion: Lion, IExtendedData 
{ 
    public override string GetMoreData<T>() 
    { 
     if (typeof(T) == typeof(Lion)) 
      return "Extra lion data"; 

     return base.GetMoreData<Mammal>(); 
    } 
} 

사용에서, 당신은 IExtendedData 동적 캐스트 수있다 : 당신은 단순히 결과를 달성하기 위해 더 많은 다형성을 사용할 수 있습니다 다중 상속입니다. 물론 C#에서는 할 수 없습니다 (Stackoverflow에 대한 많은 Q를 참고하십시오). 인터페이스에

이동 : IAnimal, IMammal, ILion을하고 다음 항목을 참조 할 때 클래스를 사용 중지 - :

선택할 수있는 옵션은. 못생긴 큰 콤보 클래스를 만들 수 있지만 관련 속성 만 볼 수 있도록 IAnimal 또는 IAnimalExtended을 사용하여 참조하십시오. 고유 한 논리적 기능을 그룹화하는 인터페이스를 더 잘 사용합니다. 어쩌면 ISocial 대신 IAnimalExtended이 표시됩니다. 여기서 ISocial은 생물이 서로 어떻게 상호 작용하는지 정의합니다. 대신 상속

사용 구성 : LionExtendedFeeding 일부 기본 Animal 클래스가 아닌 구현 SocialNature뿐만 하나의 문제를 다루는 작은 클래스의 속성을 노출합니다.

모두 수행 : 상속에 비해 인터페이스와 선호하는 구성을 사용하십시오.

0

나는 당신이 선택한 접근법이 건전하고 작동 할 것이라고 생각합니다. 값을 추가 할 때 (예 : 포유 동물을 livesAmicablywith에 추가하는 등) 유형 검사를 수행하려고합니다 (값이 추가 된 시점에서 캡슐화 된 것으로 가정). 오류를 훨씬 쉽게 잡을 것입니다.

0

Decorator 패턴의 경우에는 좋은 사례라고 생각합니다. 당신이 생각하는 해결책은 확실히 그 방향으로 간다.

관련 문제