GeppettoJS / backbone.geppetto

Bring your Backbone applications to life with an event-driven Command framework.
http://geppettojs.github.com/backbone.geppetto/
MIT License
203 stars 28 forks source link

TodoMVC and some thoughts #18

Closed creynders closed 10 years ago

creynders commented 11 years ago

Hiya, I'm one of the core team members of Robotlegs, and started recently working with backbone and marionette. As you can imagine I'm quite enthusiastic about the direction you're taking with Gepetto :)

Some thoughts and remarks:

  1. I noticed there's no TodoMVC app for Gepetto; if you're interested I can help out creating one.
  2. The enforcement of the execute function in the commands: would you consider a more loose approach? It's sth I really pushed in RL as well, in my experience commands are more versatile and powerful if the execute method is configurable (or optional), especially in JS. If so, I can take a look and see if I can come up with a non-breaking implementation that's a bit less strict.
  3. Again a request to consider a more loose approach: the passing of event payloads, now it's restricted to a single payload object, but if that could be opened up and an unlimited number of arguments could be passed to the dispatch method it would again make everything a bit more versatile and flexible. I suspect it was restricted in order to limit payload injection into commands? But it might be really beneficial to pass the payload values to the execute method as parameters instead/additionally (just the payload values, not the event type).

Anyway, if you're interested I can prepare a PR and we could discuss the benefits/disadvantages of the proposed changes.

geekdave commented 11 years ago

Welcome, @creynders! It's an honor to see you in this repo. I learned a ton about scalable de-coupled architecture from Robotlegs, and a lot of that came from your informative posts in the RL forums. I'd very much like to collaborate with you on the Geppetto's direction. So far we are using it internally at my company for two large (and very different) projects. But since I've been prescribing the architectural patterns, myself, I haven't had much feedback from the outside world.

I noticed there's no TodoMVC app for Gepetto; if you're interested I can help out creating one.

That would be amazing! I think the lack of examples is a huge barrier for people wrapping their mind around the benefits of a Command pattern in Backbone. Demonstrating this using the familiar TodoMVC app would be fantastic.

The enforcement of the execute function in the commands: would you consider a more loose approach?

I'd definitely like to hear more about this. The mandatory execute function is something I thought I was borrowing directly from RL... but perhaps I missed something. Let's talk about the use cases.

the passing of event payloads...if that could be opened up and an unlimited number of arguments could be passed...

As you mentioned, this was done to simplify the way the payload is injected into the command instance. Having named properties on the payload object also avoids the issue of ordering of parameters, which I think could be a maintainability issue if it was changed to direct parameters passed to the dispatch method. Nevertheless, I'd like to hear more about this use case and how it might lead to more flexible designs.

Looking forward to discussing further!

creynders commented 11 years ago

I think the lack of examples is a huge barrier for people wrapping their mind around the benefits of a Command pattern in Backbone.

Agreed. I had a little time yesterday, so I already started. I'll push to a repo, once the code makes a little sense.

The mandatory execute function is something I thought I was borrowing directly from RL... but perhaps I missed something.

Yeah in v1 it was enforced, but I was one of the people who started pushing towards a more loose approach with commands in general, which we followed in v2. I have a love-hate relationship with commands. On the one hand I deem them necessary to achieve a decoupled and flexible system, but on the other hand ... aaargh, there's always so many of them. What I wanted to be able to do (and what I immediately yearned for when working on the TodoMVC app of Geppetto) was to wire events directly to service/helper/model methods. With RL v1 my projects were riddled with commands that did one thing only: call a method on an injected instance. I wanted to get rid of all those middle-men commands. Problem was, I couldn't simply add those service class methods as listeners to the system events for 3 reasons:

  1. I'd loose lazy initialization for the service classes.
  2. It could lead to a mess, very fast, with service methods added as event listeners here and there.
  3. The service method would have to accept an event as a first parameter. Yuck!!

Especially the first one is totally unacceptable, but the last one is ugly too since it would tie them to the system messaging type (yeah, I'm one of those idiots who likes to swap system messaging mid-project: from events to signals, oh no, back to events) and would severely lessen their reusability. So the solution was to allow to map service classes as commands:

map(RetrieveTweetsEvent.RETRIEVE_TWEETS)
    .toCommand(TwitterService)
    .withExecuteMethod('retrieveTweets');

This is what we implemented in RL v2. (That said, I wasn't satisfied with the method name as String parameter for the withExecuteMethod so I created an extension that allows to metadata-tag your methods with [Execute]) Anyway - this is getting long :) - I think it could be beneficial to allow such an approach in Geppetto as well. That's also why I asked about passing event payloads as parameters to the 'execute' method.

I'm not entirely sure how this could be best achieved though. JS is an odd language. And Backbone isn't RL. So could be I'm trying to push into a direction due to old habits that I should get rid off.

A last question: do you allow your views to update their model directly or do you take the strict route: view -> command -> model? On the one hand it seems a bit overkill, since your views have a direct reference to the model anyway, but on the other hand it does make everything more flexible, e.g. the view's model could be a little different from the model stored in a collection for instance.

geekdave commented 11 years ago

@creynders just a heads-up as you're working on this that I switched Geppetto's test framework from qunit/pavlov to mocha/chai. Pavlov was not being maintained, and mocha seems to be getting a lot more traction in the community than qunit. The switch was pretty easy, so I went ahead with it.

geekdave commented 10 years ago

This was the historic issue that spawned the whole Dependency Injection API in Geppetto. Now that it's been implemented, I'm closing this. @creynders If there's anything from the above that you'd still like to discuss, let me know and we can track it as separate issues.