Models and business logic patterns

In the last post, we talked about the different models that co-exist in an application. However, some of these models may or may not exist in a given application and time. To get a better understanding of this effect, let’s review 3 different configurations and the way they affect the application models mentioned before.

Transaction script

A transaction script as described by Martin Fowler, it’s a procedural (often a structured programming) approach to organize an application logic. It contains all the steps to fulfill a request/use case/scenario/story. In my experience, this kind of applications often uses the persistence model directly. This means that this model doesn’t have a domain model but the business logic is embedded in the transaction script itself. Often the transaction script returns a different model on the result, effectively using a presentation model.

Table module

A table module is a different way to organize an application. It’s based on the idea of having a structure that represents a table, just one row at a time. The object itself it’s just an access mechanism to the data of the underlying table. It allows to move to any given record and provides access to all of its fields. You can put the business logic onto this object making it instantly available to all of the records. Often this object is directly bound to the controls of the UI. This means that the persistence, domain and the presentation model are exactly the same.

Domain model

A domain model centric configuration works by separating the domain layer from anything else. The resultant objects are focused on one thing and one thing only: hosting the business logic and rules. By doing this (keeping the domain model ignorant to persistence and presentation needs) we are forced to create a persistence and presentation model. This may initially closely resemble the domain model but can change independently to accommodate the needs of the layer it belongs to (presentation, persistence). Usually, the domain model is developed using an OOP paradigm, whereas the persistence model is often developed under a RELATIONAL paradigm (if using a relational DB) and the presentation model is done following an ACTION or OBJECT representation approach.

Closing thoughts

So there you have it. Go and check your codebase again. Which pattern it follows? Can you pinpoint the different models being used? leave your comments below…

Not all models are the same

Some time ago I used to work for a company that made gelatin capsules used for drug administration. The process was a tricky one: there were several machines that would mix the gelatin and then you have a to wait a cool down time before you could start using it. There were different kinds of gelatin with different mix and cooldown times. My job was to create a simulator that would calculate the optimistic use of the machines given the requirements for different kinds of gelatin. I was given access to a database that had everything I needed. So my initial domain model was based on the DB structure. As time passed by, however, it was clear that the current model was lacking a lot for my purposes. So I just dropped the whole thing and start anew. Using a repository I then mapped the domain model to the DB model. Then something funny happened: my manager could not understand my domain model since he could not reason outside of the DB one. It took me some time to figure what was confusing for him…

Not too long ago I heard something similar. I was helping a friend at work to distill a domain model that was based on a DB. I didn’t do much, just giving some pointers on how to apply OOD principles and helping him to find out how to allocate responsibilities to the right objects. As the model became more clear he came to the conclusion that some of the DB design decisions were getting in the way, so he decided to create his own domain model. Once he did that, the code became so much clear.

The fallacy of one model to rule them all

Unfortunately, a lot of people tends to start modeling the DB and then create a domain model that mimics that structure. That works for a relatively simple system but it won’t stand against a more complex one. The reason it’s simple: the DB model, serves a different purpose than solving the problem. Actually, we deal with several models on a system, each one serving a different purpose. Let’s go over them.

The persistence model

I’ll start with this because often this is the starting point when designing a system. The persistence model actually has the purpose of storing data efficiently. That’s it. We often use E/R diagrams as a tool to understand the concepts of the domain and the relationship between them. One problem with this is that often these concepts are related only on a given context and these relationships are not valid out of that scope. A very experienced developer can avoid that but I argue there are better tools for analysis than E/R diagrams. Usually, the persistence model is very granular.

The domain model

The domain model it’s the one responsible for solving a very specific problem. Hence a domain model should be very specific. Designing a domain model requires you to have an understanding of the problem. This is part of the solution and not the problem space. I believe this model should be created before any other one. If you are using OOP, this model comprises your objects and the interactions between them. Is often more coarse than the persistence model.

The presentation model

The purpose of the presentation model is to allow the user to interact with the system.

When dealing with an object-oriented system, there are 2 schools of thought regarding the user interface: task-based and object-based.

Task-based user interfaces are geared towards a task that involves several objects interacting together. It’s like a script that a set of objects has to follow to accomplish something on behalf of the user. This often results in a more coarse model that aggregate several domain objects. Objects on this model are often called view-model objects.

Object-based user interfaces are predicated on the idea that the user should be able to manipulate the objects together as he/she sees fits to accomplish anything he wants. This means exposing the underlying domain model directly to the user. Patterns and frameworks such as naked objects are examples of this idea.

Traps and tricks

One of the problems I often encounter comes from the use of ORM’s. I’m not saying that using them is bad, but you should use them carefully. They often introduce constraints from the underlying persistence mechanism, forcing us to concern with stuff other than solving the problem at hand. They also somehow promote coupling so it’s not easy to switch the underlying persistence technology, ie from a relational to a document DB.

Another problem arises when you try to expose your domain objects on a task-based UI. In my experience they become intermingled with UI logic, making them a mess that is hard to maintain. Often you end up with additional data that has nothing to do with the object original purpose.

Eric Evans figure this out long ago. That’s why on DDD he provides us with patterns to isolate the domain model from any external influence. Repositories allow the domain model to be completely independent of the persistence model whereas the application API isolates it from the UI. Unfortunately, the intent behind these patterns has been forgotten and thus misuse and abuse of these patterns arise.

Closing thoughts

Next time you start a new project, put mechanisms in place to keep your models separated.

Whenever you find yourself struggling to accomplish something because your model (be it persistence, domain or presentation) cannot accommodate that change without creating a ripple effect to the other models, take a look at the patterns mentioned here and look for ways to isolate the model. This may take some time in the present, but it will pay handsomely in the future.

Good luck out there!

The basics part 4: composition

In a previous post we illustrate how inheritance can help to refine the behavior of a particular case. In this post we’ll take a look at a different approach.

Composition over inheritance

In the Gang of 4 book, they advise to use composition over inheritance. Composition is a technique that breaks an object overall behavior in smaller objects each tasked with an aspect of it. This allows for better reuse and a more maintainable codebase.

Let’s see how it works.

Refactoring from an inheritance hierarchy to a composition model

Identify the aspects of the behavior

The first thing we’re going to do is to identify the steps of the behavior being overriden.

public virtual decimal CalcBonus(Vendor vendor)
{

     decimal bonus = 0;

     bonus = washMachineSellingBonus(vendor);

     bonus += blnderSellingBonus(vendor);

     bonus += stoveSellingBonus(vendor);

     return bonus;

}

In this case these would be washMarchineSellingBonus, blenderSellingBonus and stoveSellingBonus. It’s worth mentioning that you’ll find code where the steps are not as clearly seen as in this example. Nevertheless, they’re still there. Every algorithm is just a bunch of steps in a certain order.

Create abstractions as needed

In our example the washMarchineSellingBonus, blenderSellingBonus and stoveSellingBonus are, as the name describes, bonuses. We can make this implicit abstraction explicit by creating an interface to represent it:

public interface Bonus
{
  decimal Apply(Vendor vendor);
}

public class WashMachineSellingBonus:Bonus {…}

public class BlenderSellingBonus:Bonus {…}

public class StoveSellingBonus:Bonus {…}

By doing this, we can have the calculator object with the responsibility to decide which bonuses will apply and keep track of the bonus amount while using the command pattern to contain each bonus calculation logic.

public class BonusCalculator()
{
  List<Bonus> bonuses = new List<Bonus>();

  public BonusCalculator()
  {
    bonuses.Add(new WashMachineSellingBonus());
    bonuses.Add(new BlenderSellingBonus ());
    bonuses.Add(new StoveSellingBonus ());
  }

  public decimal CalcBonus(Vendor vendor)
  {
   return bonuses.Sum(b=>b.Apply(vendor));
  }

}

So far, so good. But what’s the real benefit of this?

Inject behavior at runtime

If we apply the Dependency Inversion Principle, something interesting happens.

Public class BonusCalculator()
{
  List<Bonus> bonuses = new List<Bonus>();

  public BonusCalculator(IEnumerable<Bonus> bonus)
  {
    bonuses.AddRange(bonus);
  }

  public decimal CalcBonus(Vendor vendor)
  {
    return bonuses.Sum(b=>b.Apply(vendor));
  }
}

Now our BonusCalculator class becomes a mere container. This means that the behavior must be setup somewhere else. If needed the definition of the bonus calculator can now be hosted outside the code, like in a configuration file.

public class BonusCalculatorFactory()
{

   public BonusCalculator GetBonusCalculator(string region)
  {
   //Lookup the configuration file or a database or webservice and get the Bonuses 
     that apply to this particular region 
   }

}

The idea here is that you can now modify the behavior of the BonusCalculator without the need of a hierarchy tree.

Advantages over inheritance

The main advantages of using composition are

  • Changing behavior can be done at runtime without a need to recompile the code.
  • You don’t have the fragile base class problem anymore.
  • You can easily add new behaviors (in the example just implement the Bonus interface)
  • You can compose behaviors to create more complex ones

Let’s take a quick look at this last point.

Mix and match to create new behavior

Let’s create a composed bonus object. We can reuse the template functionality from the bonus calculator.

public class ExtraBonus(): BonusCalculator, Bonus
{
  public decimal Apply(Vendor vendor)
  {
    decimal theBonus = CalcBonus(vendor);
    return theBonus > 2000? theBonus * 1.10 : theBonus;
   }

}

Final thoughts

One of the things that I like about using composition, is that it forces you to decompose a problem to its simplest abstraction, allowing you to use this as a building block to create complex behavior and great flexibility at runtime. Now is time for a revelation: the actual text in the GoF book reads

  Favor object composition over class inheritance

It’s not my intention to explain the reasons behind this principle on this post, but the hint is on the words object and class. Think about it and let me know your observations.

Polymorphism or how to decouple structure from behavior

The 2 sides of the coin

There are 2 aspects to any software piece: a static and a dynamic one, the former being the code and the latter being the execution of that code. The static part deals with the structure of the software while the dynamic part deals with the behavior of the software. This duality in the software is often ignored by a lot of developers, yet is there and its effects are tangible.

The structure and behavior relationship

There is a strong relationship between structure and behavior. The behavior is conditioned to the structure represented in code. You can have a rigid structure, that is, a structure that don’t allow the change of behavior without any changes to itself. The opposite is a flexible structure that allows changes to behavior without changing the structure itself.

Structure vs Code

It’s important to understand that code is not the same as structure. You can change the code without changing the structure of the software. Renaming a variable, even changing a variable, are changes that do not affect the structure of the software. The structure is more of a conceptual model, coupled with some conceptual mechanisms that is implemented by a programming language in the form of code. The way the conceptual model is defined will be affected by the programming paradigm used by the developer. You’ll come to different models/structures using different paradigms. Also the conceptual mechanisms will differ from one paradigm to another and in some cases from one language to another.

The case against switch

Put simply the purpose of polymorphism is to create a flexible structure that allows the software to change it’s behavior without changing the structure. There may be changes to the code, but not to the structure.

Consider the following code:

public enum EmployeeType
{
    Manager, Worker
}

public struct Employee
{
   public string ID {get; set;}
   public string FirstName {get; set;}
   public EmployeeType Type {get; set;}
}

public void MakePayment(Employee employee)
{
    decimal wage = 0;
    switch(employee.Type)
    {
      case EmployeeType.Manager:
        wage = 30m;
      break;
      case EmployeeType.Worker:
        wage = 10m;
      break;
    }
   decimal payment = wage * getWorkedHours(employee.ID);
...
}

Suppose we want to add a new employee type, Janitor. To make the software make payments to the Janitor (change in behavior) we would need to add a Janitor value to the EmployeeType enum and modify the switch to accommodate the new value. This is a rigid structure: you need to tweak it to make it learn new tricks. This is a typical procedural style (using C#).

The worst part of the code above is that by changing the Employee type from struct to class and putting the MakePayment procedure inside a class (most of the time as an static method) an lot of developers believe that they are now doing OOP.

Let’s see how this would look like from an OOP paradigm.

public interface Role
{
   decimal GetWage();
}

public class Manager: Role
{
   public decimal GetWage() { return 30m;}
}

public class Worker: Role
{
   public decimal GetWage() { return 30m;}
}

public class Employee
{
   Role _role;

   public Employee(Role role){
      _role = role;
   }

   public string ID {get;}
   public decimal Wage{ get{ return _role.GetWage(); }}
}

public class Timesheet
{
   public bool Pay(Employee employee)
   {
      decimal payment = employee.Wage * getWorkedHours(employee.ID);
      ...
   }
}

So in this code, if you wanted to add a Janitor employee, all you have to do is to create a new Role class that represent the Janitor role. And that’s it. That’s a code change, not a structural one. The price for this flexibility is indirection. Now there are a lot of classes, each one representing a case in the switch. That’s how we deal with branching in OOP. And that’s why OO software tends to be way more flexible than procedural software.

Final words

I hope this helps making the point clear. I tried keeping it simple, so maybe the example may look silly. I would like to say that polymorphism is not a characteristic of OOP alone: C allowed to define some sort of interface for a function and the languages in the Functional programming paradigm make heavily use of it too. Even when the form may vary, the idea it’s almost always the same: decouple dependencies and allow the creation of a flexible software structure, making it resilient in the face of change.

The basics part 3: inheritance

One of the pillars of object-oriented programming is the inheritance or the ability to create hierarchies of objects where you are refining or modifying certain behavior.  For the sake of an example, imagine a company that sells washing machines, stoves and blenders. To motivate their vendors, they have a bonus system that works in the following way:

All vendors have a sales quota. If 25% of sales are coming from washing machines, the seller gets a bonus of 15% of their salary. If at least 50% of the sales come from selling blenders, then receives a bonus of 30% of their salary. Finally if it achieves 25% of its share selling stoves gets a bonus of 20% of their salary.

Now, suppose that these vendors are distributed in the areas north, East and South. Vendors in the southern area have an additional 10% bonus if they exceed the sales quota.

We could represent it in the following way:

Herencia (1)

Then we have a class BonusCalculator. Objects of this class contain all the rules to calculate the bonus of any vendor. One way of implementing this might be something like:

public interface Vendor
{
   bool SalesPercentAchieved(double percent, string productLine);
}


public class BonusCalculator
{
  public virtual decimal CalcBonus(Vendor vendor)
  {
	  decimal bonus = 0;
	  bonus = washMachineSellingBonus(vendor);
	  bonus += blnderSellingBonus(vendor);
	  bonus += stoveSellingBonus(vendor);
	  
	  return bonus;
  }
  ...
}

However for vendors in the South, we have an additional rule to all others.

public class SouthernBonusCalculator:BonusCalculator
{
   override CalcBonus(Vendor vendor)
   {
	   decimal bonus = base.CalcBonus(vendor);
	   bonus + = overSellingBonus(vendor);
	   return bonus;
   }
   ...
}

That’s it. Just use the correct object to calculate the bonus.

void main() {
   List<Vendor> vendors = getVendors("North");
   vendors.AddRange(getVendors("Eastern"));

  var calculator = new BonusCalculator();
  for each(var vendor in vendors)
 {
    decimal bonus= calculator.CalcBonus(vendor);
    Console.WriteLine (bonus);
 }
 
 calculator = new SouthernBonusCalculator();

 List<Vendor>SouthernVendors= getVendors("South"); 
 for each(var vendor in SouthernVendors)
 {
  decimal bonus= calculator.CalcBonus(vendor);
  Console.WriteLine (bonus);
 }
}

Simple. This code leaves much to be desired but we will go adjusting it later.

Now I would like to point out that there’s no properties in the diagram nor in the code.
I did this deliberately to place emphasis on a fundamental principle: inherits it’s all about the behavior, not the data. In other words we use inheritance when we have an object that has a method that you want to adjust a bit to your needs, not when we want to reuse data. That is a common mistake. It comes from the relational databases mindset, which is reduce the duplication of data. In the case of object-oriented programming, it is reducing duplication of methods. Don’t be afraid to repeat data on different objects.

Well that is all for today, next time we will see the meaning of the phrase “favor composition over inheritance” and how that can help us improve the code for this example. Until then.

The basics pt. 2

Getting things done

The main question when it comes to OOD is: what does this do? Objects are all about doing things. They have some data to do this things, but that’s it. I’ve seen so many codes where objects are nothing more than data containers. That’s not OOP. You may be using an OOP language, but you’re not doing OOP. Now i don’t intend to upset you. I used to code like that. That’s one of the reasons I’m sharing this with you. Objects do things. They must have a reason to exist. A role to fulfill.

If you paid attention to the previous post, i defined a VirtualPet in terms of what it does. It sleeps, play and eat. I didn’t start with stuff like name or age. Sure those can be used to identify a particular object, but what’s so good about identifying a useless object?

When designing a database you start with data. When designing an object model you start with behavior. There seems to be a lot of people who don’t know or don’t understand this subtle difference, thus leading to a lot of hard to maintain code. They heard of design patterns and try to apply those to their pseudo-oop code often resulting in unnecessary complexity. I’ve been through this myself, wondering what was so great of these so called patterns. Have you?

Finding the right guy for the job

A great deal of a developer’s life is understanding things/learning concepts. This is because very often objects represent real life concepts. Even more, the same concept can have a different meaning in a different context. A home phone number can be some optional data in a customer relationship management system but can be a crucial piece in a delivery pizza system ;).

Creating a flexible OOP system it’s a lot about identifying the key concepts related to a given domain and the responsibilities related to them in a given context.

So let’s do a little exercise.

Let’s say we’re making a banking system. We’re assigned the following case (mind my bad English, I’m not a native speaker):

Cashing a check.
The bank receives a check from a customer. 
The customer can ask for either get the cash or deposit it to another account. 

Deposit to an account
The customer deposit an amount to a certain account.

The data oriented approach

So here we have it. Let’s think about it for a second would ya? where do we start ? What are the main concepts here? let’s see, there has to be a customer, right? i mean the customer always starts everything, brings the check, deposit the money, we should have one, right? right? It must have a name, an address maybe, surely an account number! It may look something like:

image

Validating the model

ok, what’s next? well the next thing is asking yourself: what does this do? What does customer do? what’s it’s Raison d’être? go ahead take your time. Think about it.

So imagine I’m the same room with the author of the previous design, here’s how this conversation would go (probably):

-so what does customer do?
-well obviously every account has an owner. That would be the customer.
-Yeah but what does it do?
-Mmm... what does it do you say? (frowning eyes as if thinking hard) that would be... to help finding an account.
-You could always use the account number
-Yeah, but not everyone knows it. Heck i don't even know my zip code!
-OK, i got your point. So the customer helps finding the right account.
-That's right.
-But then, wouldn't make sense to add the customer as an account attribute?
-I don’t think that’s a good idea.
-why not?
-because they’re different things. Different concepts.
-So you’re saying that every time I want to find an account, first I have to fetch the customer object?
-Yeah…
-and then I guess I would call a method called GetAccount()
-not necessarily. You just have to transverse to the CustomerAccount property
-so the customer doesn’t do anything. It’s just a place holder.
-it does! it let’s you access the account!
-… Thinking smile

The meaning of “do”

As you can see from our fictional discussion, the problem lies with the meaning of probably one of the most used words. To help us understand what “do” means in this context let me rephrase the question: what’s this object’s mission? What does a mailman do? what’s his mission? that would be to deliver mail. He doesn’t let you search his bag for your mail. And you don’t care if he uses a bike or an elephant as long as you get your mail. So “do” in this sense defines the object’s ultimate purpose.  In OOP slang we call this the object responsibility.

Ok, now that we state what we mean with the question. Let’s get back to our little exercise. What was that again? Ah! What does customer do? the short answer is: nothing. I won’t go into the long answer Winking smile.

Let’s continue with the check object. What does check do? from what we read earlier it gets money from an account. We’ll come back to it later.

Ok, next is the account object. What does account do? Mmm… could we say that it maintains a balance? does that make sense to you?

So far we have the following:

Object what does it do?
customer nothing
check get money from an account
account maintains a balance

The lens we see through

The “what does this do?” kind of analysis is not new. It is implicit in Kent Beck CRC cards technique as well as in TDD. The important thing here it’s that we have objects that do things. Now let’s get dirty Winking smile

The first thing that comes to mind is the customer object. It really does nothing. Any object that does nothing in the model, just make it harder to understand, so let’s get rid of that Customer… (I mean the object, not that pricky, close minded guy from your last project! I bet you’re thinking about him/her now Angry smile)

Woah! no customer object? but this is a banking model we’re doing here! there has to be a customer object!

Well you see, an object model shows up just what’s important to a specific context. That means it highlights what’s important to a specific use case. Maybe the following example will make this clear.

Optimized-world-map-terrain

I got 2 maps here.  You could say that both are models of the world. The difference lies in what they’re trying to convey. The first one shows the time zones. The second one put emphasis on the terrain.

So you see, an object model it’s just like a map. You don’t show the reality in full detail, just the stuff relevant to the matter at hand. We call this process of identifying the important objects and relevant actions, the abstraction process. And the resulting objects are called abstractions, since they represent the important stuff on the domain. Ok, now that I’ve made my point, I hope you understand that Customer is not relevant to this model. At least at this point.

Digging deeper

Now that we have objects, and responsibilities assigned to them, let’s find out how they carry them out. I’ll start with the “deposit to account” use case since it seems the simpler one (I always try the simpler use cases first). This case tell me that the account object has a deposit operation that adds an amount to it’s current balance. Easy peasy.

Object what does it do? How does it do it?
account maintains a balance deposit(amount)

Now on to the “cashing a check” use case. So we have a cash method in the check object and it needs an account to withdraw from. But the account object doesn’t have a way to withdraw from itself so we have to create one.

Object what does it do? How does it do it?
check get money from an account cash()
account maintains a balance deposit(amount)
withdraw(amount)

The customer can also cash the check to another account. This effectively is a transfer operation. Where should we put this? Who has this responsibility? to answer that question we got to understand the effects of this operation. What’s going to happen after the operation is completed? if all goes well one account will have it’s balance decreased while another will have it increased. And who’s responsible for maintaining a balance? the account itself! it’s not an AccountService object or a TransferOperation object but the account who’s solely responsible. So let’s create a transfer method in the account object and a cashToAccount method in the check object.

Object what does it do? How does it do it?
check get money from an account cash()
cashToAccount( account)
account maintains a balance deposit(amount)
withdraw(amount)
transfer(amount,account)

So there you have it. Both cases with just 2 simple classes. I’m sure you have a pretty clear idea of how to code this now. It may be something similar to :


class Account
{
    decimal _currentBalance = 0;

    public bool Deposit(decimal amount)
    {
        //biz rules    
        _currentBalance += amount; 
        return true;
    }

    public bool Withdraw(decimal amount)
    {
        //biz rules   
        _currentBalance -= amount; 
        return true;
    }

    public bool Transfer(decimal amount, Account toAccount)
    {   //biz rules   
        toAccount.Deposit(amount);
        this.Withdraw(amount);
        return true;
    }
}

class Check
{
    decimal _amount = 0;
    Account _originAccount;

    public Check(decimal amount, Account account)
    {
        _amount = amount;
        _originAccount = account;
    }

    public bool Cash()
    {
        //biz rules
        return _originAccount.Withdraw(_amount);
    }

    public bool CashToAccount(Account account)
    {
        //biz rules
        return _originAccount.Transfer(amount: _amount, toAccount: account);
    }
}

Homework : Go back to any of your past projects and identify at least 2 use cases, their main concepts and if there are objects representing each one. Then find what their responsibilities are and, if they are not clear, define them. Last but not least, identify the operations needed to carry on the object’s responsibilities. Compare and write your comment below. Let me know if this changes would simplify the current code or not.

See you in the next post.

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.