views:

199

answers:

3

I have a simple class library (COM+ service) written in C# to consume 5 web services: Add, Minus, Divide, Multiply and Compare.

I've created the abstract product and abstract factory classes. The abstract product named WS's code:

public abstract class WS
{

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

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

As you see, when one of the subclasses inherits WS, both methods must be overridden which might not be useful in some subclasses. E.g. Compare doesn't need Calculate() method.

To instantiate a new CompareWS object, the client class will call the CreateWS() method which returns a WS object type.

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

But if Compare() is not defined in WS, the Compare() method cannot be invoked. It's because the client will make use of WS type object, not CompareWS object.

This is only an example with two methods, but what if there are more methods? Is it stupid to define all the methods as abstract in the WS class?

My question is: I want to define abstract methods that are common to all subclasses of WS whereas when the factory creates a WS object type, all the methods of the subclasses can be invoked (overridden methods of WS and also the methods in subclasses). How should I do this?

A: 

You can declare all methods that are common to all subclasses in the WS class, but you should declare abstract only those methods whos implementation will be changed in the derived classes. It does not make sence to make Compare method as astract. Why do you say that such method cannot be called?

You can always have abstract and non abstract methods in one class and it looks like your Compare method just don't need to be abstract.

Andrew Bezzub
I see. I mentioned Compare() method cannot be called only if it's not existed in WS but only it's in CompareWS (subclass of WS) since the Concrete Factory will only create an object of type WS, not CompareWS. i.e. WS compareWS = CompareFactory.CreateWS(); In this case, calling compareWS.Compare() doesn't work.
Regina Foo
A: 

Regina, abstract classes can define both abstract and virtual methods. Virtual methods will contain some default implementation in the base class, but can be overriden by derived classes as needed:

    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
    }
}  
Miguel Sevilla
A: 

If you class inherits from abstract class and does not provide body for all abstract methods, then that class becomes abstract as well. One solution to this problem is to use interfaces, instead of classes!

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) {...}
}
0xDEAD BEEF
Can this way be applied to Factory/Abstract Factory Method design pattern? I mean, will this violent the design pattern?
Regina Foo