Managed World

Techno-babble from yet another babbler RSS 2.0
# Saturday, June 14, 2008

One realization I have come to when talking with many other developers is that there is a good number of developers that don't realize that inheritance introduces dependencies directly into your classes. Your derived class is now dependant upon the interface and behavior of your base class. Worded another way, your derived class is now strongly coupled to your base class. I've met a number of developers that are very passionate about managing their dependencies via inversion of control, dependency injection, etc. and yet they implement solutions that have a class hierarchy 5+ layers deep.

This strong coupling can become problematic if you need to change either the interface or behavior of my base class. For instance, if I need to add another abstract method I didn't originally think of, every single class that derives from that base class now must change in order to implement that behavior. Or, if I change the behavior of one of the methods in my base class, I can find myself in a situation where one of my derived classes will break because they were relying on that base class behavior to act a given way (even more confusing when the change doesn't impact any other of the derived classes).

Over-using (read: abusing) inheritance in your code can very easily lead to brittle classes that prevent you from being as agile as you need to be. While it is easy for developers to look at dependencies as other external classes your class is dependant upon, you have to keep in mind that your class is also strongly dependant on its base class as well.

The beautiful thing is that with some of the functionality introduced into .NET in both 2.0 and 3.5, you can avoid developing these brittle classes by using Generic programming.

"Generic programming is a style of computer programming in which algorithms are written in terms of to-be-specified-later types that are then instantiated when needed for specific types provided as parameters. This permits writing common functions or types that differ only in the set of types on which they operate when used, thus reducing duplication."

I know this description can be a bit confusing at first. Let's learn about Generic programming by example. And as an example, let's take a look at possible implementations of the Command pattern.

"In object-oriented programming, the Command pattern is a design pattern in which objects are used to represent actions. A command object encapsulates an action and its parameters."

In these examples, we are going to look at a home automation system. Specifically, let's look at the code it takes to automate lights using the Command pattern. In order to do this, we of course need a Light that we are actually automating (automation code removed for readability purposes):

    class Light
    {
        public void TurnOn()
        {
            Console.WriteLine("Light Turned On");
        }

        public void TurnOff()
        {
            Console.WriteLine("Light Turned Off");
        }
    }

So, let's dive right in.

In the "typical" way of implementing the Command pattern, you have an abstract base class Command that your detailed commands inherit from, overriding a virtual method to actually execute the command (this could also be an interface ICommand as well, instead of an abstract base class).

    abstract class Command
    {
        public abstract void Execute();
    }

    class LightOnCommand : Command
    {
        private Light _light;

        public LightOnCommand(Light theLight)
        {
            _light = theLight;
        }

        public override void Execute()
        {
            _light.TurnOn();
        }
    }

    class LightOffCommand : Command
    {
        private Light _light;

        public LightOffCommand(Light theLight)
        {
            _light = theLight;
        }

        public override void Execute()
        {
            _light.TurnOff();
        }
    }

Let's take another look at that definition of the Command pattern: "the Command pattern is a design pattern in which objects are used to represent actions". In our case, each action (turning a light on, turning a light off) is represented by an object (LightOnCommand, LightOffCommand).

Now to use these classes, all we need to do is instantiate new instances of our two commands (LightOnCommand and LightOffCommand) and execute them. Pretty simple. And because of leveraging a common base class, we can use polymorphism to reuse this code even more (like having a list of commands that we can execute in a script or elsewhere).

            var livingRoomLight = new Light();
            var lightOn = new LightOnCommand(livingRoomLight);
            var lightOff = new LightOffCommand(livingRoomLight);

            lightOn.Execute();
            lightOff.Execute();

This classic approach doesn't come without it's drawbacks though. First of all, for every home device that we wish to turn on and off, we would be introducing two new classes into our code. While this may not be that bad for a couple of devices, it can quickly get out of hand when the number of devices start to grow.

Also, the "common behavior" we get out of our base class isn't very flexible. If we change our Execute() method in our base class from abstract to virtual in order to introduce common behavior, how do you guarantee that the base method is called when it should be? In a derived class, should you call the base method before your own execution code, or after? What if I want common code in my base class that will be executed both before and after the behavior in my derived classes? While .NET has ways of achieving this, it quickly becomes complex and just introduces more code that obfuscates what the true purpose of our code is.

Not as flexible as we first though, eh?

So what has .NET done lately to make this job easier? Well, with the introduction of Generics and Lambdas, we can do a form of Generic programming that helps us write "one Command class to rule them all." By writing more generic code, you get down to the essence of what your code needs to do, and allows you to write code that is more flexible and not as dependant on other classes as before (since we are not directly leveraging inheritance like we were before).

What might a generic solution to the Command pattern look like?

    class GenericCommand<TReceiver>
    {
        private TReceiver _receiver;
        private Action<TReceiver> _commandToExecute;

        public GenericCommand(TReceiver theReceiver, Action<TReceiver> theCommandToExecute)
        {
            _receiver = theReceiver;
            _commandToExecute = theCommandToExecute;
        }

        public void Execute()
        {
            _commandToExecute(_receiver);
        }
    }

Let's look back at that description for Generic programming: "This permits writing common functions or types that differ only in the set of types on which they operate when used, thus reducing duplication." That's all we are doing here. We have written a common type in which only the types on which it operates differs when used.

When we use this generic type is when we actually dictate what type it operates upon. In the case of our home automation system, we are going to create an instance of our GenericCommand that operates on a Light fixture. Then, we will specify what action needs to be taken when the command is execute by leveraging lambda expressions:

            var livingRoomLight = new Light();

            var genericLightOn = new GenericCommand<Light>(livingRoomLight, theLight => theLight.TurnOn());
            var genericLightOff = new GenericCommand<Light>(livingRoomLight, theLight => theLight.TurnOff());

Pretty simple, for our light on command we turn the light on, and for our light off command we turn the light off. And in both cases, we are using the exact same common type (GenericCommand<TReceiver>) when declaring our command.

Now let's say we want to start automating our Garage as well. The class we might be given to do this automating might look like the following (with all the automation code removed again):

    class Garage
    {
        public void TurnLightOn()
        {
            Console.WriteLine("Garage Light Turned On");
        }

        public void TurnLightOff()
        {
            Console.WriteLine("Garage Light Turned Off");
        }

        public void OpenDoor()
        {
            Console.WriteLine("Garage Door Opened");
        }

        public void CloseDoor()
        {
            Console.WriteLine("Garage Door Closed");
        }
    }

Using the prior inheritance-based way, we would need to introduce two more command classes for this new Garage automation. And as stated before, when having to introduce two more command classes for every new piece of home automation, we quickly have a blow-up in the number of classes we have to maintain. However, using the generic programming-based approach that leverages Generics and Lambdas, we actually don't have to introduce any new classes as our meta-class GenericCommand<T> can handle those situations already. 

Here's how we might consume the new Garage with our GenericCommand<T>:

            var genericOpenGarage = new GenericCommand<Garage>(myGarage, theGarage => 
            { 
                theGarage.TurnLightOn(); 
                theGarage.OpenDoor(); 
            });
            var genericCloseGarage = new GenericCommand<Garage>(myGarage, theGarage => 
            { 
                theGarage.CloseDoor(); 
                theGarage.TurnLightOff(); 
            });

            genericOpenGarage.Execute();
            genericCloseGarage.Execute();

Very simple. Once again, we are using the exact same type (GenericCommand<TReceiver>) to implement the automation commands for our Garage as we were using with our Light. So, the same common type that, when used, only differs by the types it operates on. Which is exactly the definition of Generic programming we discussed before. It's not as scary as it sounds!

Now if we need to introduce logging or any other common functionality into our command class, we can introduce it in one place and have it applied to all our consuming code. Unlike the polymorphic approach outlined above, we now have the flexibility in this approach to execute any common code in relation to our command, whenever we want, however we want. It doesn't matter if that common code is before, or after, or before and after.

If you are still reading this (in which case I thank you), you should realize that you are already familiar with a pattern used to achieve parallelism in the new Parallel Extensions to the .NET Framework CTP that has been released. The programming model used when dealing with Tasks and Futures are essentially the exact same thing as the generic command pattern used above. So if you grok the GenericCommand above, you'll settle right into using Tasks and Futures within the Parallel Extensions.

In closing, by using a Generic programming approach when implementing our Command pattern, we now have just the base functionality that is absolutely needed to implement our commands. And, we avoid the explosion in the number of classes and dependencies that taking an inheritance-based approach would introduce, all made possible by the introduction of Generics (in 2.0) and Lambdas (in 3.5) in .NET.

I hope you enjoyed this walk down the "applying generics and lambdas" road. Until next time, Happy Coding!

Posted in C# | Programming
 #       Comments [19]
Saturday, June 14, 2008 6:48:07 PM (Pacific Standard Time, UTC-08:00)
The problem with this approach is that you lose the encapsulation of the types.
If I want to turn the light on in two places, I now need to share an instance, or duplicate the code (using a factory degenerate into a command pattern).
Saturday, June 14, 2008 7:58:41 PM (Pacific Standard Time, UTC-08:00)
Hey Oren! It's great to have you here.

When you talk about the loss of encapsulation, are you talking about the new approach w/ generics, or the classic approach with inheritance?

My personal opinion is that if there is enough logic that encapsulation is very important, the command pattern may not be the best match. I don't think the command objects themselves have anything that needs to be encapsulated. In this case, they don't have any private state they need to protect, and their simply a set of public operations exposed by another type.

On the other hand, the light is fully encapsulated. And all the command objects are doing are issuing statements that you can already execute directly against the light itself. I would consider commands very lightweight wrappers around existing operations.

Thoughts? I know you have a rebuttal :P.
Saturday, June 14, 2008 8:12:39 PM (Pacific Standard Time, UTC-08:00)
I am referring to your method.
My main objection is that I am using commands quite often, and they can get fairly complex.

Case in point:
https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/experiments/NMemcached/NMemcached/Commands/Storage/DeleteCommand.cs

Commands are not always resolving to a single method call, they are often orchestrating interactions, dealing with multiple objects, etc.
Saturday, June 14, 2008 8:25:25 PM (Pacific Standard Time, UTC-08:00)
I see. Yes, in the example DeleteCommand that you linked to, I would certainly agree with you. You would not want to use the approach I talked about as that would be a lot of code to have in the declaration of the command itself.

But, to be honest, this post was definitely not directed towards you or other developers of your caliber. You know about generics and lambdas and how to use them. You also know about the implications of having dependencies in your inheritance chain, and determining whether you can handle those dependencies or not.

This post was aimed at developers who are't aware of how you might use generics and lambdas, and what problems you might have when you have "inheritance-run-awry". And the Command Pattern was simply used as an example in which to talk about generic programming (not to say you should always use the generic approach over the inheritance approach). Though perhaps I should have talked about the drawbacks of the generic approach to make it more level-headed.

Just out of curiosity, with the business logic you have within your Delete command, do you think something like a transaction script would have been more applicable than the command pattern?
Sunday, June 15, 2008 7:26:41 AM (Pacific Standard Time, UTC-08:00)
Excellent article! I was thinking how to create a flexible sripting system and this is the way I will follow. Thanks.

"If I want to turn the light on in two places, I now need to share an instance, or duplicate the code (using a factory degenerate into a command pattern)."

Maybe this can be extended/combined with extension methods ... just thinking loud ;)
Sunday, June 15, 2008 12:55:02 PM (Pacific Standard Time, UTC-08:00)
Thanks Jason! I was writing some code on Friday and I wanted to so something like this but I couldn't quite put my finger on how to do it. You've made Monday much more productive for me! Whoohoo!
Sunday, June 15, 2008 2:21:51 PM (Pacific Standard Time, UTC-08:00)
Great to hear Pete and Andrew!! I'm glad the post helped. Happy coding :).
Monday, June 23, 2008 1:19:05 PM (Pacific Standard Time, UTC-08:00)
Great article!
Very clear and easy to read
Tuesday, July 08, 2008 10:04:28 PM (Pacific Standard Time, UTC-08:00)
I don't get it. Why exactly is this preferrable to a simple anonymous delegate with a capture variable?

e.g.:

Action openCommand = (Action)delegate { theGarage->TurnOnLight(); theGarageDoor->OpenDoor(); }

ed_r
Thursday, July 10, 2008 12:15:06 PM (Pacific Standard Time, UTC-08:00)
Hi, very good article. I was to delighted, when I discovered generic approach to this kind of problem. I my case, I was using generic interfaces but concept is the same, and have many advantages, but one of the main drawback in my opinion is composition of generic elements in classes, because you have to know generic type.

For example, if I have interface:

public interface ISomeActions<T>
{
void Action1(T t);
T Action2();
}

when I want to use that interface from some class, I must know exact type that I want to use:

class SomeClass
{
//ISomeActions iSomeActions; //compile error
//ISomeActions<int> iSomeActions; //valid code
}

so I cant' decide which type of my ISomeAction interface will be in a runtime

cheers
Monday, July 14, 2008 1:00:10 PM (Pacific Standard Time, UTC-08:00)
Nice one. Presentation is very simple.
KOTESWARA RAO KOMMINENI
Monday, July 21, 2008 3:00:02 PM (Pacific Standard Time, UTC-08:00)
Nice article. Already added it to me repertoire! A few comments:
For those who want to link the old with the new, you could just have this support the Command interface (or abstract base class. Then you could combine the two (strongly typed with lambda expressions or Action delegates and possibly complex inherited classes).
Two drawbacks (or features):
1) The expressions are limited to either public or internal interfaces (a good feature).
2) A lot of times we want the commands to work on a wide variety of objects (lights, TV's, radios, etc.), the generics are useful for strong type support and makes general commands a little more combersome with type reflection. Actually, I forget how generics work. Can I have a IList<GenericCommand<object>> and add a GenericCommand<string>?

In any case, as you mentioned the Command pattern was not really the point, the point was to consider delegates and generics where you typically might have done an inheritance hierarchy.

Roger
Monday, July 21, 2008 3:06:37 PM (Pacific Standard Time, UTC-08:00)
BTW. I did want to mention on ed_r's comment.
From ed_r:
> Action openCommand = (Action)delegate { theGarage->TurnOnLight(); theGarageDoor->OpenDoor(); }

The class encapsulates both the action and the instance the action should be applied to. You still need to pass a garageDoor instance to the openCommand.
Thursday, July 24, 2008 5:41:44 PM (Pacific Standard Time, UTC-08:00)
Jason, I think that there is principle lurking beneath the surface of your example, and Ayende's comment.

Finding it hard to put my finger on it, but I think it has to do with cohesion.

The two options that come up in these situations are to specialise by inheriting (LightOnCommand) vs. parameterising (GenericCommand(cmd)).

In many cases, creating a concrete subclass to specialise something is the right thing to do.

But the reason we do this is to give that specialisation a name, so that it can be referred to in disparate parts of the code without passing instances around.

Passing instances around is annoying when the places where the instance is required are not closely related.

I.e. if the cohesion is high, passing instances around is probably not an issue. If passing instances around is an issue, this might (sometimes) be an indicator that cohesion is too low....

Just an embryonic idea - :) enjoyed the article.
Wednesday, July 30, 2008 4:54:53 AM (Pacific Standard Time, UTC-08:00)
Can you tell me how you would do this using your generic version of Command:

class Command_Handler
{
private SortedList commands = new SortedList();

public Command_Handler()
{
}

public void Add(Command a_command)
{
commands.Add(a_command,a_command);
}

public void Do_The_Lot()
{
foreach (Command c in commands)
{
c.Execute();
}
}
}

Cheers

Richard
richard develyn
Wednesday, July 30, 2008 5:29:41 AM (Pacific Standard Time, UTC-08:00)
(sorry - the foreach statement should be for commands.Values (or Keys) - but you know what I'm getting at)

Richard
richard develyn
Wednesday, July 30, 2008 9:33:25 AM (Pacific Standard Time, UTC-08:00)
Hey Richard, great example. Your example shows where the Generics approach falls down. If you need to have a collection of base Commands, there is no easy way to do that since generic types do not support covariance and contravariance today. Meaning, in the case of Animal, and Dog deriving from Animal, there is no way to assign a MyGenericType<Dog> to an instance of MyGenericType<Animal>. Eric Lippert has a whole set of blog posts on this topic on his blog.

So, in a future version of C#, this should hopefully be possible since variance will allow us to assign MyGenericType<Dog> to an instance of MyGenericType<Animal> (in given situations). But that of course doesn't help you today.

The point of the post was merely to encourage people to "think outside the box" and realize that inheritance isn't the answer to every problem. I've seen way too many developers problem-solving in an OOP language where they _always_ gravitate towards inheritance.

Thanks for the comment!
Wednesday, July 30, 2008 9:35:01 AM (Pacific Standard Time, UTC-08:00)
I should clarify. In this future version in C#, it would hopefully be possible to create an interface in this scenario called ICommandable that all command-able objects implement. Then the base collection of GenericCommands you want could be a collection of GenericCommand<ICommandable>.
Thursday, July 31, 2008 1:02:29 AM (Pacific Standard Time, UTC-08:00)
I thought you chose a bit of a funny example, since the Command pattern (IMVHO) is all about implementing Command stacks for things like "Undo" and "Redo".

And it isn't just for collections of base classes where you trip up. I couldn't even implement a one level "undo" feature by declaring:

public GenericCommand<TReceiver> last_command;

- somewhere, and then calling last_command.Execute() when someone hits "undo".

Richard
richard develyn
Comments are closed.

Contact

Email Me Send mail to the author(s)

Calendar

<September 2008>
SunMonTueWedThuFriSat
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

About this site

Jason Olson's thoughts on Programming, Games, Music and Life in General

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2008
Jason Olson

Sign In
All Content © 2008, Jason Olson
Theme based on 'Business' created by Christoph De Baene (delarou)