Skip to content

Archive

Category: Software Design

Our code is rarely as neat as we’d like it to be. And sometimes we’d like to make it do something, and we’re not sure how. Depending on… …a lot of things, there are two ways around the problem:

  1. Go with the code. Work out the problem bottom up and wire up everything as best as we can.
  2. Bend (and break) the code. Work out the problem top down, lay out a neat solution and (re)wire up everything else according to how we think is best.

The main argument for going with the code is that it won’t break anything. Honest, it’s true. I’ve seen it done with extreme care and it works. But… It doesn’t make it easier to make the next change, and the next change, and the next change.

Working top down will break the code, and should be done with care too. Sometimes breaking and repairing code is better than just going along with it. But just because the code hasn’t been written to solve the particular, new problem we’re looking at needn’t mean it’s bad code.

A Story

It was an ordinary day. A colleague had been working for a couple of months on a client side bridging component. We wanted the same functionality on the server side and I just thought it would be neat to share the code. So I suggested we do just that and he told me the component couldn’t be extracted from the client. I said it could, and he asked: how?

Separation is rarely down to our software’s effective logic. For practical purposes, anything can be separated from anything else. So I just said:

“Use the Sword of Faith”

A couple of days later, the bridging component was all neatly… modularized. The code was cleaner and more readable (not my opinion – I didn’t even look). Unsurprisingly (and however unfortunate) the guy in charge of our server refused to use this code, and moved on to write their own. Whatever project this related to was postponed, and we moved on…

The Evangelist

For all the medieval hype surrounding it, the sword of faith is a well named design tool. Ideally it should be as sharp as a Katana, and operated with surgical precision (that and lightning fast coding skill, right?). Why a sword, then. Well there are other tools you might consider working with when extending and fixing up your code:

  • The mace. You can maim and mangle large sections of your code in the name of a good cause, leaving behind you many bugs for others (or more likely, yourself) to fix later.
  • Biological weapons. You can add a couple of lines of code here and there to get your new feature to work. This code won’t make sense in context and will likely contribute the overall sense of rot and decay emanating from your codebase.
  • The Hydrogen bomb. You can delete whole classes, even packages. At this point extending our software isn’t a problem. The problem is we’ll have to write the code all over again.

In contrast, there are several techniques founding our belief into the sword of faith – namely, that code can be improved locally and that local improvements over time can significantly reduce our overall sense of helplessness looking at (what looks less like) the ambient mess.

  1. Define a ‘good solution’ for the problem at hand. Inasmuch as possible, the solution should hold good considered in isolation.
  2. Retrofit the ideal solution onto existing code, pass (existing code fits the solution) or break (existing code must be modified)
  3. Rewrite/Refactor as little and as much code as necessary.
  4. Be comprehensive, not exhaustive. If you’re unsure whether something needs/to be changed or fixed, you (or a compiler, or a unit test, or a tester…) will find out later. Trying to be exhaustive may result in changing too much code, getting a migraine, breaking more code and losing hair.

In similar situations, many programmers will either offer to ‘entirely refactor (meaning, rewrite) the code’ or ‘just make it work’ (aka muddle through). These attitudes underly dubious beliefs, explicit and implicit.

  • The explicit belief that Order and Chaos cannot coexist, (let alone interact) within our codebase.
  • The implicit (and somewhat Luciferian) belief that this time we’ll get everything right.

Don’t buy into this s**t. Use the sword.

The Brothel

Back to my code, here is what I wanted to do today. I am rewriting the ‘go back to main menu’ feature in Antistar. Yes, I could muddle through, but I won’t. Here goes.

1. Destroying the game session is (almost) all we (should need) to do.

I have a class named GameSession. This class is instantiated by a command (GameStart) and is meant to contain the game session (everything that goes on while playing) as opposed to the game container (the menus and other bits and pieces that frame the gaming experience).

So I’m guessing deallocating the game session object is a good step towards going home.

While many objects reference the session, most (all) of these are back-references from aggregates. Say we just called [session release], would [session dealloc] be called? Sadly no. It took a couple of calls to release to get dealloc to kick in. Not being the local reference counting expert, I use a little trick to get me out of trouble in these situations. We can set a breakpoint in an object’s [ retain] method, overriding it as thus:

-(id)retain{

return [super retain]; // set a breakpoint here

}

I find it convenient, although it is crude. I don’t keep this code after I find what I’m looking for.

2. Everything must go

It isn’t enough that dealloc be called onto the game session object. We want the whole hierarchy of objects owned by the session to ‘collapse’. I don’t have a clean implementation of [GameSession dealloc], so I’m guessing now is a good time.

The idea is simple. All objects owned by the game session should get deallocated, unless proven otherwise — recursively.

So I spent about three hours writing miscellaneous implementations of [dealloc] (I’ll explain later why I don’t do this upfront). Amusingly, after I finished I found the code crashing exactly as it had three hours before:

  1. The display link dispatches to my EAGLView
  2. My overlay view ‘ticks’
  3. Talkback display attempts using a zombie instance of the… …game session.

So why is my EAGLView not being destroyed?

  1. Retained as a child of the main window.
  2. Retained by display link using EAGLView’s startAnimation method.
  3. Retained (and most likely, released again later) by a couple of system level thingies.

Let’s ignore (3) for now. So practically this says we should remove the 3D view from the main window and unregister the display link callback. While it may seem obvious, it is altogether pleasant and reassuring to find about it this way, right?

There we go:

  • EAGLView provides a (void)stopAnimation method (this is code provided by the big guns).
  • We have removeFromSuperView, or whatever it’s called.

After adding this code to my MainMenuAction, I had a slightly more worrying occurrence as an auto-release pool attempted to deallocate the view a second time. This reminded me a couple of useful points:

  • When using NSZombieEnabled, we can find out the type of the zombie being accessed by checking the console, if anywhere.
  • self.myRetainedProperty = foo; will retain myRetainedProperty. myRetainedProperty = foo will not.

After fixing this up, I could observe the following behavior when pressing the menu button:

  • The screen goes blank
  • The overlay view (ui controls) is still visible. Not much of a surprise. For better (and especially for worse), I use a UI view from a nib file for my controls. As it is, this view exists independently from the game session. It isn’t clean, but it isn’t really useful to ever get rid of it either. Notwithstanding I can press the menu button over again, causing an exception and demonstrating that, if we’re keeping a view after the game session has been discarded, we need to do some cleanup.
  • The game menu isn’t showing. Not a surprise either. The game menu shouldn’t be part of the view hierarchy while we’re playing, so I guess we’ll have to put it back.

3. The final touch?

I made a trivial interface, GameSessionListener:

@protocol GameSessionListener <NSObject>

-(void)gameSessionEnded;

@end

This lets me pass an instance of the game container to the game session, so after the game is over the container can put up the menu again.

While this works, starting and exiting over and over causes bugs on the game menu. It looks like the view hierarchy interacts in unpredictable ways, as eventually the menu screen goes blank.

But hey, that’s what the sword is for, right? :)

Needless to say I went back to my code a few minutes later. UIViews don’t just go blank, do they? and that view had to interact with something. So I looked up whatever views (not many) are somehow shared between the game container and the game session. Then I found the view root  (a kind of custom thing, not the absolute view hierarchy root) was being over-released.

What have we gained?

In the previous version of Antistar, the game exit/re-entry process is fairly robust. Meanwhile, it involves a lot of cookery for no special reason other than me shying away from just saying ‘let’s tear down everything’. In theory, tearing everything down should be easy. In practice, if it’s not then we probably have an unsolved problem that’s not good being left unsolved.

The ‘cookery’ occasioned hard to fix bugs. Not tearing everything down means having dirty objects lingering, leading to functional bugs. I haven’t run the new code through instruments and I’m bound to find leaks. Good point here. Leaks, unlike functional bugs, can be detected automatically.

Not tearing everything down also defeats one of the useful applications of a so called game container. Running not just one, but several games under the same hat.

So I started with a clear goal and solved the problem as I intended. I wanted to clear the game session by deallocating it, and this is what it does. What I did not intend to get over and done with today (yesterday, rather) is memory management. Yes, I feel I have a head start on this, but that wasn’t quite the issue here and I’ll look into it another time.

Epilogue

  1. I didn’t go around analyzing this and that, eventually deciding that I should rewrite the whole whatchamacallit (don’t use the hydrogen bomb)
  2. I haven’t hacked up a quick patch (no biological weapons)
  3. I added code that’s useful, concise and clear and contributes functionality to my app (use the sword)
  4. I haven’t fixed or otherwise ‘improved’ anything that didn’t need fixing (don’t use the mace)
  5. I spent about 7 hours on this f***ing thing (have faith).

Hairlock - dev pic

Let’s face it, Good Old Fashioned AI was practically (if unintentionally) invented for making games. Why? Because it works well with clean, clearcut data sets. So instead of lamenting that the lab methods only work with ‘block-worlds’, take notice and realize game worlds are all ‘block-worlds’. Or shall we?

I should be elated I suppose. I wouldn’t be considering implementing a general purpose solver unless I actually had a use in mind, and I if I do, then I’m in for fun and the weather, since I get to do the kind of programming I like best – as if coding a game wasn’t hard work, hard fun enough.

A conversation

Hyde: Your objects and functions. All of this lacks structure.

Jekyll: It’s because I want to address a few more practical problems before normalizing the structure.

Hyde: Well, I think it’s time. Actually, aren’t you getting tired of reusing the same recipes over and over?

Jekyll: We’ve been through this before. Sometimes applying the same recipe over and over is better than attempting to normalize everything, only to realize that we weren’t applying quite the same recipe over and over.

Hyde: Just a simple heuristic solver would breeze over the tedious steps you take in programming your game logic. Plus you could subtly vary the solver’s behavior to emulate agents with various degrees of intelligence and contrasting personas.

Jekyll: Specifically what can a problem solver do, other than add more mess to the ambient mess?

Hyde: Come to reason. Our problem solver will solve our problems.

Jekyll: Can I trust you?

Hyde: No, but you have to.

Jekyll: How about performance. Won’t this ruin performance?

Hyde: Probably not. Once you’ve objectified search steps, you’ll find it easy to stagger processing. Besides the solver load is independent from  the rendering/animation load.

Jekyll: Back to the original point, why take excuse of the lack of structure to suggest introducing a problem solver?

Hyde: Elementary. Solvers don’t look at individual steps. Good solvers heuristically chain steps without consideration for what each individual step does. Ergo, programming-wise writing a solver will force your game code into normalized structures.

Jekyll: Sounds Ominous.

A Piece of Cake

Chocolate isn’t enough. The world is not enough. I’ve been wondering all week why my girlfriend has been babbling about how she’d been thinking of ordering a cake, and how it would be great to have a cake done to spec. Even asking me if I’d like mint chocolate. I don’t really think mint and chocolate are such great pals.

Either way. Enjoy the cake – or the picture at least. See you in the app store.

Here’s an idea that may work for some of us. I’ll try this next week if, and only if, I run into annoyances:

Let’s take an example:

  1. We have a Model class. The model class is just a placeholder for data.
  2. We have a Request class. The request class is just querying a server for data.
  3. We have a controller that (a) fires the Request and receives its response and (2) passes the result to the model.

Does the controller need to effect this operation? Think not. Maybe the controller shouldn’t control this.

The business logic argument

The described operation is exposing too much of the model in the wrong way. The controller should care about how the model updates only insofar as the view may need to render something about it.

If we need the view to let the user know that a request has been sent, what we’re really asking for is the model to fire an event to let us know, and the controller to handle this event.

The clarity argument.

Controllers easily get intricate. If we can move something from the controller to the view or the model, we should.

I like to have struct like classes that not define any operations. This isn’t incompatible. More often than not, model operations can be neatly defined using commands. Otherwise, we can fall back on a model/data split, where the model is a kind of ‘data controller’ viz. the model holds no state, only business flow, and the data holds no function, just data.

The integration argument

If the controller is manipulating view and model states too finely, service integration is reduced. Instead of having qualified, usable views and models, we have particulate, D.I.Y views and models that turn out, more often than not, to provide the kind of flexibility attracting bugs and reducing maintainability.

A particular, enlightening scenario is when the model or view expose sufficient state that they could not avoid being put into an inconsistent state by a careless controller. Hey, we got a nice little rule here:

If a view or model’s interface allows putting such view or model in an inconsistent state, there is too much logic in the controller.

An organic, yet ideal controller

An ideal controller should…

  1. Hold no state
  2. Receive events from the view and model
  3. Issue high level commands mapping the model to the view, and vice versa.
  4. Be thin.
  5. Look boring and redundant.

Why (5)? well, that’s good, and that’s why we often wonder what the controller is for. Here’s an example:

  1. Play button is pressed and fires an event
  2. Controller handles the event and invokes the model’s play method.

That’s boring, yet performs an awfully simple function: decouple the view from the model. Because it is boring and simple, it also makes a fair allowance for ‘becoming more complicated later on’ without anticipating over much anything at all. This isn’t planning what features we’ll need in six months, it’s just a kind of placeholder for future intricacies.

On the other hand, here’s a counter-example

  1. Play button is pressed and fires an event
  2. Controller handles the event
  3. Controller creates a download stream.
  4. Controller receives a callback to indicate the stream is connected (and sets a ‘control state’ flag)
  5. Controller  changes the color of the play button.

The good news

Interaction can easily get complex. Models and views can also get complex. Let the controller be thin and stateless. If our controllers are more concerned with the semantics of interaction, and less with rendering and model updates, they are better controllers.

The bad news is, it’s easy to push too much logic in a controller. The good news is, it’s easy to take it out.

I wrote a little, here and there, about the so called F* meta-pattern. I created F* to close a bag of worms. However… …F* is merely a minority report. A kind of footnote to MVC.

In the grand scheme of corporate front end development, MVC stands out for super-structure. To begin with, it doesn’t take a genius architect to work out labour separation. We named Max, Vincent and Connie. How many Frogs would it take to maintain an F* app?

Incidentally, the bag of worm re-opened when I tried to explain the command pattern to a new recruit, and got a poor old MVC natural on my doorstep the next day.

What would you do? Rewrite the whole thing? I didn’t. I tried fixing it up. Now’s a time for rambling and recriminating.

Post-scriptum

OK then. This post is about MVC the way people do it ‘their own way’. Without using frameworks, and without using the command pattern. This post doesn’t contain answers. It’s just listing lazily a lot of scary/worrying/time consuming issues.

Command patterns and frameworks have one thing in common. They’re a little heavy. Heavy can mean a lack of concision and elegance. It can also imply conceptual overhead. Heavy can also cover an element of cultural difference. Either way…

…heavy isn’t for everybody. I didn’t write heavy code when I was 17. I did write some cool stuff though, including stuff I would only half-guttedly replicate today. So this post is raising an issue: can we still just write a little bit of code, and get away with it?

Finally, before you read away, be assured this isn’t a spoiler. If you want to do your own MVC stuff without a command pattern and without a framework, it won’t protect you against unpleasant surprises.

May refactoring be with you.

It all started with a view, a model and a controller…

Back when I started ‘doing MVC’…

  1. Write a *Model* class containing a few bites (no bits, no bytes) of data.
  2. Write a *View* class batching a couple of widgets.
  3. Write a *Controller*. The controller instantiates and refers the *View* and the *Model*.
  4. Let the controller listen to events from the view and the model.
  5. In response to view/model events, let the controller update the view and modify the model.

Really doing it

If you really are doing MVC the wild way  (or maybe just writing a moderately sizable app) then you’ll need to go a little further:

  • Writing components. For lack of a better word, I refer to ‘mini-apps’ – bunches of MVC classes that work together to realize a feature in a larger app – as ‘components’. Components needn’t be hard to write, and in theory the ’scaling up’ question needn’t interact with whatever well-formed approach to MVC we’re using (why? because either way the secret is to keep components decoupled. A ‘keep the bags of crap small enough’ idea that I’ve been pushing forward in my posts about F*).
  • Writing ‘models’. I hope you’re not trying to get your way around TableModel, ListModel and other API induced models, and how they should fit in our MVC collection. Because I am, and I wish to be enlightened.
  • Keeping it small and simple. We don’t want our apps to grow any bigger or more complex than they ought to be. Or do we? Unfortunately trying to keep front ends manageably small is a good way to make them unbearably intricate. At the other end of the scale, fixing the same bugs in countless apps ‘prototyped one another’ resurrects Taylorism.

Before things go wrong

Before things get really nasty, here are the tell-tal signs that might finally help us understand what to do with our MVC naturals.

Getting confused and arguing over it

When I started with my 3D engine, I considered that 3D assets were view. Unfortunately, 3D geometry affects game logic. Sometimes also, 3D assets are adequately used to hold data that (I think) ought belong to the model. Some guys quickly judge this kind of situation and get over it. Your colleagues from the front end get into heated discussions about what goes in the M or V or C. You think it’s a waste of time and you’re perfectly right. If there’s no hard business/real world constraint driving towards a correct answer, it’s like naming a baby can get. Oh my.

What is the controller?

I felt immensely relieved when I heard a colleague say this for the first time. Here’s why. Because every so often, the view is specifically written for the model. Most of us understand why you would want to change/write a different view for the same model. Many of us acknowledge that views are disposable app-fodder. Views are ad-hoc. In short, the view root can listen to widget events and effect model changes directly. So why do we need a controller?

Why we cannot write clean components.

Because the UI is bullshit, or the UI is bullshit.

If you give the UI work to a UI designer, they’ll think about usability. They’ll make a UI that has weird shortcuts. The component hierarchy won’t match the model’s functional hierarchy. In short, the UI won’t map your model closely. If it’s a good UI, it will even get literally (legitimately) intricate. Meaning that the hierarchy will be unclear enough that you won’t be able to ‘just take a component and drop it into another app’. Business apps should be more tractable. That’s because…

Usability is irrational bullshit. Unfortunately business apps also are bullshit. They are boring, slow to use and un-fun. That’s why people are paid to use them.

What are view states?

We’re writing an app allowing people to choose shirts. Shirts come in different colors. The UI designer suggests that the ‘add’ buttons in the shopping cart should match the shirt colors. What’s going on?

This is just a silly (and actually, redemptory – the ‘color state’ is blissfully captured by the natural data model) version of the model-view/view-model dilemma. View has states that aren’t perceived to partake the model. However such states can be linked to the model, and more often than not, these states also persist in real apps (as in, real-world apps persist their UI states). Here are three perspectives on the situation:

  1. If it’s a variable, it’s a state. State belongs to the model. My first tech lead frustrated me a little by implying this is obvious. Is it obviously right to conflate the data, or (as he suggested) whatever is the data model (4th tier alarm!) with cosmetic stuff like font size, colors and alignments?
  2. Add view.model, view.controller, view.view to your view package. Call a cat a cat. While this may seem logical, it needn’t take us very far. If we’re not serious about our view, that’s OK. Otherwise we’re reducing separability in unpredictable ways. Most apps do MVC just to keep things neat and clean. If separability has business strings attached, there will be a price.
  3. Don’t confuse data and model. More specifically, don’t confuse the view model and the data model. That’s a weird avatar of (1) and I don’t want to be sure what to make of it.

Is my controller holding state?

Yes. That’s a prime rule for a well formed MVC instance (an app written using MVC). The controller should hold no state. I would be so very delighted to announce that controllers cannot declare fields. Err, I’m afraid we started off declaring a view and a model field under our Control class. I’m sure you don’t think we are doomed yet.

But it’s not over. Now we’re ready to add ‘control states’. We’re also ready to write state machines. Yuk, see below.

I know you know. Call a rabbit a rabbit. These are states which belong to the control layer. Let’s add a control.model package. Unleash the Geek Inside.

Hyper-hacktivity

MVC naturals are incredibly hackable. That’s one of the things that got me writing tonight. I’ve been hacking an MVC instance mercilessly for 10 hours nigh. It’s very neat, because I spent three days this week trying to ‘rehabilitate’ the same app. Now I feel ready to start over. It’s good to be able to sort things out and release on time. But if I save one day every time I waste three, how good can it get?

Thinking about it, here’s one reason why MVC naturals are so hackable: statemessness.

  • Your GUI library is object oriented. It’s full of weeny controls that duplicate model state.
  • Your model is the primary state-holder. Surely the model knows (nearly) everything.
  • Your controller wouldn’t be so easy to write if you didn’t buffer a little state here and there.

Hackable. No matter where we’re writing code inside an MVC application, no state is ever far from us. Maybe not quite the right state, yet, in a first (and durably misleading) approximation, just about right.

Don’t hide behind your framework

MVC frameworks do that. If you look into their implementations, you’ll find that rules get broken. Basic rules. I see three solutions:

  1. Rules are for n00bs. The powerful magic behind singletons, static, event broadcasters and (while you’re at it) the C pre-processor is trickery that everyday coders should be interfaced with / insulated from, not exposed to.
  2. MVC frameworks are bad.
  3. The rules are bad.

Unit-testable or clear and concise?

I’ve been trying to put some of my latest MVC natural under unit test. Since I’ve been trying, and trying often leads me to explicit stuff I’d rather, for the sake of clarity, didn’t show up, I feel that natural MVC is biased against unit tests.

Inter-act

STOP.

By now, if you’re still reading you should probably go for a coffee break. Trust me. After all this article is just food for thought, not very thoughts.

Nice to see you back. Now that I’ve dusted around a little of the dust in the dust-bag, let’s muse a while into the muddle-dy swamp.

How things go wrong…

The shortest path is never the best path

Here are a few examples:

  1. It’s faster to emulate a button click than to separate action from reaction. The play button starts playback. The play menu item also starts playback. I want exactly the same thing to happen when I press the play menu item and when I press the play button. Sooo… I hack something up to pretend the play button was pressed when I hit the play menu item.
  2. It’s nearly always faster to pre-empt view updates. The controller knows what the view wants to do. The controller knows what the model will be like after we change it. In fact, the controller needn’t read the model, because the view reflects the model state faithfully enough… especially when we get started off and our view/model mapping is simple. I remember decomposing roundabout VCMCV routes using powerfully soporific sequence diagrams for the sake of principled colleagues. I also remember breaking my own rules and trying to explain what kind of risk is involved using whatever shortcuts.
    Now that I think about it…. (gasp) we don’t even need to update the model every time. That is, until auto-save stores a half-baked image of our data.
    Back to the original point: do we need a controller, or a model? Do we even need classes? Why not just use punchcards?
  3. Re-writing it is faster than just using it. MVC naturals tend to generate hierarchies. These hierarchies, more often than not, connect on an ad-hoc basis. Lay it out in UML:

    “it is 7:50 pm and you want to go home. You are ‘here’. The function you need is 10 clicks away on the class diagram and 3 steps are blocked because the hierarchy doesn’t back-wire. Re-write? Use a singleton? Introduce dependencies over 10 unrelated classes? Expose your lack of style and insight (russian doll message passing)?”

My button back-fired

Here’s a list widget. The user selects an item. A view event fires. The model updates.

Here’s a list. The list selection gets remotely updated. A model event fires. The list widget gets updated. A view event fires. The model gets updated. A model event fires…

Why is this happening all the time?

The inheritance delusion

It’s a text-book truth that inheritance isn’t an implementation level commodity. That’s probably why inheritance is hailed as a technique improving reusability and concision.

I took a controller this week; abstracted a base class off it. That simplified my coding four more, similar controllers. How are they similar? Well, they kind of work the same as the first one.

Truth is, I did it to save time and clarity. I’ve also seen what happens when we keep at it. Controller code isn’t especially concise. App controllers are meaningless idiosyncratic beasties anyway. Not your rationally bound mammal to mouse to cow inheritance anyway. If an app controller is a meaningless idiosyncratic beastie, what would an abstract app controller be? Or its grand-grandson?

Before you know it you’re abusing the decorator pattern. Classes implement functions for no reason, and nobody can understand a derived class until they’ve mastered five ancestors up the chain.

MVC naturals make it easy to use inheritance in this way. Or is it just inheritance that’s easier than delegation?

Your controllers are cursed down to the 13th generation. Amen.

The state machine delusion

Controller states are non committal. Unlike data-grave entries. Unlike serializable model data. Unlike view states, which at least, get rendered. Add a little flag here. Add an enum there. It doesn’t matter if two controller state-holders describe overlapping state. It can only hurt a little.

Here we are. It’s ‘kind of like a state machine’ just less complex and more complicated at the same time. However, all we need to keep ahead of it is a really good debugger. Well, I’d rather go and sink my own boat.

Until next time

It’s nothing like I’m done. I’m expecting staffing this experiment. As I stated at the beginning, there are many reasons not to go heavyweight. So I still need to find a way to get us sitting atop Pandora’s box. If there’s a way little bits of code mightn’t spiral out of control, looking for it is helping out, not brandishing glossy patterns no teenage coder would bother with.

Once again I’m about to do the wrong thing – forgo my assumption that stumbling steps are enlightening and not writing this post. I’ve just completed writing a unit test for a foo():Void haXe function with no flow control to its name. More about this another time.

Bear in mind, this article isn’t about what is or isn’t worth testing. My first step into TFD consists in having a fair go at writing tests before I write the code, without breaking my usual design flow – correcting my design flow is OK, if that’s what it amounts to. Correcting, yes – breaking, no.

Can we test the main() method? Do we want to?

I’m taking over a colleague’s work, now I’m sniffing the Main class and thinking hell, what shall I do with it. Test? Well yea, I should test it first. Since there are not unit tests for this project yet, I might as well consider it to be legacy code.

My colleague did something that I tend not to do – they just use Main.main() to instantiate a singleton. I guess it should really be a singleton but the point is, they escaped the static logic behind main. So I’ll follow in their steps and instead of testing main(), I should probably test whatever gets instantiated by main.

Unfortunately, as a good initializer does, mine mostly invokes other initializers. Essentially a constructor is a static function. So yea I could pass an array of  classes and instantiate them by reflection, but I don’t want to do that. Too much trouble.

I had the neat idea to just call the constructor to make sure it works, but that’s not a unit test – that’s actually testing the whole f*** thing. Too integrated.

Why I don’t feel like testing main() and constructors anyway?

I’d like to test how my code changes the software system I’m building. Although I’ll come back to this later and discuss, a function that doesn’t return value isn’t making local changes, so from this point of view there’s nothing to test inside the unit.

So what shall I do?

Flowing with TFD?

Here’s my problem with test first development right now. I need a method that flows. If it flows slowly, fine, but right now my flow is frozen. Let’s get flowing and try this…

  • I’ll always write a test for each function. That’s easier than  asking everytime whether to write a test.
  • If I can’t test the function, at least, I’ll document the test function with my design intention for the non-test function – that’s because I need somewhere to write my design intention. Then I’ll past this doc in the function’s code body so I can use it to write the actual code (that’s because my STM is very limited)

I’d like to still call these functions to make sure they don’t fail. That wouldn’t be a unit test, however. Oh my…

Working notes

No time for a conclusion today – just a few ideas

  • In absolute, I’d really like to write my tests first. This is why I’d prefer to write an ‘untestedConstructor’ function rather than no function at all in the test class. untestedConstructor() may seem horribly pedant, but I like it. This way you know I haven’t tested this by looking at the tests. Also, I can move design comments to the test class – if the tests are gonna stand for documentation, I think that’s alright.
  • So far, I only note I find it difficult to test root initializers. The type dependencies involved make it appear so difficult as to be counter productive. However, even with a statically typed language such as C++, doing this is likely not impossible (just map another .c file to the same .h file?).
  • One view about testing is that only state transitions matter. ‘unit’ testing consists in testing a class. Applying this, we could say that a method that causes no local change needn’t be tested.
  • Surely, a controller doesn’t manipulate it’s own state. A controller should hold no state. Does it mean a controller shouldn’t be tested? Oh my, controllers are were the case logic of a program resides… Maybe a productive idea – how about if we extract the case logic, so that the case decision can be returned from a function as a value. My counter-intuitive bet is that such functions should then be private – unfortunately, I heard over and over that a good unit test focuses on the public interface of a class. More contradiction. Or maybe we should just distinguish ‘do’ classes from ‘case’ classes; then we’ll have a good reason to make ‘case logic’ methods public.
  • Another view about testing might be that it is the behaviour of a class we are trying to test. Even if a class doesn’t manipulate its own state, we still want to assert whether the changes it makes to the outside world are as intended. TDD programmers that use mock objects liberally seem to be on this side.

Enough musings for today.

A few months ago, I put quite a bit of work into understanding an MVC framework called PureMVC and getting a team up to speed using it.

I didn’t like the PureMVC thing too much because it’s so heavy. In this post I described a strategy for doing MVC with your own, home baked MVC pattern instance.

Do you bake MVC? Here’s a way to get your three layer cake from the designer’s pencil to the forge.

Ideal means this stuff is paperwork. I haven’t really tried it – but frankly speaking it’s mostly a simplification of what goes on in PureMVC, with a little bit of salt. Bon Appetit

An ideal MVC instance

In this model, the software is structured around three broad categories instantiated as packages.

  • View classes. View classes use some GUI API such as flash, java swing, OpenGL or the like. View classes also hold view specific data(1). When the user performs an action, such as clicking a button, the view handles this action by firing an event (see below).
  • Model classes. Model classes hold your application data.
  • Controller commands. A controller command is a command that changes the way the application reacts to events from the model and view, rather than changing the view and model directly. Typically, a controller command does nothing except register callbacks causing such or such event to trigger such or such command. Additionally…
    • Model actions are commands that change the model in some way. These commands operate only on the model. When the model has changed in some way, and we want to update the UI, the model needs to fire an event
    • The UI is controlled by UI update commands – commands that change the UI in some way. These commands operate only on the UI.

More about events

In the above model, note that neither view or model ever handles an event directly. This is not to avoid type dependencies, but to avoid conceptual dependencies:

  • Maybe an animation just finished in the view. If the model handles this event, the model is doing something based on the fact that an animation is complete. Even though the actual view type is hidden from the model, the model now requires making a big assumption about the view to operate.
  • Maybe the model changed in such or such way. It may be that this causes just one change in the view, but it maybe that the view needs to update in many ways, or it may be that we are using a general purpose view component that is used in combination with concurrent models.

Also note that a view or model doesn’t directly instantiate commands. This is consistent with the fact that the view shouldn’t know about the model (and vice versa). There are many cases in which it may be convenient and safe to allow the view to know about the model; however, this is a simplification of the ideal instance described here, so to stick to the general rule, the view should generate a SEND_MAIL event, even though it is obvious that this event maps to the SendMail command.

Lightweight versus heavyweight events

When writing your application, you will often need to send quite a bit of data along with an event – for example if a view needs to update a table, you need to send whatever needs to be updated along with your event, not just a message.

In this case, you have two choices:

  1. Use untyped event data. This is in some ways unsafe (more parsing/relying on implicit data formats), but it saves the trouble of defining additional structs or classes to store event data.
  2. Use typed event data. It is commendable to include event definition in a subpackage, e.g model.event, view.event

More about the event dispatcher

To make the above work, you need a kind of event dispatcher that can broadcast events to receivers. All your view/model classes should be able to access the dispatcher so that they can trigger events. Your control commands should be able to access the dispatcher so they can register callbacks.

It may be a good idea to expose the dispatcher to the view/model and the controller commands using a different interface. We don’t want view classes and model classes to modify our event to command bindings accidentally

ViewManager and ModelManager

When a command is instantiated, it needs to get hold of the data that it wants to manipulate. A simple way to allow this is to define singleton ViewManager and ModelManager. So for example the ViewManager contains all the views, and ModelManager is the root of the model’s data hierarchy.

How does the application start?

You may have noticed that it’s the job of command to specify bindings from events to commands. This leads to one of those chicken and egg problems – which one started it all? an event or a command. This doesn’t really matter, but here are two solutions anyway:

  1. Use a Main command. Then your framework needs some kind of bootstrap class that you call start() on.
  2. Invoke a command to bootstrap your application.

How to use the above while enforcing feature driven separation

It may be a good idea to combine your MVC pattern with some degree of feature driven separation (I wrote a lot about the F* Meta-Pattern and feature driven separation somewhere else). Here’s how a simple, non adventurous way to do it:

  • Break down your controller package into subpackages – one package per feature.
  • Use a controller command to register all the callbacks and commands related to each given feature. This is the ‘feature root’
  • Bundle additional commands required to realize your feature in the same sub-package as the feature root.

There are pros and contras to the above approach, compared to a typical F* instance:

  • PRO 1: In many existing workflows, we use WYSIWYG UI builders to generate our views. The original F* pattern typically requires moving back UI building into the code, because you need to be able to add widgets as part of feature code – in F*, your ’send mail’ feature will require you to add the send mail button to a toolbar – that’s the price to pay if you want the UI to be correct once you have the removed the mail feature.
    This is further reflected in the way UI designers work. In cool applications, the UI is typically very integrated. Removing a function often means redesign in this case.
  • PRO 2: In many applications, most features rely on a core data model – i.e most of the data is used by several features. F* fragments your data model across features and leaves the generation of the core model as a refactoring exercise. There are many cases in which designing the data model as a self contained entity, adding stuff to it over time, maybe more efficient.
  • CON: F* allows you to delete a feature by deleting all related classes. With the above strategy, deleting the feature deletes only application functionality, not widgets and model data related to such functionality.