10_装饰模式
装饰模式是一种结构型设计模式,它允许我们在不改变现有对象结构的情况下,动态地向对象添加额外的功能。
装饰模式有四个主要角色:
-
抽象组件(Component):定义了一个抽象接口,用于被具体组件和具体装饰器实现。
-
具体组件(Concrete Component):实现了抽象组件接口,是被装饰的对象。
-
抽象装饰器(Decorator):继承自抽象组件,并包含一个抽象组件的引用,用于对组件进行装饰。
-
具体装饰器(Concrete Decorator):继承自抽象装饰器,并实现了具体的装饰逻辑。
装饰模式的工作原理如下:
-
抽象组件定义了组件的接口,具体组件实现了该接口。
-
抽象装饰器继承自抽象组件,并包含一个抽象组件的引用。
-
具体装饰器继承自抽象装饰器,并实现了具体的装饰逻辑。
-
客户端可以通过抽象组件的引用调用组件的方法,而具体装饰器会在调用前后添加额外的功能。
装饰模式的优点包括:
-
可以动态地添加或删除对象的功能,避免了使用继承的静态特性。
-
可以按需添加多个装饰器,实现不同的组合效果。
-
可以保持对象接口的一致性,使得客户端无需关心具体的装饰器。
装饰模式适用于以下场景:
-
当需要在不改变现有对象结构的情况下,动态地向对象添加额外功能时,可以使用装饰模式。
-
当需要按需添加多个额外功能的组合时,可以使用装饰模式。
总结而言,装饰模式通过动态地向对象添加额外的功能,而不改变现有对象结构。它提供了一种灵活的方式来扩展对象的功能,并保持了对象接口的一致性。
Component
public abstract class Person { public virtual string Name { get; set; } public virtual void Eat() { Console.WriteLine($"{Name}能吃饭"); } public virtual void Sleep() { Console.WriteLine($"{Name}能睡觉"); } public abstract void Invoke(); }
Concrete Component
/// <summary> /// 婴儿 /// </summary> public sealed class Baby : Person { public override void Invoke() { this.Eat(); this.Sleep(); } }
Decorator
public abstract class Decorater:Person { protected Person person { get; private set; } = null; public Decorater(Person person) { this.person = person; } public override void Invoke() { if(person !=null) { person.Invoke(); } } }
Concrete Decorator
public sealed class Child : Decorater { public Child(Person person) : base(person) { this.Name= person.Name; } public override void Invoke() { base.Invoke(); Console.WriteLine($"{Name}长大了,7岁"); } }
public sealed class Boy : Decorater { public Boy(Person person) : base(person) { this.Name= person.Name; } public override void Invoke() { base.Invoke(); Console.WriteLine($"{Name}成年了,可以结婚!"); } }
调用
public class Client { public void Start() { Baby baby = new Baby() { Name = "张三" }; baby.Invoke(); Console.WriteLine("--------------装饰-------------------"); //装饰 Child child=new Child(baby); child.Invoke(); Console.WriteLine("------------------------------------"); Boy boy = new Boy(child); boy.Invoke(); } }
static void Main(string[] args) { new Client().Start(); Console.ReadKey(); Console.WriteLine("Hello, World!"); }