2014-03-25 1 views
1

비슷한 기능을 공유하는 여러 클래스의 이름을 지정하는 것에 대한 질문이 있습니다. 나는 과학 API에 일하고 클래스/인터페이스를 다음과 같습니다다른 이름을 가진 동일한 클래스가 여러 개있는 것이 맞습니까?

public interface IRange<T>{ 
    T Minimum {get;} 
    T Maximum {get;} 
    // A few other methods that aren't important 
} 

public class Range<T> : IRange<T> where T: IComparable<T> { 
    public T Minimum {get; protected set;} 
    public T Maximum {get; protected set;} 

    public Range(T minimum, T maximum) { 
     Minimum = minimum; 
     Maximum = maximum; 
    } 
} 

내 API를 들어, 내가 double 작업을 많이 (즉, Range<double>) 범위, 그래서 나는에게 MassRange라는 다른 클래스를했다. Range<double>MzRange라고의 나는 또한 내가 별도의 유지하지만 MassRange로 주 모두 같은 구조와 기능이 있음을, 또 다른 유형이, 개념적으로

public class MassRange : Range<double>, IRange<double> { 
    public double Width { get { return Maximum - Minimum;} } 
    public double Mean { get { return (Maximum + Minimum)/2.0;} } 

    public MassRange(double mean, MassTolerance width) { 
     Minimum = mean - width.Value; // pseudo-code 
     Maximum = mean + width.Value; 
    } 
} 

:이 클래스는 또한 몇 가지 새로운 생성자와 속성 아래 그림이있다 API 그들은 똑같은 방식으로 작동하고 동일한 유형의 데이터를 저장하지만, 과학 측면에서 볼 때 서로 다르며 뚜렷합니다.

그래서 나는 DoubleRange의보다 일반적인 이름으로 MassRange 클래스의 이름을 변경 간주하고 모두 MassRange : DoubleRangeMzRange : DoubleRange을 가지고과 같이 설계 :

public MzRange : DoubleRange, IRange<double> {} 

public MassRange : DoubleRange, IRange<double> {} 

하지만 난 정말 이름 DoubleRange에 대한 관심, 그리고 것하지 않습니다 내 API를 통해 공개적으로 공개하지 마세요. 동일한 기능을 가진 두 개의 다른 유형이 적절하게 노출되고 있습니까? 나는 단지 DoubleRange에 대해 더 좋은 이름을 내고 MzRangeMassRange을 잊어 버려야합니까? DoubleRange을 내부 또는 무언가로 만들어 API를 통해 노출되지는 않지만 계속 사용할 수 있습니까?

이것은 Extension Properties의 경우 인 것으로 보이지만 현재 존재하지 않습니다.

답변

1

이 당신이 표준 extension methods으로이 작업을 수행 할 수없는 이유가 될 것 같지 않습니다 :

public static double GetWidth(this IRange<double> range) { 
    return range.Maximum - range.Minimum; 
} 

public static double GetMean(this IRange<double> range) { 
    return (range.Maximum + range.Minimum)/2.0; 
} 

그리고 당신은 IRange의 구현에서 호출 할 수 있습니다

var massRange = ... 
var mean = massRange.GetMean(); 

I 확장 속성의 문법적 호소력이 없다는 것을 알고 있지만 그것은 DoubleRange 클래스를 만들어야하는 번거 로움이없는 해결책입니다.

+0

여기에있는 내용에 분명히 동의합니다. Linq가 구현되는 방식으로 요구 사항을 구현해야합니다. 제네릭 인터페이스가 많이 있으며 많은 확장 방법이 있습니다. +1 –

+0

이 속성에 대해 작동하지만 DoubleRange에 추가 한 새 생성자에 도움이되지 않습니다. – Moop

+0

@Moop 그것은 당신에게 어떤 생성자도 제공하지 않지만 아마도'DoubleRange'는 어쨌든 가질 수없는'MassRange'와'MzRange' 클래스에 다른 생성자를 가질 것입니다, 맞습니까? 'MzRange'는'MzTererance'를 취합니까? 물론 정확한 요구에 따라 정적 팩토리 메서드를 만들 수는 있지만 정확히 무엇이 될 것인가라는 질문에서 완전히 명확하지는 않습니다. –

0

이것은 아주 적절합니다. 논리적 구분 외에도 앞으로 두 클래스를 서로 독립적으로 진화시킬 수있는 가능성을 제공합니다.

코끼리와 새는 동물입니다 (동물을 상속 함). 둘 다 같은 속성 집합을 가지고 있습니다 (구성원을 추가하거나 무시하지 않음). 나중에 Fly 메서드를 새에 추가 할 수 있습니다. 한 가지 유형에 대한 모든 변경 사항은 다른 할 필요가로 내가 Dumbo라는 이름의 코끼리가

+0

'Elephant'와'Bird'가 상속받는 Animal 클래스가없는 이유는 무엇입니까? 'Bird'와'Elephant' 클래스는 동일하지 않지만'Weight' 나'Height'와 같은 기본 속성이나 모든 동물에 공통적 인 속성을 포함하는'Animal'을 상속합니다. 장소 전체에 중복 된 속성을 가진'Bird'와'Elephant'를 만들고 싶지는 않을 것입니다. 그것은 가난한 디자인 일 것입니다. –

+1

@ MichaelJ.Gray 올리버가 말하는 것을 볼 수는 있지만 '코끼리'와 '버드'는 여기서 가장 좋은 은유가 아닐 수도 있습니다. '코끼리'와'자동차'는 더 좋을지도 모른다. 둘 다 특정 무게와 높이를 가지고 있으며 둘 다 트렁크를 가지고 있습니다. 그러나 그것들은 매우 다르므로 완전히 다른 계층을 설계해야 할 수도 있습니다. 그럼에도 불구하고 실제로 주변에서 기능 할 수있는 인터페이스를 설계해야합니다 (예 :'Car : IHasWheels'). –

+0

@ MichaelJ.Gray : "코끼리와 새는 동물입니다"라는 말은 모두 동물을 상속한다는 뜻입니다. 그리고 둘 다 "같은 속성을 가지고있다"는 말은 동물로부터 상속받은 것 외에 다른 멤버를 제공하지 않는다는 의미입니다. –

0

는 동일한 기능을 두 가지 유형을 갖는 :-) 실제 시나리오에 존재하지 않는 가정은 적합하지 않습니다.

당신이 MassRangeMzRangeDoubleRange위한 더 나은 이름을 제공하고 MassRange/MzRange 삼가고, 미래의 어떤 시점에서 차별화됩니다을 알고 않는 길을 가야하는 것입니다. 그렇다면 공유 기능을 부모 유형으로 사용해야합니다.

사용자를 돕기 위해 언제든지 syntactic sugar을 제공 할 수 있습니다. 예를 들어, MassRangeMzRange이라는 단순하지 않은 클래스를 만들면 간단히 DoubleRange으로 확장됩니다. 사용자가 사용하도록 권장하기 위해 원본 클래스의 클래스를 공개하고 싶지만 실제로 숨기려면 public 대신 protected 접근자를 사용하면됩니다.

관련 문제