Showing posts with label design patterns. Show all posts
Showing posts with label design patterns. Show all posts

Wednesday, January 14, 2009

Interfacing Outside the Box

Happy New Year, everyone! Another hiatus is over and I hope to make it the last one. I've never been the one for New Year's resolutions before, but I guess there's a first time for everything: this year I resolve to post at least once a month.

I gave my self a head start by accumulating a number of topics I want to write about. After some careful consideration, I decided to start off with a bang: by introducing a new design pattern!

Hacking the Language

A while ago, I wrote about design patterns and how they're often a result of having to work your way around language limitations. No language is perfect, so you're bound to run into an annoying limitation sooner or later, even if you're not spending your days coding in Blub. If you're lucky, there's already a design pattern that allows you to hack your way around it. If not, you'll have to invent a solution yourself.

One of such limitations in C# is the boxing that occurs when you cast a value type to an interface. I've wrote about a related topic before, back when I was just learning about value types and boxing in C#. You could probably tell, because I made a spectacular mistake in my speculations.

Safe Deposit Box

In the course of devising a solution for the problem described in Enum Conundrum, I erroneously suggested that a possible solution might have been to have my enum implement the IEquatable interface, had the language allowed it. That, of course, wouldn't have helped. The enum would still have been boxed, although for a different reason.

Why do value types get boxed when cast to an interface? The reason is simple enough: for safety. For example, if you have a local value type variable, it resides on the stack and gets destroyed after the call ends. Without boxing, if you stored an interface reference to that value type instance in an object field, that field would wind up with an invalid reference as soon as the original call is done and the variable goes out of scope.

Of course, you might not care about boxing. After all, boxing was invented precisely so that people could use value types and reference types on equal footing: the alternative to it is all that nasty wrapping code that was so widespread in Java before it incorporated boxing. So boxing is neat, isn't it?

Get Back in Line

When you define a value type, you (should) do it for a good reason. Most of the time, it's because you need a type with value semantics; in other words, you want a type that behaves in such a way that it's not possible to affect one variable of that type by performing operations on another variable of the same type.

The way value semantics is enforced is through memory allocation. Value types are allocated in-line. This means that the memory allocated for a value type instance is a part of the memory allocated for whatever contains that instance. If it's a local variable, the instance is allocated directly on the stack. If it's a field, the instance is contained in the memory allocated for the field's object. Only when it gets boxed does a value type wind up on the heap independently, all by itself.

At times, this is precisely the reason why you'll choose a value type: not so much for its semantics, as for its memory allocation. For example, you might be writing a game in XNA and you don't want the garbage collector kicking in and ruining your frame rate.

Whatever your reasons for wanting to keep them in line, the fact remains that you cannot cast your value types to interface without them getting boxed. What, then, is the alternative?

Generic Static

Fun fact: a static field in a generic class is allocated separately for each closed constructed type of that generic class. What does this mean? Take a look at the following code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BeardsEye
{
    class GenericStatic<T>
    {
        public static int SomeVal;
    }

    class Program
    {
        static void Main(string[] args)
        {
               GenericStatic<int>.SomeVal = 1;
               GenericStatic<string>.SomeVal = 2;

               Console.WriteLine(GenericStatic<int>.SomeVal);
               Console.WriteLine(GenericStatic<string>.SomeVal);
        }
    }
}

If you run it, it will print out 1 and 2. Of course, such behavior stands to reason; if you're not sure why, just change the type of SomeVal to T.

Why am I suddenly talking about this, anyway? Because, in some cases, you can use this trick as a substitute for what would otherwise be a dictionary. Specifically, for some uses, you could replace a Dictionary<Type, Something> with:
public static class MyTypeDictionary<TType>
{
    public static Something Value;
}

Of course, this is a far cry from a fully functional dictionary. You don't have the Count property, there's no way to remove values, iterate over them or find out whether a type has an associated value or not. And you can't have an arbitrary number of these "dictionaries".

On the other hand, when you need to associate something with a type and that "something" changes from type to type, this technique is just perfect.

Fun With Functions

Now we finally get to the solution itself. Suppose you have an interface IConfusticatable, for all types that can be confusticated to a certain degree:
public interface IConfusticatable
{
    double Confusticate(int degree);
}

You want to be able to confusticate classes that implement this interface, but you would also like to confusticate value types, without boxing them. You could use the following trick:
public static class Confusticator<T>
{
    public static Func<T, int, double> Confusticate = ((what, degree) => ((IConfusticatable) what).Confusticate(degree));
}

What do you have to do in your value type? Not much:
public struct MyStruct
{
    static MyStruct()
    {
        Confusticator<MyStruct>.Confusticate = ((me, degree) => me.Confusticate(degree));
    }

    public MyStruct(double val)
    {
        Val = val;
    }

    public double Val;

    public double Confusticate(int degree)
    {
        return Val + degree;
    }
}

How do you use this when you want to confusticate something? Like this:
MyStruct myVar = new MyStruct(17);
Console.WriteLine(Confusticator<MyStruct>.Confusticate(myVar, 3));

I'm sure that, at this point, you're thinking "So what good is this? If I already know that myVar is a MyStruct, I can just call its own Confusticate method directly."

This, of course, is perfectly true, unless you're writing generic code. In that case you don't know beforehand what your type parameter will be.

Warning: May Contain .NUTS

A few words of caution here. The proposed implementation of MyStruct relies on a static constructor, which is supposed to "register" the confustication lambda with the Confusticator. The problem with this is that it's a bit tricky to make sure that a value type static constructor is invoked.

If you dig around the C# Annotated Standard, you'll find some fascinating incompatibilities between different standards and their respective implementations.

According to the C# Standard, a static constructor for a value type is executed only when the first of the following occurs:
  • An instance member of the struct is referenced.
  • A static member of the struct is referenced.
  • An explicitly declared constructor of the struct is called.
On the other hand, the CLI Standard requires execution only when the first of the following occurs:
  • A static member of the struct is referenced.
  • An explicitly declared constructor of the struct is called.
To further complicate the matters, the CLI Standard does not allow execution when an instance member of the struct is referenced. You'll note that this is in direct conflict with the C# Standard.

If you actually test what happens when you run a C# program on CLR, you'll see that the static constructor is called as soon as the first of the following occurs:
  • An instance method of the struct is referenced.
  • An instance property of the struct is referenced.
  • A static member of the struct is referenced.
  • An explicitly declared constructor of the struct is called.
However, the static constructor is not called if you reference an instance field of the struct. Not only does the CLR implementation fail to conform to either standard, it does so in a way that seems spectacularly arbitrary. I'm sure there are some perfectly valid -- if arcane and obscure -- reasons for this.

All in all, it would be a lot more reliable to stick the "registration" code in some initialization method that you know will be called. That's what you would have to do anyway, if you wanted to register a confustication function for an enum, for example.

Finishing Touches

What if your IConfusticatable interface has more than one method? There are several possible solutions, but the simplest one would be to give your Confusticator<T> one static delegate field per IConfusticatable method.

Speaking of Confusticator<T>, if you find it too ugly to write Confusticator<MyStruct>.Confusticate(myVar, 3), you can use type inference to introduce some syntactic sugar:
public static class Confusticator<T>
{
    public static Func<T, int, double> Confusticate = ((what, degree) => ((IConfusticatable) what).Confusticate(degree));
}

public static class Confusticator
{
    public static double Confusticate<T>(T what, int degree)
    {
        return Confusticator<T>.Confusticate(what, degree);
    }
}

With that, you would be able to simply write Confusticator.Confusticate(myVar, 3) and have the compiler infer the type automagically.

Share and Enjoy

Well, that's all for now. For those of you who have a legitimate need to avoid boxing your value types, I hope this proves useful. For the rest, I hope that you found this an interesting trick.

I'm planning to write more recipes for getting stuff that C# doesn't have, such as multiple dispatch, so stay tuned!

Friday, June 1, 2007

Dark Side of Design Patterns

Every now and then I overhear someone excitedly talking to someone else about Design Patterns. They're so excited about it, you can hear the capital D and capital P quite clearly. And they use that tone: you know, the one usually reserved for great sports achievements. And, invariably, I can't resist the temptation to get involved. Things usually go downhill from there.

I can understand their chagrin. How would you like it if you just discovered something cool only to have some spoilsport tell you that roughly half of it is crap? Yet I just can't keep quiet; partly because I'm mean and love seeing their reactions, but mostly because I'm sick of the hype.

Patternitis
"The whole problem with the world is that fools and fanatics are always so certain of themselves, but wiser people so full of doubts."
Bertrand Russell

Don't get me wrong, I think design patterns are a great idea. Hardly a new one, but great nevertheless. The problem is that every Great Idea attracts its share of fanatics who think it's the coolest thing since sliced bread. It gets paraded around as a Silver Bullet and a Golden Hammer until its limitations percolate through the layers of hype. Inevitably, the general hype dies down -- if we're talking about a genuine Great Idea, not glossyware stuff like SOA -- and all that's left are pockets of hype that form about enthusiastic newbies or incompetent know-it-alls.

I personally love stamping out those little pockets and that's what I want to do with this blog post. I'll start by asserting the following:
  1. If you think that developing software can be reduced to applying and combining design patterns, you are wrong.
  2. If you think that a design pattern you don't completely understand must nevertheless be good, you are wrong.
  3. If you think that design patterns are a new invention made possible by OOP, you are wrong.
  4. If you think that someone is a good programmer just because they know design patterns, you are wrong.
  5. If you think that you must know design patterns to be a good programmer, you are wrong.
Now that the most common misconceptions are out of our way, we can get to separating the wheat from the chaff.

Gold vs. Other Glittery Stuff
"Any man whose errors take ten years to correct is quite a man."
J. Robert Oppenheimer

What is a design pattern? The original book by Gamma, Helm, Johnson and Vlissides (popularly known as GoF) takes a page and a half to answer this question. I prefer a shorter and simpler answer, even if it lacks all the accuracy of the original. Wikipedia has pretty good definition:
In software engineering (or computer science), a design pattern is a general repeatable solution to a commonly occurring problem in software design. A design pattern is not a finished design that can be transformed directly into code. It is a description or template for how to solve a problem that can be used in many different situations. Object-oriented design patterns typically show relationships and interactions between classes or objects, without specifying the final application classes or objects that are involved. Algorithms are not thought of as design patterns, since they solve computational problems rather than design problems.
Still a bit long for my taste, but it's quite usable. As a matter of fact, the first sentence is the most important; the rest just helps cement the scope.

The GoF book defines 23 design patterns: 5 creational, 7 structural and 11 behavioral. It took me a lot of conscious effort and quite a few years of working experience to admit that not all of those patterns are gold. In fact, the wheat-to-chaff ratio is quite close to 50 percent: there are 12 that I could describe as "okay", "good" or "great" and 11 that I see as "hack", "poor" or even "rubbish".


The Good
"The remarkable thing about Shakespeare is that he really is very good, in spite of all the people who say he is very good."
Robert Graves

If I learned something from my previous managers, it's to always dangle the carrot before using the stick. Seriously, though, the original GoF book has some really good patterns in it.

Take Bridge, for example. The best thing about this pattern is that it teaches you about the separation of concerns. You can adapt it to classless object-oriented languages, you can even apply it in structural programming languages. The main point is to keep the implementation primitives separate from the operations that use them.

Builder is another example of a highly useful pattern. Just look at SAX: they provide the director and you have to write the builder. Highly efficient and very elegant. By the way, I really recommend reading the original GoF book if you want to understand this pattern. Some of the other books attempt to explain it by applying it to convoluted problems such as constructing a MIME message or building a user interface. A word of advice to the authors: KISS.

A few other great patterns include Command, Composite and Template Method. These really make the best out of OOP and it shows. These are all nice examples of taking advantage of the benefits of OOP.

Then there is a whole range of patterns that have been around for a long time, long before OOP and long before GoF invented design patterns as we know them: Adapter, Façade, Flyweight, Chain of Responsibility and Observer.

Finally, I reserve a special place for Mediator, not because it's better than the rest, but because it's a perfect example of a good pattern that can be horribly abused. One word: Delphi. The "RAD paradigm" promoted by Delphi is to add objects to their containers and then write all the logic in a few huge Mediator classes. Delphi is based on an object-oriented language, has an excellent core framework and class library and yet it teaches its users to forget OOP. Bottom line: no matter how cool the pattern, don't overdo it.

The Ugly
"Beauty is the first test; there is no permanent place in the world for ugly mathematics."
G.H. Hardy

We have all, at some point in our lives, had to choose the lesser of two evils. That's most likely what you will be doing when you decide to apply one of the following: Proxy, Memento, Visitor, Decorator or State. All of these are a cumbersome solution for something that should have been supported or aided by the language itself.

Proxy, for example, is a necessary and useful pattern. The problem with it is that a lot of the languages require you to implement it by writing tons of boilerplate code. With some good metaprogramming facilities, Proxy becomes trivial.

Likewise, the motivation behind Memento is valid, but it should be solved by the language or its core library. Serializing and deserializing objects should be trivial, which means you shouldn't have to write gobs of code to do it. Look at the way you do it in Java:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(oos);
try {
  oos.writeObject(originator);
  oos.close();
} catch (IOException e) {
  // won't happen but we _still_ 
  // have to write code to ignore it
}
byte[] memento = baos.toByteArray();
Now compare it to Ruby:
memento = Marshal.dump(originator)
I rest my case.

Visitor is another example of hacking your way around language limitations. Most of the object-oriented code anyone writes needs only single dispatch. You can argue that supporting double or multiple dispatch in the language is wasteful, although there are ways around that. But when your language leaves you with no other choice and you need double dispatch, you will have to use Visitor. If you happen to need multiple dispatch, good luck writing and maintaining that code.

Finally, we come to Decorator and State. Both of these patterns are useful and both deal with the same issue: sometimes we want to adapt the behavior of individual objects depending on their state or some other trait we want to manipulate during run time. I believe that it should be possible without writing all the boilerplate code that you need for Decorator and State. I've learned and experimented with Self and Io languages and they both allow you to solve these needs very elegantly. Again, look at a sample implementation of State pattern in Java:
public class Bot {
  
  private int health;
  private BotState state;
  
  protected void changeState(BotState newState) {
    state = newState;
  }
  
  protected static final BotState HEALTHY = new HealthyState();
  protected static final BotState INJURED = new InjuredState();
  
  protected abstract static class BotState {
    public void takeDamage(Bot bot, int damage) {
      bot.health -= damage;
    }
    
    public void heal(Bot bot, int delta) {
      bot.health += delta;
    }
    
    public void enemySpotted(Bot bot, Object enemy) {}
  }
  
  protected static class HealthyState extends BotState {
    public void takeDamage(Bot bot, int damage) {
      super.takeDamage(bot, damage);
      if (bot.health <= 40) {
        bot.changeState(INJURED);
      }
    }
    
    public void enemySpotted(Bot bot, Object enemy) {
      bot.chase(enemy);
    }
  }
  
  protected static class InjuredState extends BotState {
    public void heal(Bot bot, int delta) {
      super.heal(bot, delta);
      if (bot.health >= 50) {
        bot.changeState(HEALTHY);
      }
    }
    
    public void enemySpotted(Bot bot, Object enemy) {
      bot.avoid(enemy);
    }
  }
  
  public void chase(Object enemy) {
    System.out.print("Chasing " + enemy);
  }
  
  public void avoid(Object enemy) {
    System.out.print("Avoiding " + enemy);
  }
  
  public void takeDamage(int damage) {
    state.takeDamage(this, damage);
  }
  
  public void heal(int delta) {
    state.heal(this, delta);
  }
  
  public void enemySpotted(Object enemy) {
    state.enemySpotted(this, enemy);
  }
}
Now compare it with the same thing in Io:
Bot := Object clone do (
  init := method(self health := 100)
  chase := method(enemy, ("Chasing " .. enemy) println)
  avoid := method(enemy, ("Avoiding " .. enemy) println)
  takeDamage := method(damage, health = health - damage)
  heal := method(delta, health = health + delta)
  enemySpotted := method(enemy, nil)
  changeState := method(newState, self setProto(newState))
)

HealthyBot := Bot cloneWithoutInit do (
  takeDamage := method(damage,
    resend
    if (health <= 40, changeState(InjuredBot))
  )
  enemySpotted := method(enemy, chase(enemy))
)

InjuredBot := Bot cloneWithoutInit do (
  heal := method(delta,
    resend
    if (health >= 50, changeState(HealthyBot))
  )
  enemySpotted := method(enemy, avoid(enemy))
)
I would even settle for hard, specific syntax supported by the language itself, like in UnrealScript.

Bottom line? Our languages really need to evolve. Combine prototype-based OOP that you can find in Self and Io with excellent metaprogramming offered by Lisp and you will have a language that kicks ass and doesn't need ugly patterns.

The Bad
"There is no stigma attached to recognizing a bad decision in time to install a better one."
Laurence J. Peter

Thus we come to the place where the bad things dwell. There's a variety of patterns that fall into this group and they do so for diverse reasons. Let's start with a couple that gave me nightmares for a long while.

Factory Method sounds like a good idea. Upon close examination, Abstract Factory is revealed to be Factory Method applied to Factory Method, which makes it sound even better. Only those who have been fooled by this pattern can appreciate the despair and the subsequent numbness brought on by writing tons and tons of the boilerplate code required by it. The worst thing is that it seems to be the only solution. Until you find out about Dependency Injection. Try it and you'll see the difference.

Another pattern that really fouls things up is Singleton. For a long time I couldn't find one good reason why I should have a class with only one instance, instead of making all that code static. Then someone asked what I would do if I had to pass an interface to it. Okay, that justifies it, I can even think of examples other than boilerplate Abstract Factory code. Another valid point is that you might want to switch from one instance to a pool and you don't want to rewrite the bulk of your code. Then there is the case mentioned in the GoF book that talks about subclassing the singleton and creating a registry of singletons. If you think that things are getting out of hand, you're right. The solution is the same as above: use Dependency Injection.

Then there's Iterator pattern. That one should be easy: use the foreach statement. And if your language doesn't have it, ask for your time back. It's simply unacceptable to have to write reams of ugly code for something we use so often. It deserves its own syntax.

What about Strategy pattern? According to the GoF and to all subsequent authors, you should use it to encapsulate a family of algorithms and make them interchangeable. That's about one thing for which I would not use it. If you want to do that use functions. Again, if you don't have them, ask for your time back. On the other hand, you could use Strategy pattern when your implementation strategy has to maintain state over time. But then it's not really Strategy, is it? Slippery things, these patterns.

Finally, there's Interpreter. I don't have any beef with its motivation: just look at how things have been evolving and you'll see several examples of minilanguages, scripting languages and XML-based stuff, all getting interpreted in the normal course of execution of your code. From printf format string of olden to XML configuration files of today, the idea has been in use for a loooong time. Thing is, this isn't a design pattern. It doesn't fit into the scope of a design pattern. And you won't make it fit by sketching out your favorite implementation of an interpreter for your favorite minilanguage. It just does not belong.


Patternitis Revisited
"When people are free to do as they please, they usually imitate each other."
Eric Hoffer

I have to give it to GoF though, they had some great ideas and the only time their scope slipped was with the Interpreter pattern. Sadly, the same couldn't be said about the later authors. I'll say it out loud: interface is not a design pattern. There are many things you could say about an interface. From a conceptual point of view, it's the definition of the contract your code will have to satisfy. From a language-specific point of view, it's a syntactic and semantic construct. But it is definitely not a design pattern. Neither is a symbolic constant name or an accessor method name.

It might seem that I'm beating a dead horse here, but I want to make it absolutely clear that not everything in software development is a design pattern. It's too easy to lose focus in enthusiasm, so do yourself a favor: learn the design patterns, keep using the ones you like (where applicable) and move on. There's a lot more to do.