The Architect´s Napkin

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

My Links

News

Archives

Post Categories

Improving the Event-Based Components Desktop Calculator

In my previous article I designed and implemented a small desktop calculator using Event-Based Components. That was fun and went smoothly – but in the end I was in a hurry and missed a bug and a feature. In the meantime I found some time to fix both.

Final architecture

Let me take the opportunity to show you the application architecture in its entirety. The missing feature – Clear calculation - has already been added:

image

This is the high level view. All activities except one are so simple, no further detail is needed. Calculate, though, deserves some refinement. So let´s quickly zoom in:

image

That´s it. An application defined on two levels of abstractions. No class diagrams needed, no component diagrams, no packet diagrams. Just some kind of activity diagrams with a clear set of rules for translating them into C# code – which, by the way, you can find here.

The beauty of it – as I see it – is that you can draw EBC diagrams on as many levels of abstraction and you´ll find all of them in your code. Model and code are always in sync.

And what about classes? Sure, there are classes:

image

But mind you: they do not depend on each other. That´s the power of events. The classes are either manifestations of activities (e.g. Calculate) and thus do not depend on other´s by definition. An activity does not depend on another activity to be performed; it just uses input and produces output (or a side effect). Or the classes are aggregations of activities and thus also do not need to depend on others.

Bug fixed

The bug to fix was, that the calculator did not deliver a correct result if after a “=” an operator was clicked and then another number entered, e.g. 1+2=+4= did not deliver 7 as the result.

The solution to that was a bit tricky. But in the end I managed to implement it without a major architectural change. I only needed to make the current number a nullable type:

class NumberAggregator
{
    private double? currentNumber;
    ...

    public void ExtendNumber(char c, Action<double?> out_currentNumber)
    {
        if (c == '.')
        {
            ...
        }
        else
        {
            if (this.currentNumber == null) this.currentNumber = 0.0;
            ...
        }

        out_currentNumber(this.currentNumber);
    }
...

That way the CalculatorEngine can distinguish between an operator clicked after entering a number and an operator clicked after “=”:

public void In_ApplyOperation(Tuple<char, double?> input, Action<double> out_result)
{
    double result = 0.0;

    if (input.Item2 != null)
    {
        if (this.operation == '=') this.operands.Clear();
        this.operands.Push(input.Item2.Value);
        result = Calculate();
    }
    else
        if (this.operands.Count > 0)
            result = this.operands.Peek();
    this.operation = input.Item1;

    out_result(result);
}

It made me quite happy that no change to the overall design diagram was needed to accomodate the bug fix. I took it as a sign of a good design ;-)

Summary

Event EBC designs don´t protect you from forgetting stuff and writing buggy code. But still I think they improve my coding. They narrow my focus, because the domain stuff happens mostly in leaf activities:

image

Depending on your level of detail those atomic activities are comparatively simple.

Composite activities on the other hand seem complicated – but they are not. I even think they could be automatically generated from an EBC design. For now, however, I´ll stick to hand crafting my EBC code ;-)

Models

Since EBC diagrams do not show implementation details like classes, objects, interfaces they are true models to me. They abstract from a concrete platform. You could translate them to C#, Java, Ruby, F#, C++ etc. That I also find quite important. You don´t want to get stuck in implementation details during the design phase.

Print | posted on Monday, July 26, 2010 11:01 PM | Filed Under [ Event-Based Components ]

Feedback

Gravatar

# re: Improving the Event-Based Components Desktop Calculator

Looks like Dataflow Programming to me.
State Machines are a good way to handle the calculator I think. I started reading about imbedded programming and how to next state machines to controll complex event processing for user interfaces. We use them a lot here to control application states and UI behavoir (Hierarchical State Machines in particular). On this is that state machines can have their own thread and be actors or active objects. I think that is really powerful when it comes to using multiple cores on your modern CPU. The MS robotics toolkit supports the data flow or event based programming. They came up with a great programming model called the Coordinated Concurrency Runtime (CRR). It seems to have died, but, it allows the buidling of pluggable components, seems to match your napkin drawings. You can make the MS Reactive Framework do the same thing just with a different style of programming.
CCR - http://msdn.microsoft.com/library/bb648752
Reactive - http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx
7/27/2010 2:37 PM | Will Smith
Gravatar

# re: Improving the Event-Based Components Desktop Calculator

How about some real world applications?
I'm implementing custom LINQ provider right now.
Does EBC offer any help here? =)

What is the scope of appliance?
7/28/2010 11:59 AM | FallenGameR
Gravatar

# re: Improving the Event-Based Components Desktop Calculator

@Will: Yes, this looks like Data Flow Programming ;-) Or like Flow-Based Programming. Or like BPMN. Or like UML Activity Diagrams. Or Event-Based Programming. Or like a poor man´s version of Event-Driven Architectures.

I don´t claim to have invented much of EBC. Rather I´m trying to synthesize a pragmatic whole from different sources.

State machines of course come in handy when doing this kind of programming. To me they are a tool to keep EBC designs simple.

However currently I don´t want to diverge into too many areas. My primary goal is to show a pragmatic meta model for designing applications. What you do with that... whether you base your EBC designs on a state machine, that´s up to you.

As for the CCR: I´m very familiar with it. I´ve implemented a wrapper lib for it (http://code.google.com/p/ccrspace/) and worked with the Technical University of Vienna on a communication infrastructure to make remoting CCR based code very easy (http://xcoappspace.codeplex.com/).
7/28/2010 2:05 PM | Ralf Westphal
Gravatar

# re: Improving the Event-Based Components Desktop Calculator

@FallenGameR: Sure, EBC offers help for implementing a LINQ provider. The API of the LINQ provider might be fixed and non-EBC. But what you do behind such a traditional object oriented facade is up to you.

Think of API methods as triggers like button clicks in a GUI. They trigger feature processes in an EBC design.

Maybe I should show that in a blog article once.
7/28/2010 2:08 PM | Ralf Westphal
Post A Comment
Title:
Name:
Email:
Comment:
Verification:
 

Powered by: