装饰者模式是在对象不改变自身的情况下,在程序运行期间给对象动态添加职责。这样既保证了原来对象的一定封装性,又保证了装饰的对象不会太过臃肿,当然如果装饰得过多,那么装饰的链条自然会很臃肿,以至于影响性能。
下面看一下如何实现装饰者模式
Function.prototype.before = function( beforefn ){
var _self = this;
return function(){
beforefn.apply( this, arguments );
return _self.apply( this, arguments );
};
};
Function.prototype.after = function( afterfn ){
var _self = this;
return function(){
var ret = _self.apply( this, arguments );
afterfn.apply( this, arguments );
return ret;
};
};
上面两个函数就是装饰者模式实现的关键,动态在原函数前后添加链条来增加功能,其返回值是一个包含了原函数和新函数的替代函数。在实际开发中,当我们遇到庞大到难以维护的对象时,往往会将其划分成很多很小的对象,这时通过装饰将其合并到一起,这样我们就可以得到一段低耦合高复用的程序。
状态模式
状态模式允许一个对象在其内部状态改变时改变他的行为,其关键就是要区分好事物内部的状态。状态模式不是那么好理解,下面上个简单的例子
var OffLightState = function( light ){
this.light = light;
};
OffLightState.prototype.buttonWasPressed = function(){
console.log( '弱光' );
this.light.setState( this.light.weakLightState );
};
var WeakLightState = function( light ){
this.light = light;
};
WeakLightState.prototype.buttonWasPressed = function(){
console.log( '强光' );
this.light.setState( this.light.strongLightState );
};
var StrongLightState = function( light ){
this.light = light;
};
StrongLightState.prototype.buttonWasPressed = function(){
console.log( '关灯' );
this.light.setState( this.light.offLightState );
};
//创建三种状态以及对应行为完毕
var Light = function(){
this.offLightState = new OffLightState( this );
this.weakLightState = new WeakLightState( this );
this.strongLightState = new StrongLightState( this );
this.button = null;
};
Light.prototype.init = function(){
var button = document.createElement( "button" ),
self = this;
this.button = document.body.appendChild( button );
this.button.innerHTML = '开关';
this.currState = this.offLightState;
this.button.onclick = function(){
self.currState.buttonWasPressed();
};
};
Light.prototype.setState = function( newState ){
this.currState = newState;
};
var light = new Light();
light.init();
引入了一个简单的开关灯例子,总体来说,状态模式的一般行为是这样的,首先创建工厂模式(因为每个状态都是一个单独的实例,而且状态变化一般很多,所以需要工厂),然后工厂出若干实例,接着给状态类添加行为。在状态模式中,我们定义了转态和行为的关系,并将其放入一个类中,十分方便后期复用以及追加需求增添新的类,但过多的状态类也很容易造成性能问题,和状态逻辑切换混乱问题。