当咱们完成一个软件产品开发后就须要对其进行各类测试,适配快速迭代下质量的保障。当有一个完善的产品的对象后,若是咱们想要给他添加一个测试功能,那么咱们能够用一个新的类去装饰它来实现对原有对象职责的扩展。新的类称为“装饰者”,原有的对象称为“被装饰者”。这种模式被称为装饰器模式。设计模式
装饰器模式(Decorator Pattern)容许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是做为现有的类的一个包装。
这种模式建立了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
咱们经过下面的实例来演示装饰器模式的用法。其中,咱们将把一个形状装饰上不一样的颜色,同时又不改变形状类。ide
装饰器模式中的角色:测试
实现一个开发完成后的产品,对其进行手工功能测试、自动化测试、压力测试。将产品做为被装饰者,也就是构件。各类测试做为装饰者,计算附加不一样的测试花费的总时间。this
using System; namespace Decorator { class Program { static void Main(string[] args) { Product a = new ProductA(); Console.WriteLine($"未执行{a.Test}测试时总共花费时间{a.TotalTime}"); a = new ManualTest(a); Console.WriteLine($"执行{a.Test}总共花费时间{a.TotalTime}"); Console.WriteLine("====================================="); Product b = new ProductB(); b = new ManualTest(b); b = new StressTest(b); b = new AutoTest(b); Console.WriteLine($"执行{b.Test}总共花费时间{b.TotalTime}"); Console.Read(); } } /// <summary> /// 一个项目产品,抽象构件 /// </summary> public abstract class Product { public string Name { get; set; } public double SpendTime { get; set; } public abstract string Test { get; } public abstract double TotalTime { get; } } /// <summary> /// 具体的项目产品A,具体构件 /// </summary> public class ProductA : Product { public ProductA() { Name = "ProductA"; SpendTime = 0; } public override string Test => this.Name; public override double TotalTime => this.SpendTime; } /// <summary> /// 具体的项目产品B,具体构件 /// </summary> public class ProductB : Product { public ProductB() { Name = "ProductB"; SpendTime = 0; } public override string Test => this.Name; public override double TotalTime => this.SpendTime; } /// <summary> /// 测试类型,抽象装饰 /// </summary> public abstract class TestType : Product { Product _product = null; public TestType(Product product) { _product = product; } public override string Test { get { return _product.Test + "+" + this.Name; } } public override double TotalTime { get { return _product.TotalTime + this.SpendTime; } } } /// <summary> /// 手工测试类型,具体装饰 /// </summary> public class ManualTest : TestType { public ManualTest(Product product) : base(product) { Name = "手工测试"; SpendTime = 200; } } /// <summary> /// 自动化测试类型,具体装饰 /// </summary> public class AutoTest : TestType { public AutoTest(Product product) : base(product) { Name = "自动化测试"; SpendTime = 100; } } /// <summary> /// 压力测试类型,具体装饰 /// </summary> public class StressTest : TestType { public StressTest(Product product) : base(product) { Name = "压力测试"; SpendTime = 200; } } }
运行后结果:spa
未执行ProductA测试时总共花费时间0 执行ProductA+手工测试总共花费时间200 ===================================== 执行ProductB+手工测试+压力测试+自动化测试总共花费时间500