Thursday 24 February 2011

Polymorphism, really... what's that...? omg you need a slap in the face!

Well it begins...
Before I start I have to admit I am also guilty of this but it needs to come out.

Why the hell do I have to see code with 4 million if and switch statements, especially when its switching or if'ing on an enum called <some name>Type and of course to get me more mad, yes its in the base class too, what a genius, what the hell are you doing!

Yes that's right, it even has the postfix of "Type", surely that has to give some kind of clue, that hmmmm, maybe this enum your switching on, shouldn't be there, and yes you can do it without having to switch, that's what polymorphism helps with, let me try to demonstrate...

Its not a superb example, but its the first thing I could think of, hopefully I can change it to something better when I can think of something, but for now I am hoping I can get some of the point of polymorphism across.

not so nice way...
    8     public enum CarType
    9     {
   10         Ferrari,
   11         MorrisMinor,
   12         SomethingElse
   13     }
   14 
   15     public class Car
   16     {
   17         public CarType CarType { get; set; }
   18 
   19         public void StartCar()
   20         {
   21             switch (CarType)
   22             {
   23                 case CarType.Ferrari:
   24                     //Car Senses key fob.
   25                     //Car starts.
   26                     break;
   27 
   28                 case CarType.MorrisMinor:
   29                     //Key fob turned.
   30                     //Car starts.
   31                     break;
   32 
   33                 case CarType.SomethingElse:
   34                     //Some random stuff to get this car to start
   35                     break;
   36 
   37                 default:
   38                     //Do some default stuff to start all other cars.
   39                     break;
   40             }
   41         }
   42     }
   43 
   44     public class Ferrari : Car
   45     {
   46         public Ferrari()
   47         {
   48             CarType = CarType.Ferrari;
   49         }
   50     }
   51 
   52     public class MorrisMinor : Car
   53     {
   54         public MorrisMinor()
   55         {
   56             CarType = CarType.MorrisMinor;
   57         }
   58 
   59     }
   60 
   61     public class SomethingElse : Car
   62     {
   63         public SomethingElse()
   64         {
   65             CarType = CarType.SomethingElse;
   66         }
   67 
   68     }
   70 
   71     //Some code somehwere to start the car you have.
   72     var ferrari = new Ferrari();
   73     var morrisMinor = new MorrisMinor();
   74     var somethingElse = new SomethingElse();
   75     ferrari.StartCar();
   76     morrisMinor.StartCar();
   77     somethingElse.StartCar();

So this has the 3 types of cars, and they all should start in a different way. When you create an instance of these cars and call StartCar they all call the same method, which then switches on some dodgy enum to distinguish the types, pffff.

OK it works but a car doesn't need to ask itself if its a ferrari, or a morris minor. What happens if a new car comes out does that mean all the other cars then need to be upgraded to then ask itself if its the new car on the market? Therefore, increasing the switch/if statement every time. Sounds like that could be a nightmare to me.

a nicer way...

    8     public class Car
    9     {
   10         public virtual void StartCar()
   11         {
   12             //Do some default stuff to start all other cars.
   13         }
   14     }
   15 
   16     public class Ferrari : Car
   17     {
   18         public override void StartCar()
   19         {
   20             //Car Senses key fob.
   21             //Car starts.
   22         }
   23     }
   24 
   25     public class MorrisMinor : Car
   26     {
   27         public override void  StartCar()
   28         {
   29             //Key fob turned.
   30             //Car starts.
   31         }
   32     }
   33 
   34     public class SomethingElse : Car
   35     {
   36         public override void  StartCar()
   37         {
   38             //Some random stuff to get this car to start
   39         }
   40     }
   41 
   42 
   43     //Some code somehwere to start the car you have.
   44     var ferrari = new Ferrari();
   45     var morrisMinor = new MorrisMinor();
   46     var somethingElse = new SomethingElse();
   47     ferrari.StartCar();
   48     morrisMinor.StartCar();
   49     somethingElse.StartCar();        


Ok here I have completely removed the enum, as its completely not needed. We already have the type, its a Ferrari, or MorrisMinor, the base class (Car) doesn't care.

I have made the StartCar method a virtual method so all the base classes can now implement their own implementation, they have the knowledge on how to start themselves. So if a new car comes along they can then implement their own StartCar method, and no other car needs to know about it. If StartCar isn't implemented then the default one in the base class will be used.

Look no more switch or if, its all gone. You now don't need to read complex code, well it wasn't complex as it was but when new types start appearing it will creep in there.

I hope my explanation makes some sense, if you like, don't like, or would like to suggest something, let me know either way, or of course just slap me! I am learning here too :-) I think I can probably go into some more depth on how it works but at the moment I think I will leave that for now, hopefully there is enough there to understand the basics of getting rid of them nasty if's and switches.

I am not sure if there is any kind of excuse to have to do the "not so nice way...", maybe I am missing something, but I know its easily done, done it myself. Maybe its a lack of time and pressure and your brain only thinks like a 'C' coder in straight lines (sorry 'C' coders out there I used to be one too, very long time ago, and if I am wrong there, please tell me and give me a slap!). I really don't know as I am sure the second way is actually less code and thinking.

That's another thing what gets on my tits too is seeing OO code written like 'C' (before I explode screaming, I will have to save that for another blog)

Hmmmm, I wonder if its possible to write code without if's, yes ban them, maybe bring a flag out in the compiler you can turn them off! I think that's another post rant too.

I can't believe I keep generating new ideas for a blog post without having even thought about it before. This bloging/ranting is superb! I recommend you try it.

Hopefully I will get to some more complex things in the future, but I guess I am learning to write too at the moment.

No comments:

Post a Comment