Stiamo costruendo un'app basata su Flux / React e stiamo provando a stabilire un pattern scalabile per configurare i percorsi e registrare le dipendenze. I due approcci che abbiamo possono essere categorizzati come "distribuiti" e "centralizzati"
DISTRIBUITA:
Questa versione ci consente di distribuire la configurazione intorno all'applicazione e consentire ai sottogruppi di lavorare sul loro pezzo dell'app senza dover modificare diversi file.
var app = new App
app.register([
re quire "dependencyA",
require "dependencyB",
require "dependencyC"
])
// dependencyA
module.exports = function (app) {
// registers self with application
app.registerItem('foo', {
// method called by application on 'start'
start: function (app) {
// can obtain previously registered things in start method
var previouslyRegisteredThing = app.getRegisteredItem("thing")
}
});
// returns some configuration
return {
routeName: "foo",
path: "/path/to/foo"
}
}
// App
var App = {
registry: {}
config: {}
registerItem: function (name, stuff) {
this.registry[item] = stuff;
},
register: function (items) {
for(item in items) {
// let's item attach itself
itemConfig= item(this);
// dynamically add configuration
this.config = extend(this.config, itemConfig)
}
},
getRegisteredItem: function(key) {
return this.registry[key];
}
}
CENTRALIZZATA:
In questa versione, l'applicazione deve assegnare un nome a ciascuna dipendenza e anche a ciascuna rotta. Questo è più esplicito, in modo da non dover pescare intorno per capire da dove proviene un elemento di configurazione:
var app = new App
app.register({
a: require "dependencyA"
b: require "dependencyB"
c: require "dependencyC"
});
app.routes({
foo: "path/to/foo"
});
// dependencyA: borrows angular-ish dependency injection
module.exports = ['b', 'c', function (b, c) {
return {
start: function () {
return c.doSomethingElse()
}
// dependencies are now in scope
}]
}
// App
var App = {
register: function (items) {
_.each(items, function (itemSpec, name) {
this.registry[name] = itemSpec
}, this);
},
initialize: function () {
// WARNING: handwaving...
_.each(this.registry, function (itemSpec, name) {
moduleFun = itemSpec.pop();
dependencies = []
_.each(itemSpec, function (item) {
if (this.registry[item]) {
dependencies.push(item);
} else {
throw new Exception("registry didn't have one of those");
}
});
// replace the item in the registry so it can be started later
this.registry[name] = moduleFun.apply(moduleFun, dependencies);
}
}
};
La preoccupazione qui è che la configurazione dell'applicazione diventerà troppo ingombrante e difficile da gestire una volta che il progetto / team sarà passato di una certa dimensione.
Preferisco la versione centralizzata, in quanto è più esplicita e l'applicazione sta dettando i nomi dei suoi "figli". Quali sono le insidie di quest'ultimo approccio? In quali circostanze sceglieresti il primo?