wong2
wong2

Reputation: 35720

How to design this architecture?

I have 3 classes:

function A(data){
    this.data = data || [];
}    
A.prototype.remove = function(index){
    // remove index from this.data;
};
function B(data){
    this.data = data || [];
}  
B.prototype.add = function(x){
    this.data.push(x);
};
B.prototype.update = function(index, x){
    this.data[index] = x;
};
function C(data){  
    this.data = data || [];
}
C.prototype.add = function(x){
    this.data.push(x);
};
var a = new A(xx);
var b = new B(xx);
var c = new C(xx);

There relations are:
if I call a.remove(i) to remove an element, b will add it to its data.
if I call b.update(i, x), c will add x to its data.
How could I design this with smallest coupling?

ps: this is just an example to demonstrate the situation, please don't care about the initialization etc.

Upvotes: 0

Views: 78

Answers (2)

WTK
WTK

Reputation: 16971

I would use events for loose coupling at its best. As base I recommend using Backbone.js (see Backbone.Events section) it has very small footprint and provide you with great custom events support. Brief description from docs:

Events is a module that can be mixed in to any object, giving the object the ability to bind and trigger custom named events.

It could look like this:

function A(data){
    this.data = data || [];
}    
A.prototype.remove = function(index){
    // remove index from this.data;
    // dispatch A_Remove event
    this.trigger("A_Remove", this.data);
};
function B(data){
    this.data = data || [];
}  
B.prototype.add = function(x){
    this.data.push(x);
};
B.prototype.update = function(index, x){
    this.data[index] = x;
    this.trigger("B_Update", x);
};
function C(data){  
    this.data = data || [];
}
C.prototype.add = function(x){
    this.data.push(x);
};
var a = new A(xx);
var b = new B(xx);
var c = new C(xx);

// mixin event support to your objects
_.extend(a, Backbone.Events);
_.extend(b, Backbone.Events);
_.extend(c, Backbone.Events);

// event listener for A_Remove event
a.bind("A_Remove", function(data) {
    b.add(data);
});
// event listener for B_Update event
b.bind("B_Update", function(data) {
    c.add(data);
});

With this event-based approach, your classes are as loose coupled as they can be, there's no need for A, B or C to know about each other. At the same time you get highest flexibility - at any point you can add more listeners or event types.

I feel that's the best solution.

Upvotes: 1

Liviu T.
Liviu T.

Reputation: 23664

I would add callbacks to class A and class B

function A(data, callback) {
  this.data = data || [];
  this.callback = callback || function() {};
}

A.prototype.remove = function(index) {
  // remove index from this.data;
  this.callback(this.data[index]);
}
...
var b = new B(xx);
var a = new A(xx, function(e) {b.add(e);});

Upvotes: 0

Related Questions