2011-09-28 1 views
8

У меня есть группа систем, позвоните по телефону A, B, C, D, E, F, G, H, I, J.Интерфейс, Аннотация или просто виртуальные методы?

Все они имеют сходные методы и свойства. Некоторые из них содержат тот же метод и свойства, некоторые из них могут незначительно отличаться, а некоторые могут сильно различаться. Прямо сейчас у меня есть много дублированного кода для каждой системы. Например, у меня есть метод, называемый GetPropertyInformation(), который определен для каждой системы. Я пытаюсь выяснить, какой метод будет наилучшим способом уменьшить дублирование кода или, может быть одним из перечисленных ниже способов не путь:

Интерфейс

public Interface ISystem 
{ 
    public void GetPropertyInformation(); 
    //Other methods to implement 
} 

public class A : ISystem 
{ 
    public void GetPropertyInformation() 
    { 
     //Code here 
    } 
} 

Аннотация

public abstract class System 
{ 
    public virtual void GetPropertyInformation() 
    { 
     //Standard Code here 
    } 
} 

public class B : System 
{ 
    public override void GetPropertyInformation() 
    { 
     //B specific code here 
    } 
} 

Виртуальные методы в классе Супер Base

public class System 
{ 
    public virtual void GetPropertyInformation() 
    { 
    //System Code 
    } 
} 

public class C : System 
{ 
    public override void GetPropertyInformation() 
    { 
     //C Code 
    } 
} 

один вопрос, хотя это может быть глупо, это допустим, я пошел с абстрактным подходом, и я хотел, чтобы переопределить GetPropertyInformation, но мне нужно, чтобы передать ему дополнительный параметр, возможно ли это или я должен создать другой метод в абстрактном классе? Например, GetPropertyInformation(x)

ответ

6

Подходы с абстрактным и «супер базовым классом» не слишком разные. Вы всегда должны делать абстрактные абстрактные классы, и вы можете предоставить реализацию по умолчанию (виртуальные методы) или нет (абстрактные методы). Решающим фактором является то, хотите ли вы когда-либо иметь экземпляры базового класса, я думаю, что нет.

Так что это между базовым классом и интерфейсом. Если между вашими классами A, B C существует сильная связь, вы можете использовать базовый класс и, возможно, общую реализацию.

Если классы A, B, C естественно не принадлежат к одному «семейству», то используйте интерфейс.

И System не такое хорошее имя.

И вы не можете изменить список параметров при переопределении. Возможно, параметры по умолчанию могут помочь, иначе вам просто нужно 2 перегрузки для GetPropertyInformation().

+0

У меня было чувство, что абстрактные и супер базовые классы были похожи. Системы A, B, C имеют сильную связь. Существует отраслевой стандарт, но его не нужно соблюдать, поэтому каждый может либо принять стандарт, либо изменить стандарт на их установку. В спешке я выбрал System :) – Xaisoft

+0

Хорошие точки кстати. – Xaisoft

3

Как правило, вы выбираете наследование объектов, когда хотите разделить реализацию и уменьшите то, что в противном случае было бы дублированием. В противном случае интерфейсы выигрывают, потому что они более гибкие, так как нет необходимости в общем базовом классе.

Что касается переопределения метода и изменения списка параметров, это просто невозможно. Представьте, как бы вы назвали этот метод базовым классом или ссылкой на интерфейс?

+0

Это «возможно» - вы должны иметь возможность объявить такой метод, он больше не является переопределением исходного метода. – millimoose

+2

@ Sii Это точно невозможно. Заданный вопрос: * переопределить * метод и добавить параметр. Это невозможно. –

+0

У меня было ощущение, что это невозможно сделать, принятие желаемого за действительное. – Xaisoft

3

Я бы пошел с чем-то вроде того, что я добавил ниже. Вы по-прежнему пользуетесь интерфейсом и совместной реализацией.

public Interface ISystem 
{ 
    public void GetPropertyInformation(); 
    //Other methods to implement 
} 

public abstract class System : ISystem 
{ 
    public virtual void GetPropertyInformation() 
    { 
     //Standard Code here 
    } 
} 

public class B : System 
{ 
    public string ExtendedSystemProp {get;set;} 

    public override void GetPropertyInformation() 
    { 
     base.GetPropertyInformation(); 

     var prop = "some extra calculating"; 

     GetExtraPropertyInformation(prop); 
    } 

    public void GetExtraPropertyInformation(string prop) 
    { 
     ExtendedSystemProp = prop; 
    } 
} 

ISystem genericSystem = new B(); 
genericSystem.GetPropertyInformation(); 

(genericSystem as B).ExtendedSystemProp = "value"; 
+0

Можете ли вы рассказать о том, почему вы должны сделать такой подход? – Xaisoft

+0

Таким образом, вы все равно получаете все свои свойства, даже если вы программируете только с интерфейсом 'ISystem' (который вы должны делать, когда у вас есть). Однако, если вы кодируете в контексте, где существует только B: 'B bSystem = new B();' также выставляете конкретный метод 'B' для явного использования. – scottm

2

Вы не можете передать дополнительный параметр в переопределение. Когда вы переопределяете, вы переопределяете метод с точной подписью. Я бы предложил вам передать параметр интерфейса, например IPropertyInformation, который может быть изменен для каждой реализации.

Решение идти с базовым классом или интерфейсом для вашей реализации действительно зависит от вашего использования. У A-I достаточно общего между собой, что они должны действительно все происходить из одного и того же базового класса? Если это так, используйте базовый класс. Неужели это всего лишь GetPropertyInformation является общим, и в противном случае системы полностью функционально отличаются? Тогда вы действительно просто хотите, чтобы они делились интерфейсом.

2

Другие рассмотрели то, что первоначально было в моем ответе, но о точке «добавления параметра»: не забывайте, что последний C# также позволяет вам иметь необязательные параметры в методах.

+0

Но я должен был бы объявить необязательные параметры в самом начале. Возможно, я не знаю, что мне нужен параметр до 1 года в будущем, поэтому дополнительные параметры не помогут мне в этом случае. – Xaisoft

2

Если у вас нет веской причины, я бы пошел с интерфейсом. Публичные виртуальные методы, хотя многое сделано, составляют not ideal.