装饰器模式
允许向一个现有的对象添加新的功能,同时又不改变其结构。
(就是可以在一个方法的前面或者后面,再添加一些逻辑,但是这个方法不用做任何修改)
组成模块
抽象组件(Component):定义一个对象接口,可以给这些接口动态地添加职责。
具体组件(ConcreteComponent):实现了组件接口,是需要被装饰的具体对象。
装饰器(Decorator):持有一个指向组件对象的引用,并实现与组件接口一致的接口,用于动态
地给组件对象添加新的职责。
ConcreteDecorator(具体装饰器):扩展了装饰器的功能,可以为组件对象添加具体的职责。
Demo
1、定义抽象组件
public interface ICar
{
string GetDescription();
}
2、具体组件
public class XiaoMiCar : ICar
{
public string GetDescription()
{
return "xiaomi 汽车";
}
}
3、创建装饰器
public class BeiDouDecorator : ICar
{
private readonly ICar _car;
public GPSDecorator(ICar car)
{
_car = car;
}
public string GetDescription()
{
//在方法前做某事。。
var des = _car.GetDescription();
//在方法后做某事
return des + ",支持北斗导航";
}
}
4、实际调用
ICar xiaomiCar = new XiaoMiCar();
ICar bdDecorator = new BeiDouDecorator(xiaomiCar);
bdDecorator.GPSDecorator();
在上述的Demo中,发现并不完全符合组成模块的构成。这是因为装饰器模式又分为”透明装饰模式
“和”半透明装饰模式“。上述代码就是半透明装饰器
透明装饰器模式Demo
1、定义抽象组件
public interface ICar
{
string GetDescription();
}
2、具体组件
public class XiaoMiCar : ICar
{
public string GetDescription()
{
return "xiaomi 汽车";
}
}
3、创建装饰器
//定义导航类
public abstract class Navigation : ICar
{
protected ICar _car;
public Navigation (ICar car)
{
_car = car;
}
public override string GetDescription()
{
if (_car!= null)
{
//之前做某事
_car.Operation();
//之后做某事
}
}
}
4、具体装饰器
public class GpsNavigation: Navigation
{
public GpsNavigation(ICar car) : base(car)
{
}
public override void GetDescription()
{
//在方法前做某事。。
var des = base.GetDescription();
//在方法后做某事
return des + ",支持GPS导航";
}
private void AddNewFunctionality()
{
Console.WriteLine("添加新功能A");
}
}
5、实际调用
ICar xiaomiCar = new XiaoMiCar();
Navigation gpsDecorator = new GPSDecorator(xiaomiCar);
gpsDecorator.GPSDecorator();
根据上面代码,”透明装饰模式“和”半透明装饰模式“主要区别在于,透明装饰模式是又做了一层抽
象的封装,对进一步的扩展更加友好。
优点
1、遵循开闭原则:装饰器模式支持开闭原则,即对扩展是开放的,对修改是关闭的。你可以通过
添加新的装饰器类来扩展功能,而无需修改现有代码。
2、灵活性:装饰器模式允许你根据需要动态地添加、修改或移除对象的功能,而无需更改其原始
类的结构。这种灵活性使得系统更容易扩展和维护。
缺点
1、复杂性:装饰器模式可能会引入许多小的装饰器类和对象之间的交互,导致代码变得复杂。理
解装饰器模式的工作原理和设计合适的装饰器类层次结构需要一定的经验和技巧。
2、可能导致过度装饰:过度使用装饰器模式可能会导致类的功能变得过于分散和复杂。如果不适
当地设计装饰器类层次结构,可能会导致代码难以理解和维护。
适用场景
1、动态地添加功能:当需要在不修改现有对象代码的情况下动态地添加额外的功能时,装饰器模
式非常有用。例如,如果你希望在运行时动态地添加日志记录、缓存、加密等功能而无需修改原始
对象代码,则可以使用装饰器模式。
实际运用
装饰器模式在实际运用中,还是挺常见的。比如Autofac工具中的拦截器以及.NET中Filter过滤器,
(不知道的,可以了解一下拦截器以及Filter过滤器)
运用的都是装饰器模式的思想,在不改变原有方法基础上,添加额外的功能。