OOP: Stop thinking about the data flow!

The main problem with the OO analysis that I’ve seen comes from the inability to leave some thinking patterns that are very routed into our analysis practice. We are animals of habit and while creating them may take at least 3 weeks, getting rid of them it’s usually harder. In this post i would like to suggest some tips to help you change your analysis approach for an OO system.

Forget everything you know

I have this spherical puzzle. Well actually it’s my daughter’s. I brought it to the office and so far only 2 of my companions have been able to resolve it. The skillset required to solve this kind of puzzle it’s very different that the one required to solve a traditional puzzle. Besides considering the shapes that now are 3d, you have an additional restriction on the order the pieces are put together. This alone requires a new thinking process, a new paradigm to try to figure out the solution. If you are a good puzzle solver your old skills are more likely to get in the way than not. It’s the same with this post. I’m just saying, keep an open mind to it.

Messages are not data

Consider the following case: you have to notify whenever a customer status change. This may be whenever a customer is new, or is deleted.

public enum CustomerStatus {New, Removed}

public class CustomerEvent
{
    public string Id {get; set;}
    public string CustomerStatus Status {get; set;}
    ... 
}

public class CustomerEvents
{
    public event EventHandler<CustomerStatus> OnChanged;
}


public void main ()
{
    CustomerEvents events = new CustomerEvents();
    events.OnChanged += (s,e) =>{
       switch(e.CustomerStatus){
            case New:
                  .....
            break;
            case Removed:
                  .....
            break;
       }
    };

}

Take 5 minutes before looking the snippet below. Can you spot what’s wrong with this code?

public class CustomerEvent
{
    public string Id {get; set;}
    ... 
}

public class CustomerEvents
{
    public event EventHandler<CustomerStatus> OnNew;
    public event EventHandler<CustomerStatus> OnDeleted;
}


public void main ()
{
    CustomerEvents events = new CustomerEvents();
    events.OnNew += (s,e) =>{...}
    events.OnDeleted += (s,e) =>{...}

}

“So?” – you may say – “what’s the big deal? It’s the same data, just exposed on a different way”. Well, yeah, it’s the same data, but these are 2 different messages. And that’s and important difference. A message is more than just a way to pass data. It’s an explicit request, we may supply some data to help accomplish the request but that’s just it. What’s important it’s the meaning of the message, the thing we are requesting.

If you want to code in an OO paradigm you need to start thinking in that paradigm: start focusing on the message flow, not the data flow.

Messages, messages everywhere

As mentioned before, an OO program can be better understood if we start with the dynamic side of the application. This means, the objects and the messages sent among them. A good starting point is to take a user story and instead of trying to do a flowchart use a sequence diagram. Try it. Even if you already have a flowchart in place try it.  Some things to keep on mind while doing it:

  1. Try to make your messages as explicit as possible.
  2. Forget about the implementation problems that may arise. Dictate your messages based only on your needs and nothing else.
  3. Avoid the need to figure out where the data contained in the messages, if any, comes from or what it looks like.
  4. Stop thinking on functions that receive data and start thinking on messages sent from one object to another.
  5. Try avoiding getters and setters as much as possible. This will force you to stop thinking of objects as data bags/tables/structs and make you think of them as things that can respond to messages. Instead of asking them for data have them doing whatever you were planning to do with that data in the first place.
  6. Avoid the use of static functions in any other way than as factory methods.
  7. Use interfaces for any object that may change a lot, or to encapsulate a particular way of doing things (algorithm).

As time goes on if you keep practicing you’ll find out that the real abstraction is on the messages. Maybe this is what Alan Kay was thinking of when he said that he should have coined the term “message oriented programming” instead of “object oriented programming”. When you have a set of messages, you can just switch the objects and as long as they can respond to them (the messages), your program will continue to work. Your messages are still in place, your objects are the ones that are replaceable.

Another example

Just consider the following c# code:

string yourName = "sam";
var greet = String.Format("hello {0}!", yourName);

The idea in this is calling a function, passing some data to it and expect the result. The static method “Format” uses the class as a module, a container for functions. The OO way of thinking would be to send a Format message to the string object requesting it to do the operation:

string yourName = "sam";
var greet = "hello {0}!".DisplayOnPlaceholders(yourName);

Here the message DisplayOnPlaceholders(yourName) it’s more explicit than just Format. This allows any developer to understand what it does without having to check it’s code to figure it out. You can mimic some of this behavior using extension methods. There’s a huge library on extensionmethod.net/. Check it out.

Closing words

Some of you maybe find this stuff absurd. But if you code in any of the multiparadigm languages out there and want to get better at your OO skills without learning smalltalk, I strongly suggest that you follow this ideas in as much as possible, at least while you’re getting the hang of it (that is until you start thinking of case objects instead of switch statements). Especially if you come from the .net area (like myself). And enjoy coding 😉