开发者

Is there a design pattern for injecting methods into a class?

开发者 https://www.devze.com 2023-02-08 13:06 出处:网络
I have a set of classes that work together (I\'m coding in javascript). There is one parent class and a number of child classes that are instantiated by the parent class. I have a number of clients o

I have a set of classes that work together (I'm coding in javascript).

There is one parent class and a number of child classes that are instantiated by the parent class. I have a number of clients of these classes that each need to add one or more methods to the parent or child classes.

Rather than having each client inherit from these classes, which is doable but messy because of the child classes, I am having these clients pass functions into the parent class when they instantiate the main class.

The mai开发者_StackOverflow中文版n class creates the methods dynamically and the clients can call the methods like they were there all along.

My questions are:

  1. is this a sensible thing to do?
  2. what would the design pattern be for what I am doing?


The strategy pattern is for situations where you get your 'strategy' at runtime. might be applicable here. Strategy in this case is a class that conforms to a behavior, i.e. has a method like 'execute' or whatever.

The decorator pattern also might apply. It is also a runtime pattern, but augments the class it is decorating at the method level.

So the Strategy pattern is good if you are choosing a class dynamically, and Decorator is good if you are only changing out the method implementation at runtime.

(I took the decorator part of this answer with permission from ircmaxell)


I must admit that patterns aren't my "thing" - but you can do exactly what you want to in javascript. It is how all of the frameworks accomplish that sort of things "extending" child "classes" (there are no classes in javascript).

If you are in the pure javascript world, you want to use:

foo.prototype.bar = function() {};

So you can call bar on any foo, and bar only exists in memory once - that is the same function is referenced in memory through every foo object. So be careful with any variables you might be referencing outside that scope.

Each library has their own plugin architecture to accomplish roughly the same goal (and they take care of some of the messiness/danger in prototype)


You should provide some code, so that we can get a feel for what exactly you're talking about.

As you haven't: I can only guess that you're not making use of prototypes. Prototypes would be the "correct" design pattern for "object-oriented" JavaScript.

When you add a function/property/whatever to the prototype of an object in JavaScript, all instances, new and old receive the function/property/whatever on their prototype.

Extending prototypes in JavaScript is very simple, and should never become messy. If it does, it probably means you're over-complicating it.


As hvgotcodes says, you are describing the Strategy Pattern, the way you would do this for your specific case, is not to use prototypes (thereby affecting all objects of your class.)

Instead you'd provide a member that accepts a function as it's value.

e.g.

function MyClass() {
    this.myFunction = defaultFunction;

    this.defaultFunction = function() {
       // do something by default.
       alert("using default");
    }

    this.doFunction = function() {
       // something that calls myFunction.
       this.myFunction();
    }
}

---8< snip --------

// later on...

t = new MyClass();
t.doFunction(); // output 'using default'
t.myFunction = function(){ 
   // do something specific with this instance, when myFunction is called. 
   alert("customized for this instance.");
}
t.doFunction(); // output 'customized for this instance.'
0

精彩评论

暂无评论...
验证码 换一张
取 消