

Decoupling inlined UI code - zt
http://twistedoakstudios.com/blog/Post1694_decoupling-inlined-ui-code

======
ejstronge
This is great point about a problem I've had in my early days of GUI
programming.

I'd take the author's suggestion a bit further: in terms of MVC a Controller
should always call the appropriate function on its Model but the Model should
check for an appropriate state before performing the requested action.

Collecting state information in the Model would also make it easier for Views
to adjust their appearance after a state change since there would only be one
source of this information.

------
RyanZAG
While this example looks pretty good now with just that limited functionality,
if you continued to use this pattern across a complex UI, your Setup()
function is going to be 1000 lines long and likely incomprehensible.

I like the idea, but I'm pretty sure there are nicer ways to set that up than
an arcane looking IObservable block inside a Setup() function. I guess it's
just for demonstration though, and in a real UI he would have those off in
their respective controllers and setup in their own methods.

~~~
stephen
> your Setup() function is going to be 1000 lines long and likely
> incomprehensible

Have you worked on a system that used these principles, and found them to be
inadequate, beyond an off-the-cuff read of this blog post?

I ask because I have built a system like this, and if your nightmare
1,000-line Setup() function is true, then my experience is that implementing
the same behavior imperatively would be 2,000+ lines of spaghetti code that is
an even worse nightmare.

For behavior that changes on multiple conditions (just like in the OP),
declarative programming is a win. Otherwise you end up coding "oh, wait, now
do _this_ " is in 2-3 different places, and invariably forget to keep all of
them in sync you're making changes.

~~~
to3m
I've always found such systems intolerably difficult to debug. Is there an
option for 1,000 lines of imperative non-spaghetti?

I've found that keeping the bulk of UI code in one place is the key to keeping
these things manageable. Ideally, each widget's handler should do little more
than affect whatever data it needs to affect, then call another function that
updates all widgets' states according to the latest data.

For stateful sequences of events (e.g., mouse drags) the rx-style approach is
a bit more compelling. Imperative code for that stuff is always ugly. But you
still seem to have the same problem of debuggability if you use rx, and
backing out of a state looks like it might be a bit of a chore.

Call me a Philistine, call me a barbarian...

------
pwnna
This does increase code complexity and make things harder to understand.

You can see a lot of this in Android's framework and it makes modifying the
simplest thing require a lot of looking around just to understand the code
base.

I think the approach itself is okay, but this is just the con in my view.

------
jtchang
I believe this is the architecture pattern known as event pooling. Though I
could be looking at it wrong.

------
chris_wot
I believe this is addressed by the Mediator pattern in the GoF's book.

------
pebb
AngularJS does this super well :)

~~~
stephen
I generally agree, although for my taste I don't like how Angular allows
declaring complex conditions inside the view as inline expressions.

Admittedly, it is succinct, and I'm being pedantic, but it seems like keeping
the expressions in the controllers and just exposing them to the view as
single, opaque values would be better separation of concerns.

(E.g. instead of "ng:show=a && b && c", you would only be allowed to do
"ng:show=nowInStateFoo" and in the controller you'd define nowInStateFoo=a &&
b && c".)

Hm. I suppose you could actually build Angular applications this way, by
opting in to the extra ceremony.

