Хитрый вопрос архитектуры. 4 Базовые классы требуют немного расширяемости - PullRequest
1 голос
/ 09 июля 2009

У меня есть 4 базовых класса:

class A { virtual SomeMethod () { <code> } }
class A<T> { virtual SomeMethod () { <code> } }

class B { virtual SomeMethod () { <code> } }
class B<T2> { virtual SomeMethod () { <code> } }

Теперь у меня есть 4 реализации (каждая реализация получена из соответствующего базового типа).

class Aa : A { override SomeMethod () { <code> } }
class Aa<Tt> : A<T> { override SomeMethod () { <code> } }

class Bb : b { override SomeMethod () { <code> } }
class Bb<Tt2> : B<T2> { override SomeMethod () { <code> } }

Теперь мне нужно добавить реализацию SomeMethod (она должна быть переопределена для базовой станции). ЖЕ ОДИН для всех упомянутых производных классов.

Какое лучшее решение? (Я поделюсь всеми своими идеями сразу после того, как вопрос будет решен. Поскольку, если я поставлю свою реализацию здесь, обсуждение, скорее всего, пойдет в моем направлении, но я не совсем уверен, прав ли я).

Спасибо за ваши прекрасные идеи !!

Ответы [ 5 ]

4 голосов
/ 09 июля 2009

Итак, вы хотите одну реализацию для некоторых 4 классов, а другую реализацию для некоторых других 4 классов? Возможно, шаблон стратегии сработает.

interface ISomeMethodStrategy {
    string SomeMethod(string a, string b);
}

class DefaultStrategy : ISomeMethodStrategy {
    public string SomeMethod(string a, string b) { return a + b; }
    public static ISomeMethodStrategy Instance = new DefaultStrategy();
}
class DifferentStrategy : ISomeMethodStrategy {
    public string SomeMethod(string a, string b) { return b + a; }
    public static ISomeMethodStrategy Instance = new DifferentStrategy();
}

class A {
    private ISomeMethodStrategy strategy;
    private string a, b, c;
    public A() : this(DefaultStrategy.Instance) {}
    protected A(ISomeMethodStrategy strategy){
        this.strategy = strategy;
    }
    public void SomeMethod() {
        a = strategy.SomeMethod(b, c);
    }
}

class Aa : A {
    public Aa() : base(DifferentStrategy.Instance) {}
}

Я реализовал шаблон с помощью интерфейса, но вы можете сделать то же самое с делегатами.

2 голосов
/ 09 июля 2009

A). было бы лучше, если бы вы опубликовали свою реализацию независимо от того, думаете ли вы, что она что-то искажает

В). концепция наличия class A и общей формы class A<T> кажется действительно инопланетянином. Это похоже на то, что ваш обобщенный класс имеет исключение для одного конкретного случая, что означает, что он менее универсален, чем другие обобщенные элементы, то есть wierd.

С). Почему бы вам просто не иметь все 4 базовых класса наследовать от более высокого класса X, если вы хотите буквально иметь один и тот же метод на каждом, или от интерфейса, если вы просто хотите, чтобы они реализовали этот общий метод. Кажется слишком очевидным, я что-то упустил в вашем вопросе?

1 голос
/ 09 июля 2009

А как насчет интерфейсов и композиции вместо наследования?

например, вы создаете новый интерфейс

interface myinterface
{
   void doSomethingCool();
}

чем новый класс, который его реализует

class interfaceImpl: myinterface
{
    public void doSomethingCool()
    {
         ... some code
    }
}

чем с

class A : myinterface
{
  private interfaceImpl interf = MyInterfaceFactory.Build(args);

  public void doSomethingCool()
  {
      interf.doSomethingCool();
  }
}

так что вы можете иметь такое же поведение в классе A, B и всех производных классах, а также можете переопределить его.

НТН

0 голосов
/ 09 июля 2009

Вопрос действительно в том, как сделать встраивание в C #.

Вы можете использовать кувалду и принять что-то вроде LinFu ; Существуют и другие подходы, которые включают открытие базовых определений для добавления дополнительных общих параметров (объект ввода). Все они связаны с обдуманным выбором языкового дизайна.

0 голосов
/ 09 июля 2009

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

Следовательно, вы можете создать один исходный базовый класс.

public class Origin {
   public virtual void SomeSharedOverrideMethod(int data) { }
}

class A : Origin {

   public void MethodForAImpl() {
       base.SomeSharedOverrideMethod(23);
   }
}

class A<T> : Origin {

   public void MethodForGenericAImpl() {
       base.SomeSharedOverrideMethod(45);
   }
}

class B : Origin
class B<T> : Origin

Это то, что вам нужно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...