上虞网站开发,郑州前端培训机构,网站建设哪家企业好,wordpress 文章内容不显示总目录 前言
装饰器模式的主要作用就是扩展一个类的功能#xff0c;或给一个类添加多个变化的情况。学习面向对象的都知道#xff0c;如果想单纯的给某个类增加一些功能#xff0c;可以直接继承该类生成一个子类就可以。应对一些简单的业务场景继承也就够了#xff0c;但是…总目录 前言
装饰器模式的主要作用就是扩展一个类的功能或给一个类添加多个变化的情况。学习面向对象的都知道如果想单纯的给某个类增加一些功能可以直接继承该类生成一个子类就可以。应对一些简单的业务场景继承也就够了但是面对一些复杂的业务场景仅靠继承是不够的。那么我们看看装饰器模式是如果以一个更为灵活的方式扩展一个对象的功能的。 1 基础介绍
动态地给一个对象添加一些额外的职责就增加功能来说装饰器模式相比生成子类更为灵活。适用于需要扩展一个类的功能或给一个类添加多个变化的情况。在装饰模式中的角色 抽象构件角色Component给出一个抽象接口以规范准备接收附加责任的对象。具体构件角色Concrete Component定义一个将要接收附加责任的类。装饰角色Decorator持有一个构件Component对象的实例并实现一个与抽象构件接口一致的接口。具体装饰角色Concrete Decorator负责给构件对象添加上附加的责任。
2 使用场景
当需要扩展一个类的功能或给一个类增加附加责任并且扩展功能可能存在多个且需要可动态组合配置的情况下使用装饰器模式就是最好的解决办法
注如果类的扩展比较简单并且不会多次进行扩展的情况下直接使用类的继承生成子类的方式更为方便快捷。
3 实现方式
看了上面这些描述没有案例我们是无法理解装饰器模式的精髓。那么我们现在通过一个手机贴膜装手机壳的案例来理解一下。
1. 传统模式
(1) 第一个需求张三有一个手机现在想给贴膜代码实现如下 public class Phone{public virtual void Show() {Console.WriteLine(手机);}}//贴膜手机 继承自 手机类public class MoPhone : Phone{//贴膜的方法public void TieMo(){Console.WriteLine(给手机贴膜了);}public override void Show(){base.Show();TieMo();}}客户端调用 static void Main(string[] args){Phone moPhone new MoPhone();moPhone.Show();Console.ReadKey();}(2) 现在需求改了手机不贴膜了要装手机壳于是我们改代码 //装手机壳的手机 继承自 手机类public class KePhone : Phone{//装手机壳的方法public void ZhuangKe(){Console.WriteLine(给手机装手机壳了);}public override void Show(){base.Show();ZhuangKe();}}客户端调用 static void Main(string[] args){Phone phone new KePhone();phone.Show();Console.ReadKey();}(3) 现在需求又改了手机贴膜 装手机壳于是我们改代码 public class Phone{public virtual void Show() {Console.WriteLine(手机);}}//贴膜手机 继承自 手机类public class MoPhone : Phone{//贴膜的方法public void TieMo(){Console.WriteLine(给手机贴膜了);}public override void Show(){base.Show();TieMo();}}//现在又改变注意了既想给手机贴膜也想给手机装手机壳//直接继承已有的贴膜手机类来实现会比较省事public class KeAndMoPhone : MoPhone{//装手机壳的方法public void ZhuangKe(){Console.WriteLine(给手机装手机壳了);}public override void Show(){base.Show();ZhuangKe();}}客户端调用 static void Main(string[] args){Phone phone new KeAndMoPhone();phone.Show();Console.ReadKey();}上面的实例中如果单独贴膜或者单独安装保护壳则直接继承手机类即可。 但如果想要即贴膜又要安装保护壳各自继承手机类的方式就行不通了只能在贴膜类或者保护壳类的基础上进行扩展。如果还有添加手机挂饰那就还需要再一层继承关系这样就会导致 ”子类爆炸“问题为了解决这个问题就用到了装饰器下面看看使用装饰器是怎么给手机添加新功能的。
2. 装饰器模式
1 首先定义手机抽象类 和 手机实现类 public abstract class AbstractPhone{public abstract void Show();}public class XiaoMiPhone : AbstractPhone{public override void Show(){Console.WriteLine(小米手机);}}2 再定义一个装饰的抽象类 //装饰抽象类是装饰模式的核心public abstract class Decorator : AbstractPhone{//保持对手机对象的引用protected AbstractPhone abstractPhone;public Decorator(AbstractPhone phone){abstractPhone phone;}public override void Show(){//这行代码比较有意思是实现装饰模式的巧思abstractPhone?.Show();}}3 定义装饰抽象类的实现贴膜装饰装手机壳装饰 // 贴膜装饰类主要实现给手机贴膜的扩展功能public class MoPhone : Decorator{public MoPhone(AbstractPhone phone) : base(phone){}public override void Show(){base.Show();TieMo();}//扩展的功能贴膜public void TieMo(){Console.WriteLine(给手机贴膜了);}}// 手机壳装饰类主要实现给手机装手机壳的扩展功能public class KePhone : Decorator{public KePhone(AbstractPhone phone) : base(phone){}public override void Show(){base.Show(); ZhuangKe();}//扩展的功能装手机壳public void ZhuangKe(){Console.WriteLine(给手机装手机壳了);}}客户端调用
只给手机贴膜 static void Main(string[] args){AbstractPhone phone1 new XiaoMiPhone();Decorator decorator1 new MoPhone(phone1);decorator1.Show();Console.ReadKey();}只给手机装手机壳 static void Main(string[] args){AbstractPhone phone2 new XiaoMiPhone();Decorator decorator2 new KePhone(phone2);decorator2.Show();Console.ReadKey();}给手机贴膜装手机壳 static void Main(string[] args){AbstractPhone phone3 new XiaoMiPhone();Decorator decorator3 new MoPhone(phone3);decorator3 new KePhone(decorator3);decorator3.Show();Console.ReadKey();}4 需求变更现在想给手机 贴膜 玩偶吊坠
我们只需新增一个 玩偶吊坠 类 继承自 装饰抽象类然后定义一个玩偶吊坠的装饰方法 // 玩偶吊坠装饰类主要实现给手机装玩偶吊坠的扩展功能public class DiaoZhuiPhone : Decorator{public DiaoZhuiPhone(AbstractPhone phone) : base(phone){}public override void Show(){base.Show();ZhuangDiaoZhui();}//扩展功能:给手机装玩偶吊坠public void ZhuangDiaoZhui(){Console.WriteLine(给手机安装玩偶吊坠了);}}客户端调用 static void Main(string[] args){//给手机贴膜玩偶吊坠AbstractPhone phone new XiaoMiPhone();Decorator decorator new MoPhone(phone);decorator new DiaoZhuiPhone(decorator);decorator.Show();Console.ReadKey();}我们发现当我们想要给手机加新的装饰只需简单的新增对应的装饰类在装饰类定义一个扩展的装饰方法新功能即可。而且还可以对装饰类进行不同组合这使得我们的代码非常的灵活。
4 优缺点分析
优点 相较于继承装饰器模式可以更为灵活的扩展新功能并且避免了单独使用继承带来的 “多子类衍生问题“。很好地符合面向对象设计原则中 ”优先使用对象组合而非继承“和”开放-封闭“原则。装饰者模式有很好地可扩展性。 缺点装饰者模式会导致设计中出现许多小对象如果过度使用会让程序变的更复杂。并且更多的对象会是的差错变得困难特别是这些对象看上去都很像。 结语
希望以上内容可以帮助到大家如文中有不对之处还请批评指正。 参考资料 C#设计模式之八装饰模式Decorator Pattern【结构型】 c#中装饰器模式详解 C#设计模式(9)——装饰者模式Decorator Pattern