當咱們完成一個軟件產品開發後就須要對其進行各類測試,適配快速迭代下質量的保障。當有一個完善的產品的對象後,若是咱們想要給他添加一個測試功能,那麼咱們能夠用一個新的類去裝飾它來實現對原有對象職責的擴展。新的類稱爲「裝飾者」,原有的對象稱爲「被裝飾者」。這種模式被稱爲裝飾器模式。設計模式
裝飾器模式(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