Абстрактные методы в продукте — фабричный метод C#

У меня есть простая библиотека классов (служба COM+), написанная на C# для использования 5 веб-служб: «Добавить», «Минус», «Разделить», «Умножить» и «Сравнить».

Я создал классы абстрактного продукта и абстрактной фабрики. Абстрактный продукт с именем WS code:

public abstract class WS
{

    public abstract double Calculate(double a, double b);

    public abstract string Compare(double a, double b);
}  

Как видите, когда один из подклассов наследует WS, оба метода должны быть переопределены, что может оказаться бесполезным в некоторых подклассах. Например. Compare не нуждается в методе Calculate().

Чтобы создать экземпляр нового объекта CompareWS, клиентский класс вызовет метод CreateWS(), который возвращает тип объекта WS.

public class CompareWSFactory : WSFactory
{
    public override WS CreateWS()
    {
        return new CompareWS();
    }
}

Но если Compare() не определено в WS, метод Compare() не может быть вызван. Это потому, что клиент будет использовать объект типа WS, а не объект CompareWS.

Это только пример с двумя методами, но что, если методов больше? Глупо ли определять все методы как абстрактные в классе WS?

Мой вопрос: я хочу определить абстрактные методы, общие для всех подклассов WS, тогда как, когда фабрика создает тип объекта WS, могут быть вызваны все методы подклассов (переопределенные методы WS, а также методы в подклассах). Как мне это сделать?


person Bally    schedule 15.03.2010    source источник
comment
Спасибо за ваш комментарий. Позвольте мне немного изменить мою проблему. Абстрактные методы, которые должны быть определены в классе WS, — это Add(), Minus(), Divide(), Multiply() и Compare(). Так что нецелесообразно писать интерфейс для каждого метода, верно? Конечно, это всего лишь пример.   -  person Bally    schedule 15.03.2010


Ответы (3)


Regina, абстрактные классы могут определять как абстрактные, так и виртуальные методы. Виртуальные методы будут содержать некоторую реализацию по умолчанию в базовом классе, но при необходимости могут быть переопределены производными классами:

    public abstract class WS
{

    // All derived classes will have to implement this
    public abstract double Calculate(double a, double b);

    // This can be overriden by derived classes (since it's a virtual method)
    public virtual string Compare(double a, double b)
    {
        // Some default implementation.
        // Any derived classes can override this implementation if they want
    }
}  
person Miguel Sevilla    schedule 15.03.2010

Вы можете объявить все методы, которые являются общими для всех подклассов в классе WS, но вы должны объявить абстрактными только те методы, реализация которых будет изменена в производных классах. Делать Compare метод astract не имеет смысла. Почему вы говорите, что такой метод нельзя вызвать?

Вы всегда можете иметь абстрактные и не абстрактные методы в одном классе, и похоже, что ваш метод Compare просто не должен быть абстрактным.

person Andrew Bezzub    schedule 15.03.2010
comment
Я понимаю. Я упомянул, что метод Compare() нельзя вызывать только в том случае, если он не существует в WS, а только в CompareWS (подкласс WS), поскольку Concrete Factory будет создавать только объект типа WS, а не CompareWS. т. е. WS compareWS = CompareFactory.CreateWS(); В этом случае вызов compareWS.Compare() не работает. - person Bally; 15.03.2010

Если ваш класс наследуется от абстрактного класса и не предоставляет тело для всех абстрактных методов, то этот класс также становится абстрактным. Одним из решений этой проблемы является использование интерфейсов вместо классов!

interface ICalculate
{
   double Calculate(double a, double b);
}
interface ICompare
{
   string Compare(double a, double b);
}
class Compare : ICompare
{
   public double ICompare.Compare(double a, double b) { .... }
}
class CompareAndCalculate : ICompare, ICalculate
{
   public string ICompare.Compare(double a, double b) { .... }
   public double ICalculate.Calculate(double a, double b) {...}
}
person 0xDEAD BEEF    schedule 15.03.2010
comment
Можно ли применить этот способ к шаблону проектирования Factory/Abstract Factory Method? Я имею в виду, будет ли это насильственным шаблоном проектирования? - person Bally; 15.03.2010