Working with GoF's Design Patterns in JavaScript Programming
page 4 of 8
by Xianzhong Zhu
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 80069/ 150

Working with the Decorator Pattern

First of all, let us, as usual, look at the definition of the Decorator pattern.

 (1) Concept

The Decorator pattern is one of the seven Structural patterns which are concerned with how classes and objects are composed of larger structures (the other six Structural patterns are Proxy, Bridge, Composite, Flyweight, Adapter, Façade, respectively). The Decorator pattern makes full use of the advantages of inheritance and aggregation, whose main purpose is to attach new state and behavior to a ready-made object dynamically while not modifying the original behaviors. This can be compared to an adornment worker who is ready to decorate a wall of a new residence with colorful pigment.

 (2) Example

Interesting thing is that we can apply the Decorator pattern to the Aspect Oriented Programming (AOP) in the JavaScript scenario.

Author's Note: Aspect-oriented programming, AOP in short, is a new means of method to improve the existing pattern and discover new ones. According to Wikipedia, aspect-oriented programming (AOP) is a programming paradigm that increases modularity by allowing the separation of cross-cutting concerns. Separation of concerns entails breaking down a program into distinct parts (so-called concerns, cohesive areas of functionality). All programming paradigms support some level of grouping and encapsulation of concerns into separate, independent entities by providing new abstractions (e.g. procedures, modules, classes, methods) that can be used to represent these concerns. But some concerns defy these forms of encapsulation and are called crosscutting concerns because they "cut across" multiple abstractions in a program.

Next, let us look at the code shown in Listing 8 below.

Listing 8: Use the Decorator pattern to achieve AOP in JavaScript

function Decorator(object){
object.setup=function(method){
//if never execute the Setup method,
  then make initialization
if(!(‘_’+method in object)){
//reserve the existing methods
object[‘_’+method]=object[method];
//initialize the lists for before and after 
 advice respectively
object[‘beforeAdvice_’+method]=[];
object[‘afterAdvice_’+method] =[];
// override the <span class=Bold>method</span> method
object[method]=function(){
//establish the before advice list
var before=this[‘beforeAdvice_’+method];
// establish the after advice list
var after=this[‘afterAdvice_’+method];
//used to hold the returned value
var ret;
//invoke the functions in the before advice
for(var i=0; i<before.length; i++) {
before[i].call(this,arguments);
}
// invoke the initial functions
ret=this[‘_’  +method](arguments);
// invoke the functions in the after advice
for (var i=; i<after.1ength; i++){
after[i].call(this, arguments);
}
//return the value of the initial method
return ret;
}
}
};
 
//attach the before advice
object.addBeforeAdvice=function(method, f) {
object.setup(method);
//the last before advice attached will be invoked first
object[‘beforeAdvice_’ +method].unshift(f);
};
// attach the after advice
object.addAfterAdvice=function(method, f) {
object.Setup(method);
// the last after advice attached will be invoked first
object[‘afterAdvice_’ +method].push(f);
};
}

The basic idea behind the Decorator function above is to substitute the original function for a now one and in the one add invocations to the before and after functions. Below is a concrete example to explain the usage of the Decorator function. For convenience, we should first define a class named testClass.

Listing 9

var testClass  =  function()  {
testClass.prototype.pl=”hello”;
testClass.prototype.ml =function()  {
alert(this.p1);
}
};

If you wish to place before or after notifications upon all the instantiations of class testClass, then you need to do some processing with the testClass.prototype attribute.

Listing 10

Decorator(testClass.prototype);
testClass.prototype.addBeforeAdvice(“m1”,   
function()  {
alert(“beforeAdvice”);
});
testClass.prototype.addAfterAdvice(“m1”, 
 function()  {
alert(”afterAdvice”);
});

At this time, if you create an instantiation of class testClass and invoke its ml method, then the application will output strings "beforeAdvice," "hello," and"afterAdvice" in order.

Listing 11

var t=new testClass ();
//output 'beforeAdvice','hello','afterAdvice'
t.ml();

If you only want to place before or after notifications upon a specified instantiation of class testClass, then you can directly do with this instantiation, as shown below.

var t=new testClass();
Decorator(t);
t.addBeforeAdvice(“ml” ,function](){
alert(“beforeAdvice”);
});
t.addAfterAdvice(“ml”, function(){
alert(“afterAdvice”);
});

That is it.


View Entire Article

User Comments

No comments posted yet.

Product Spotlight
Product Spotlight 





Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-03-29 3:14:04 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search