乐趣区

关于前端:设计模式之装饰模式

冬天曾经降临,南方的小伙伴们是不是感觉天气一天比一天冷了呢?从秋天过渡到冬天,冷了就穿一件毛衣,如果穿上毛衣还感觉冷可能会添一件羽绒服,如果下雪天可能就须要穿上雨衣或者带上雨伞了。在咱们生存中这些衣服以拓展的形式给了你和煦,然而它们并不是你的一部分,如果到了春天那么这些衣服可能会一一的脱掉了。

在软件开发过程中,有事想用一些现存的类或者组件,这些类或者组件可能只是实现了一些外围性能。但在不扭转其构造的状况下,能够动静的拓展其性能。所有这些都能够用装璜模式来实现。

什么装璜模式

装璜模式:指的是在不用扭转原类文件和应用继承的状况下,动静地扩大一个对象的性能。它是通过创立一个包装对象,也就是装璜来包裹实在的对象。—— 节选自百度百科

装璜模式有两种形式能够实现给一个类或者一个对象增加行为,第一种是应用继承,应用继承是给现有类增加性能的一种有效途径,通过继承一个现有类能够使得子类在领有本身办法的同时还领有父类的办法。然而这种办法是动态的,用户不能管制减少行为的形式和机会。第一种则是应用关联的办法,行将一个类的对象嵌入到另一个对象中,由另一个对象来决定是否调用嵌入对象的行为以便扩大本人的行为。

装璜模式优缺点

装璜模式以对客户通明的形式动静地给一个对象附加上更多的责任,换言之,客户端并不会感觉对象在装璜前和装璜后有什么不同。装璜模式能够在不须要创立更多子类的状况下,将对象的性能加以扩大。

长处

  1. 装璜模式与继承关系的目标都是扩大对象的性能,然而装璜模式能够提供比继承更多的灵活性。
  2. 能够通过一种动静的形式来扩大一个对象的性能,通过配置文件能够在运行时抉择不同的装璜器,从而实现不同的行为。
  3. 通过应用不同的具体装璜类以及这些装璜类的排列组合,能够发明出很多不同的行为的组合。能够应用多个具体装璜类来装璜同一个对象,失去性能更为弱小的对象。
  4. 具体构建类与具体装璜类能够独立变动,用户能够依据须要减少新的具体构建类和具体装璜类,在应用其进行组合,原有代码无需扭转

毛病

  1. 是以哦那个装璜模式进行零碎设计时将产生很多小对象,这些对象的区别在于他们之间的相互连接的形式有所不同,而不是他们的类或者属性值有所不同,同时还会由很多具体的装璜类。这些装璜类和小对象的产生将减少零碎的复杂度,加大学习了解的难度。
  2. 这种比继承更加灵活机动平的个性,也同时意味着装璜模式比继承更加易于出错,排错也是蛮艰难的,对于屡次装璜的对象,调试时寻找谬误可能须要逐级排场,较为繁琐,我的项目复杂度偏高。

示例

装璜模式的次要角色如下:

  1. 部件:申明封装器和被封装的对象的专用接口
  2. 具体部件:类是被封装对象所属的类。它定义了根底行为,但装璜类扭转了这些行为
  3. 根底装璜:类领有一个指向被封装对象的援用成员变量。该变量的类型该当被申明尾通用部件接口这样就能够援用具体的部件接口,这样他就能够援用具体的部件和装璜。
  4. 具体装璜类:定义类可动静增加到部件的额定行为。具体装璜类会重写装璜基类的办法,并在调用父类办法之前或之后进行额定的行为。
  5. 客户端:能够应用多层装璜来封装来装璜部件,只有它能应用通用接口与所有对象交互即可。

类图如下所示:

代码示例:

// 形象构件
abstract class Component {public abstract operate() : void;
}

// 具体构件
class ConcreteComponent extends Component {public operate() : void {console.log('do something');
    }
}

// 装璜角色
abstract class Decorator extends Component {
    private component : Component = null;
    constructor(component : Component) {super();
        this.component = component;
    }

    public operate() : void {this.component.operate();
    }
}

// 具体装璜者
class ConcreteDecoratorA extends Decorator {constructor(component : Component) {super(component);
    }

    // 定义本人的润饰办法
    private methodA() : void {console.log('methodA 润饰');
    }

    // 重写父类办法
    public operate() : void {this.methodA();
        super.operate();}
}

class ConcreteDecoratorB extends Decorator {constructor(component : Component) {super(component);
    }

    // 定义本人的润饰办法
    private methodB() : void {console.log('methodB 润饰');
    }

    // 重写父类办法
    public operate() : void {this.methodB();
        super.operate();}
}

function main() {let component : Component = new ConcreteComponent();
    // 第一次装璜
    component = new ConcreteDecoratorA(component);
    // 第二次装璜
    component = new ConcreteDecoratorB(component);
    // 装璜后运行
    component.operate();}

main();

总结

装璜模式来实现扩大比继承更加灵便,它以对客户通明的形式动静地给一个对象附加更多的责任。装璜模式能够在不须要发明更多子类的状况下,将对象的性能加以扩大。

继承是一种耦合度较大的动态关系,无奈在程序运行时动静扩大。在软件开发阶段,关联关系尽管不会比继承关系缩小编码量,然而到了软件维护阶段,因为关联关系使零碎具备较好的松耦合性,因而使得零碎更加容易保护。

退出移动版