102、23种设计模式之装饰器模式(11/23)

发布于:2025-09-12 ⋅ 阅读:(25) ⋅ 点赞:(0)

一、定义

装饰器模式(Decorator Pattern)是一种结构型设计模式,允许在不修改原有类或继承体系的前提下,动态地为对象添加新功能。其核心思想是通过组合而非继承实现功能扩展,符合“开闭原则”(对扩展开放,对修改关闭)。

二、应用场景

1.动态扩展功能

需要运行时为对象灵活添加/移除功能,例如:

  • 为文本编辑器动态添加字体、颜色、下划线等格式。
  • 为咖啡店饮品动态添加配料(牛奶、糖浆等)。

2.避免继承导致的类爆炸

当继承会导致子类数量指数级增长时(如为每个功能组合创建子类),装饰器模式通过组合实现功能排列组合。

3.需要透明扩展的场景

客户端无需知道对象是否被装饰,接口保持一致(如Java IO流中的BufferedInputStream装饰FileInputStream)。

4.替代多层继承

如Android中为View动态添加边框、点击事件等,避免继承导致的层次过深。

三、优缺点

1.优点

  1. 灵活性高:动态添加/移除功能,无需修改原有代码。
  2. 避免类爆炸:通过组合实现功能扩展,减少子类数量。
  3. 符合开闭原则:对扩展开放,对修改关闭。

2.缺点

  1. 代码复杂度增加:多层装饰时,调试和追踪逻辑困难。
  2. 性能开销:多层装饰可能增加对象创建和调用的开销。
  3. 接口污染风险:装饰器需实现与被装饰对象相同的接口,可能暴露不必要的方法。

四、C# 示例代码

以下示例模拟为Person对象动态添加“红帽子”和“黑外套”装饰:

using System;

// 1. 定义组件接口
public interface IPerson
{
    void Introduce();
}

// 2. 具体组件:原始对象
public class Person : IPerson
{
    private string _name;
    private int _age;

    public Person(string name, int age)
    {
        _name = name;
        _age = age;
    }

    public void Introduce()
    {
        Console.WriteLine($"我叫{_name},今年{_age}岁");
    }
}

// 3. 抽象装饰器:持有组件引用
public abstract class PersonDecorator : IPerson
{
    protected IPerson _person;

    public PersonDecorator(IPerson person)
    {
        _person = person;
    }

    public virtual void Introduce()
    {
        _person.Introduce();
    }
}

// 4. 具体装饰器:红帽子
public class PersonRedHatDecorator : PersonDecorator
{
    public PersonRedHatDecorator(IPerson person) : base(person) { }

    public override void Introduce()
    {
        base.Introduce();
        Console.WriteLine("我有一顶红色的帽子");
    }
}

// 5. 具体装饰器:黑外套
public class PersonBlackJacketDecorator : PersonDecorator
{
    public PersonBlackJacketDecorator(IPerson person) : base(person) { }

    public override void Introduce()
    {
        base.Introduce();
        Console.WriteLine("我有一件黑色的外套");
    }
}

// 6. 客户端代码
class Program
{
    static void Main(string[] args)
    {
        // 原始对象
        IPerson person = new Person("张三", 18);
        person.Introduce();

        Console.WriteLine("---------装饰上红帽子---------");
        person = new PersonRedHatDecorator(person);
        person.Introduce();

        Console.WriteLine("---------装饰上黑外套---------");
        person = new PersonBlackJacketDecorator(person);
        person.Introduce();
    }
}

输出结果:

我叫张三,今年18---------装饰上红帽子---------
我叫张三,今年18岁
我有一顶红色的帽子
---------装饰上黑外套---------
我叫张三,今年18岁
我有一顶红色的帽子
我有一件黑色的外套

五、关键点总结

  1. 装饰器与被装饰对象实现相同接口,确保客户端代码无感知。
  2. 装饰器持有被装饰对象的引用,通过组合实现功能叠加。
  3. 支持多层装饰,如示例中先添加红帽子,再添加黑外套。
  4. 典型应用:Java IO流、ASP.NET Core中间件、GUI组件扩展等。

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到