In my node.js application, I have a queue class which has push and pop methods and a data property. I have an Event class which handles an event and pushes it on to the queue.

If I think object oriented, is the relationship between queue and event better modeled as "is a" (inheritance) or "has a" (composition)?

First approach:

var util = require('util'),
    array = [];

function Q(source){
    this.data = source;
}

Q.prototype.push = function(x){
    this.data.push(x);
};

Q.prototype.show = function(){
    console.log(this.data);
};

function Event(y){
    Q.call(this, y);
}

util.inherits(Event,Q);

Event.prototype.trigger = function(bb){
 //some logic
 this.push(bb);
};

var x = new Event(array);
x.trigger('hi');
x.show();

Second approach :

var array = [];
function Q(source){
    this.data = source;
}

Q.prototype.push = function(x){
    this.data.push(x);
};

Q.prototype.show = function(){
    console.log(this.data);
};

function Event(y){
    this.arr = new Q(y);
}

Event.prototype.trigger = function(bb){
    //some logic
    this.arr.push(bb);
};

var x = new Event(array);
x.trigger('hi');
x.show();
有帮助吗?

解决方案

Conceptually, inheritance (is-a) is a specialization of composition (has-a). (from Reg Braithwaite) Both accomplish the same thing (which is why you can ask a question like this), but inheritance lacks the flexibility of composition. Inheritance makes your code rigid.

From a practical view, this doesn't matter as much in JavaScript since JavaScript isn't limited to single inheritance. What we're calling inheritance is actually some prototype patching and function delegation. There's nothing stopping us from creating a mixin from several "types". This has more in common with Go's type composition than Java or C#'s inheritance model. It doesn't make your code as rigid.

Still, it does seem strange to say an Event is-a Queue. Is it really? It seems more likely that an Event is a model of some action in your app and it uses (has-a) a Queue to manage its workflow. If an Event is truly a Queue, I should be able to use it anywhere I use a Queue without a second thought:

var q = new Event();
q.push("hi");
q.pop();

This doesn't seem right to me. It's a stretch. This is a perfect place to avoid inheritance in favor of composition.

See also: Liskov substitution principle

许可以下: CC-BY-SA归因
scroll top