views:

58

answers:

3

Hello, is it possibly in c# to have some sort of base class functionality which is manipulated slightly based on the class. For instance say i have the following code (which will quite obviously not compile it's meant to only be for demonstrative purposes)

class BaseFunctionality
{
    public virtual bool adminCall
    public static string MethodName(int id, string parameter)
    { 
        if (adminCall)
            return dbcall.Execute();
        else
            return dbcall.ExecuteMe();
    }
}
class Admin : BaseFunctionality
{
    override bool adminCall = true;
}
class Front : BaseFunctionality
{
    override bool adminCall = false;
}

Now what i would like to be able to do is;

string AdminCall = Admin.MethodName(1, "foo");
string FrontCall = Front.MethodName(2, "bar");

Is their any way to do something like this? I'm trying to do everything with static methods so i do not have to instantiate classes all the time, and have nice clean code which is only being manipulated in one place.

The idea behind this is so that there is minimal code repeating and makes things easier to expand on, so for instance another class could implement the BaseFunctionality later on.

Thanks
Dan

A: 

What you're trying to do seems to fall cleanly into the pattern of classes and inheritance. You have your BaseFunctionality general super-class and two more specific sub-classes. You're using the adminCall boolean flag to distinguish the two, but better design would be to have two different implementations of MethodName in two specific sub-class.

This way you can have as many slightly-modified versions of MethodName as you need (one per sub-class), and can simply call obj.MethodName(string) on any 'obj' that is an instance of BaseFunctionality or any sub-class.

tehblanx
+3  A: 

Your desire to use static methods is getting in the way of using inheritance properly. The base class in your example knows how to implement the functionality of the two sub-classes. A cleaner way of coding this would be:

    abstract class BaseFunctionality
    {
        public abstract string MethodName(int id, string parameter);
    }

    class Admin : BaseFunctionality
    {
        public override string MethodName(int id, string parameter)
        {
            return "dbcall.Execute()";
        }                        
    }

    class Front : BaseFunctionality
    {
        public override string MethodName(int id, string parameter)
        {
            return "dbcall.ExecuteMe()";
        }
    }

you can then create other static methods or use singletons to access these methods if you must have static access. e.g.:

string AdminCall = Admin.Instance.MethodName(1, "foo");
Mark Heath
Thanks Mark, this is similar to something I already had.I have a question though regarding instantiation and static accessors. If i left your code as-is, obviously i would have to call the the methods via instantiation, so string s = new Admin().MethodName(3,"");So using static methods and creating a singleton pattern (which i have done), is it more benefical using the singleton pattern than constantantly instantiating Admin each time to call a method (this was my reasoning for wanting things in a static method / singleton pattern.)
danrichardson
Hi Dan, it's hard to give a definite answer without knowing more about what your system does. If there are several places in your code that need to call into this function, all scattered throughout different files, then you ought to consider having an interface that is passed around as a dependency. Using static methods/singletons is fine so long as you recognise that everyone that uses them is now tightly coupled to that concrete class, often making your code less testable.
Mark Heath
I have created a couple of cms systems so obviously there is a managament area and then a front-end/consuming end. So a real work example is members functionality. Some functionality is shared (get info, update info, change email etc..) with very slight difference - for example the management side would allow for a member type to be changed whereas a consumer would not be able to during info update.This means that 90% of the time code is the same (database calls, class instantiations/populating, reading database columns names) so i suppose an interface or and abstract base class could work?
danrichardson
+4  A: 

Sure you can do this. It is called Template Pattern.

However, "trying to do everything in static methods" will ruin you quickly. For one thing, you can't override a static method in an inheritor. Instantiating and using objects is what object-oriented programming is all about. Creating instances is exactly what allows you to reduce code duplication -- you still only manipulate code in one place, but that code can do lots of different things and be in different states at runtime.

Also, instead of using the adminCall flag in the base class, override the method to do the different behaviour, and factor the common functionality into other methods (this is where the protected modifier comes into play).

For example:

public abstract class BaseFunctionality
{
    public abstract string methodName(int id, string parameter);

    protected ThingClass createThing(int id, string parameter)
    {
        // instantiate and return result
    }

    protected bool isValidId(int id)
    {
        // evaluate validity of id
    }
}

public class Admin : BaseFunctionality
{
    public override string methodName(int id, string parameter)
    {
        if(!isValidId(id)) return string.Empty;
        var thing = createThing(id, parameter);
        thing.Execute();
    }
}

public class Front : BaseFunctionality
{
    public override string methodName(int id, string parameter)
    {
        if(!isValidId(id)) return null;
        Console.WriteLine(parameter);
    }
}

By avoiding the if…then stuff in the base class, you can have any number of inheritors that do any number of different things in the methodName method without having to make any changes to BaseFunctionality class (which, incidentally, refers to the open-closed principle -- that your classes are open to extension -- you can make them do some new things -- but closed to modification -- you don't actually go in and make any changes to the code of that class).

Jay