The Architect´s Napkin

Software Architecture on the Back of a Napkin
posts - 69 , comments - 229 , trackbacks - 0

My Links

News

Archives

Post Categories

Event-Based Components – Leaving the beaten path of canonical object orientation

Since long I´ve been doubting the canonical object oriented way of programming was of much help. I´ve never seen a “true” object oriented software system that also was maintainable. And I´ve never seen an average programmer who had an easy time coming up with an evolvable design for even a small application.

The litmus test for me is to put someone in front of an empty whiteboard and ask them to quickly draw a design for, say, a Tic Tac Toe game. It´s an easy scenario, I´d say. The requirements are pretty obvious; they could look like this:

The application will be played by two players sitting in front of it. When the application is started it creates a fresh game. The players then in turn click on cells in the 3x3 matrix. The application marks clicked cells with a cross or circle depending on the player. The application determines which player wins by observing the cells.

I´d even throw in a mock-up of the GUI I envision:

image

How´s that? Why not try to design the application yourself. It shouldn´t take you longer than, say, 5 minutes. Or should it? Since I´m asking for a design be sure to do a design and don´t even think about wipping up Visual Studio and start programming. No, I´m serious.

What would your application architecture for this small scenario look like? How would you go about developing this architecture?

I at least find it very difficult to find consolation in common object orientation when pondering this task. Also I feel pretty much left alone when looking to architectural layers. And so do 9 out of 10 developers I know.

But where else to look for a meta model to base my concrete model on? Where to look for guidelines for moving from requirements to code?

I´ll now leave you alone with this exercise for a couple of days. Maybe you find it easy to solve. If you like, let me know your solutions.

In the meantime I want to show you an approach to software design I´m currently using. And I want to start with an even simpler scenario.

Switching to events

Here are the requirements for a trivial application:

The application shows a rectangular field colored in green. Pressing a button switches the color to red. Pressing the button again switches the color back to green.

And here´s my proposal for the GUI:

image

How would you design this application. And again I mean design, which excludes solutions containing domain logic in button click event handlers and the like.

Too simple a problem for a design you say? No, I don´t think so. There is no such thing as a too small scenario for doing a solution design. So here´s mine:

image

This is my version of the architecture for the toggle feature.

But what about application start? Initializing the colored area with green is another feature. So I need to do some more modelling:

image

That´s it. That´s my design for the solution to the above trivial problem. A couple of circles, arrows, and boxes. If this looks like BPMN to you, you´re on the right track. If this looks like UML Activity Diagrams, you´re on the right track, too. But as you´ll see I don´t want to slavishly stick to those standards. I´m more of a pragmatic guy. And I want to show you a way to model your software from the tiniest problems to big ones.

Anyway… what does this diagram mean?

Focus on the boxes first. They describe some task, some activity, some step in a process, something to do. Where did I get those activities from? Well, I got them right from the requirements. Pressing a button to switch the color can be described by the verb “to toggle”. So the upper box represents the main feature of the application. And the lower box I gleaned from the initial statement of the requirements: the rectangle should show green upon application start.

As simple as this is it represents a very fundamental view: Requirements are about processes, sequences of activities, algorithms. Requirements describe input, and output, and some transformation to apply to the former for arriving at the latter. Of course requirements don´t tell you how to do the transformation in code; that´s your job to find out. But nevertheless they are mainly about transformation processes.

That´s why I start modelling software by extracting these processes from the requirements. And that´s why my boxes are named using verbs or small phrases describing an activity.

Viewed from a high altitude each feature is represented by a single box which is triggered by an event, and which produces events. That´s why I call the boxes Event-Based Components (or EBC for short). But more on the term component in a future blog article.

The “Toggle Color” activity is triggered by some event with no parameters, and it fires an event with the new color as a parameter. This might be unusual for you. You probably expected some “Color Manager” class with a function like Color Toggle(). That would have been truely object oriented, wouldn´t it? Sure – but I want to leave this beaten path of object orientation, since it´s so hard to travel. For example: Where would you have gotten the idea of a “Color Manager” (to keep the current color state) from? Do you find the notion of a “Color Manager” somewhere in the requirements? No. They are just talking about some GUI details - and desired behavior.

What you can glean from the requirements are just activities, verbs, behavior, not stateful objects. Stateful objects like a “Color Manager” are abstractions (at least in many cases). So why trying it the hard way and imagine them? I rather come up with a design from what I readily find in the requirements. That´s behaviors.

And to be able to chain behavior together I use events. Just suspend your skepticism for a short while, maybe a couple of blog articles.

Translating EBC diagrams into code

Now you know what the boxes and arrows are in the above diagrams. Boxes represent behavior, arrows represent data flow using events. But what do the circles stand for? They are event sources and sinks. They are initial sender and terminal receiver of events/data. They are not activities; they can be described with nouns. When translating such a diagram into code, you map sources and sinks to a class.

But what about the activity boxes? You can map each to a class as well. Or you can map them to methods on a class. For this small example let me do the latter:

    class ColorManager
    {
        private Color currentColor;


        public void In_ToggleColor()
        {
            this.currentColor = this.currentColor == Color.Green
                                    ? Color.Red
                                    : Color.Green;
            this.Out_CurrentColor(this.currentColor);
        }


        public void In_GetInitialColor()
        {
            this.currentColor = Color.Green;
            this.Out_CurrentColor(this.currentColor);
        }


        public event Action<Color> Out_CurrentColor;
    }

See, there is your “Color Manager”. But it sure looks differently than you would have expected from object oriented programming. And I arrived it from a different direction. Instead of top-down design I did bottom-up design. I started from what I found in the requirements – and then I aggregated it on a higher level of abstraction into a “Color Manager” (not a very good name, but well… ;-):

image

The same is true for source and sink. I started with a very general notion of who initiated the feature processes – and then decided to let source and sink be the same: the GUI form.

    public partial class WinMain : Form
    {
        public WinMain()
        {
            InitializeComponent();
        }


        private void Form1_Load(object sender, EventArgs e)
        {
            this.Out_Start();
        }


        private void button1_Click(object sender, EventArgs e)
        {
            this.Out_ToggleColor();
        }


        public void In_CurrentColor(Color color)
        {
            this.pictureBox1.BackColor = color;
        }


        public event Action Out_Start;
        public event Action Out_ToggleColor;
    }

image

See how outgoing arrows were translated into events, and incoming arrows became methods (procedures)? That´s the basic pattern of Event-Based Components.

But how are the classes communicating? They don´t know each other. There are no static dependencies between them. And I´d even argue there are no dependencies at all between them.

Well, instances of the two classes are plugged together (or wired up) like this:

    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        var wm = new WinMain();
        var cm = new ColorManager();

        wm.Out_Start += cm.In_GetInitialColor;
        wm.Out_ToggleColor += cm.In_ToggleColor;

        cm.Out_CurrentColor += wm.In_CurrentColor;

        Application.Run(wm);
    }

Each outgoing event is assigned an incoming event handler. It´s a very mechanical translation of the diagram, isn´t it.

Summary

Doing object oriented design starting from requirements is hard. So why not try something else? I believe Event-Based Components (EBC) are an alternative to check out. In this article I introduced you to the very basics of EBC, as I see them. There are only a few rules to master – but their implications for software design are profound. That´s at least my feeling after using them for a couple of months. Stay tuned for more, if you like…

PS: If you want to follow along with Visual Studio, check out the Google Project accompanying this article series.

Print | posted on Sunday, July 25, 2010 5:15 PM | Filed Under [ Event-Based Components ]

Feedback

Gravatar

# re: Event-Based Components – Leaving the beaten path of canonical object orientation

I like the EBC idea beacause it decouples the components and makes the testing easier. What I see is that developers generate to many stateful components. Why should the "ColorManage" component have a state? The UI application knows the current color. Any other color is not the true one because the user does not see it. When you remove the state from this component you can also rename it to ColorToggler but you have to add the current color to the In method.
I would also remove the IN_GetInitialColor from the ColorToggler because who initials the application? The main method (in your example) or a DI. They should know the initial color and not the component at all.

With all this in mind I would change the example to:

class ColorToggler
{
public void In_ToggleColor(Color currentColor)
{
this.currentColor = currentColor == Color.Green
? Color.Red
: Color.Green;
this.Out_CurrentColor(this.currentColor);
}

public event Action<Color> Out_CurrentColor;
}

static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);

var wm = new WinMain();
var cm = new ColorManager();

wm.Out_Start += Color.Green;
wm.Out_ToggleColor += cm.In_ToggleColor;
cm.Out_CurrentColor += wm.In_CurrentColor;

Application.Run(wm);
}
7/26/2010 3:13 AM | Jörg Dieber
Gravatar

# re: Event-Based Components – Leaving the beaten path of canonical object orientation

@Jörg: Sure, you can design the application without keeping state in the logic. But that´s a different dicussion. You can do both with EBC.

Why I made the domain logic stateful, though, is simple: I believe that it should be. That´s what the application is about: some state that gets toggled. And that needs to be represented in the domain logic.
7/28/2010 1:55 PM | Ralf Westphal
Gravatar

# re: Event-Based Components – Leaving the beaten path of canonical object orientation

Many thanks, found this very thought provoking.

Is an object-oriented approach about state? I'd argue it's about behavior. Just because many developers only view objects from the perspective of state, doesn't mean that is what object-orientation is.

Shouldn't a real object-oriented developer think that some behavior is triggered by a message (typically a method call), and that message *may* have an Event as its source? So in this case the message is ChangeColor, the receiver is a Toggle, and the source of the message is an Event. While in this example the Toggle might maintain state (current color), more generally this might not be the case.

So, isn't your model a restatement of an object-orientation approach, but with the constraint that all messages are generated by an Event, and that the receiving object must notify interested parties that state has changed?
8/6/2010 12:28 AM | Alex Hoffman
Gravatar

# re: Event-Based Components – Leaving the beaten path of canonical object orientation

@Alex: Originalle object orientation was about messages. But where have they gone? So I´d argue despite these origines de facto object orientation is not about messages and behavior but primarily about state.

And it is this common misunderstanding which stands in the way of evolvable designs that I´m "attacking". I don´t want to do away with classes etc. I just want to set the minds of developers free to use them in more beneficial ways.

My finding is this happens, when you don´t start with thinking about actors but rather about actions. Then you aggregate actors from actions. It´s simply much easier than the other, common way.

-Ralf
8/6/2010 8:30 AM | Ralf Westphal
Post A Comment
Title:
Name:
Email:
Comment:
Verification:
 

Powered by: