天天看点

C#设计模式-装饰器模式(Decorator Pattern)

当我们完成一个软件产品开发后就需要对其进行各种测试,适配快速迭代下质量的保障。当有一个完善的产品的对象后,如果我们想要给他添加一个测试功能,那么我们可以用一个新的类去装饰它来实现对原有对象职责的扩展。新的类称为“装饰者”,原有的对象称为“被装饰者”。这种模式被称为装饰器模式。

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

我们通过下面的实例来演示装饰器模式的用法。其中,我们将把一个形状装饰上不同的颜色,同时又不改变形状类。

C#设计模式-装饰器模式(Decorator Pattern)

装饰器模式中的角色:

抽象构件(Component)角色:声明封装器和被封装对象的公用接口。即给出一个抽象接口,已规范准备接收附加责任的对象。

具体构件(ConcreteComponent)角色:类是被封装对象所属的类。 它定义了基础行为, 但装饰类可以改变这些行为。

装饰(Decorator)角色:拥有一个指向被封装对象的引用成员变量。 该变量的类型应当被声明为通用部件接口, 这样它就可以引用具体的部件和装饰。 装饰基类会将所有操作委派给被封装的对象。

具体装饰(ConcreteDecorator)角色:定义了可动态添加到部件的额外行为。 具体装饰类会重写装饰基类的方法, 并在调用父类方法之前或之后进行额外的行为。负责给构件对象“贴上”附加的责任。

实现一个开发完成后的产品,对其进行手工功能测试、自动化测试、压力测试。将产品作为被装饰者,也就是构件。各种测试作为装饰者,计算附加不同的测试花费的总时间。

定义一个产品抽象类。

实现具体的产品,具体的产品继承产品抽象类。

定义一个测试类型的抽象装饰类,继承产品抽象类。

实现不同类型的测试,继承测试类型的抽象装饰类。

使用时实例化一个产品,然后对产品进行附件不同的测试类型。

运行后结果:

在无需修改代码的情况下即可使用对象, 且希望在运行时为对象新增额外的行为时可以使用装饰模式。因为装饰能将业务逻辑组织为层次结构,可为各层创建一个装饰, 在运行时将各种不同逻辑组合成对象。 由于这些对象都遵循通用接口, 客户端代码能以相同的方式使用这些对象。

如果用继承来扩展对象行为的方案难以实现或者根本不可行,可以使用装饰模式。

无需创建新子类即可扩展对象的行为。

可以在运行时添加或删除对象的功能。

可以用多个装饰封装对象来组合几种行为。

装饰类和被装饰类可以独立发展,不会相互耦合。

单一职责原则。 可以将实现了许多不同行为的一个大类拆分为多个较小的类。

在封装器栈中删除特定封装器比较困难。

实现行为不受装饰栈顺序影响的装饰比较困难。

各层的初始化配置代码看上去可能会很糟糕。