The basics

Words without meaning

So, if you are anything like me, you have indeed listen about OOP and stuff. It’s just that you never wrap your head around it. Inheritance, really what is it for? And what the heck does polymorphism mean? The reason a lot of people have a hard time trying to do OOP, it’s because to them these are still words without meaning.

Fighting loneliness

I was a kid when i first saw a tamagotchi, a digital pet that lived inside a key chain like device. So let’s create our own virtual pet to keep us company on those long coding nights. I’ll give u a start but first, let’s define what a virtual pet is.

Virtual cuteness

Ok, for this exercise let’s say that a virtual pet eats, sleeps, and play. This all depends on the mood it currently has which could be hungry, tired and bored. That means that our little friend won’t play anything while it’s hungry.

So time for a little coding. I need you to create an enum holding all the creature mood states. Then code it’s actions as given in the specification. Ready, go!

using System.IO;
class VirtualPet
{
  public static VirtualPet CreateTiredPet(TextWriter output)
  {
      return new VirtualPet();
  }
  
  public static VirtualPet CreateHungryPet(TextWriter output)
  {
      return new VirtualPet();
  }
  
  public static VirtualPet CreateBoredPet(TextWriter output)
  {
      return new VirtualPet();
  }
  
  public void Eat(){}
    
  public void Play(){}
    
  public void Sleep(){}
}
class VirtualPetSpecs
{
    static TextWriter writer;
    
    public static void mustPlayOnlyIfBored ()
    {
        Console.WriteLine ("Must Play Only If Bored:");
        writer = new StringWriter();
        VirtualPet bobby = VirtualPet.CreateBoredPet(writer);
        bobby.Play();
        if (writer.ToString () == "playing time")
        Console.WriteLine("pass");
        else
        Console.WriteLine("fail");
    }
    
    public static void mustEatOnlyIfHungry ()
    {
        Console.WriteLine ("Must Eat Only If Hungry");
        writer = new StringWriter();
        VirtualPet bobby = VirtualPet.CreateHungryPet(writer);
        bobby.Eat();
        if (writer.ToString () == "yummy")
        Console.WriteLine("pass");
        else
        Console.WriteLine("fail");
    }
    
    public static void mustSleepOnlyIfTired()
    {
        Console.WriteLine ("Must Sleep Only If Tired");
        writer = new StringWriter();
        VirtualPet bobby = VirtualPet.CreateTiredPet(writer);
        bobby.Sleep();
        if (writer.ToString () == "zzzz...")
        Console.WriteLine("pass");
        else
        Console.WriteLine("fail");
    }
    
}
VirtualPetSpecs.mustPlayOnlyIfBored();
VirtualPetSpecs.mustEatOnlyIfHungry();
VirtualPetSpecs.mustSleepOnlyIfTired();

 

The ripple effect

Ok, now that you made it work let’s mutate it. Copy the code you just wrote and reset everything using the button on the lower left. Paste your code again and now modifiy it to use a dictionary instead of an enum. Go ahead i’ll wait for you. Nope, no more reading for you until those changes are done.
Ok, now that you finished, let me ask you, how hard was that? Was the implementation really that diferent? Think you could do it with a list? Or with mere strings? Would that be too hard? Could you think of a way to store those settings in a config file? What about a web service? Can you do it?
Now tell me, if you were to make any of those changes, how would the VirtualPetSpecs be affected? Why?

The reason for this code to be so ‘changeable’ (is that a word?) it’s because you’re just changing the way it does the things it does but no what those things are. In an OOP slang you’re changing the implementation, not the responsibilities. Now imagine the following code:


 static void mustPlayOnlyIfBored ()
{
  Console.WriteLine ("Must Play Only If Bored:");
  VirtualPet bobby = new VirtualPet ();
  bobby.mood = Mood.Bored;
  bobby.Play();
  if (bobby.mood == Mood.Tired)
   Console.WriteLine("pass");
  else
   Console.WriteLine("fail");
}

Try using a dictionary, config file or web service. Better yet, try changing the mood to hungry. Or create an algorithm that randomly choose any of the other states. Can you do that without having to change the specification?
The problem with this code it’s that VirtualPet it’s showing way too much of the way it does it’s own things (implementation details in OOP slang). This lead to the code using this objects to depend on the implementation details (coupling in OOP slang) hence making it impossible to change the implementation without changing all the code that depends on it. I’ll call this the ripple effect, since one change tends to propagate to other parts of the system. The only way i know to prevent the ripple effect it’s to completely hide the implementation details. This is called encapsulation. Yup, you heard that right. It’s the same they told you in your java or c++ class. Encapsulation it’s nothing more than the oop slang for “hide implementation details!”. And this opens the door for a lot of other interesting stuff.

Stay tuned for part 2 😉

P.S. Here’s a little homework for you: go grab a copy of a past project and start searching for parts where some code depends on the implementation details of an object. Analyze rhe ripple effect on that code and how you would modify the code to prevent it. Post your answer on the comments.