【愚公系列】2021年12月 二十三种设计模式(九)-装饰者模式(Decorator Pattern)

简介: 【愚公系列】2021年12月 二十三种设计模式(九)-装饰者模式(Decorator Pattern)

文章目录

前言

一、装饰者模式(Decorator Pattern)

二、使用步骤

角色

示例

总结

优点

缺点

使用场景

前言

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。


提示:以下是本篇文章正文内容,下面案例可供参考


一、装饰者模式(Decorator Pattern)

装饰者模式属于结构型模式,装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。


装饰者模式通过创建一个包装对象(wrapper),也就是用装饰来包裹真实的对象。


二、使用步骤

角色

1、抽象构件(Component)


给出一个抽象接口,以规范准备接收附加责任的对象;


2、具体构件(Concrete Component)


定义一个将要接收附加责任的类;


3、抽象装饰(Decorator)


持有一个构件(Component)对象的实例,并实现一个与抽象构件接口一致的接口;


4、具体装饰(Concrete Decorator)


负责给构件对象添加上附加的责任。


示例

image.png

命名空间DecoratorPattern中包含汽车Car类、玛莎拉蒂Maserati类、法拉利Fabbrica类、酷汽车CoolCar类、汽车车贴Paster类和汽车遮阳挡Visor类。本示例通过使用装饰者模式为汽车进行一次简单的外观装饰。

public abstract class Car {
    public string Name { get; set; }
    public abstract void StartUp();
}

汽车基类Car,充当抽象构件。

public class Fabbrica : Car {
    public Fabbrica() {
        Name = "Fabbrica";
    }
    public override void StartUp() {
        Console.WriteLine($"{Name} is starting!");
    }
}

法拉利Fabbrica类,充当具体构件。

public class Maserati : Car {
    public Maserati() {
        Name = "Maserati";
    }
    public override void StartUp() {
        Console.WriteLine($"{Name} is starting!");
    }
}

玛莎拉蒂Maserati类,充当具体构件。

public abstract class CoolCar : Car {
    protected Car _car = null;
    public CoolCar(Car car) {
        _car = car;
    }
    public override void StartUp() {
        Console.WriteLine($"{_car.Name} is starting!");
    }
}

酷汽车CoolCar类,充当抽象装饰。

public class Paster : CoolCar {
    public Paster(Car car) : base(car) {
    }
    public override void StartUp() {
        SetPaster();
        base.StartUp();
    }
    private void SetPaster() {
        Console.WriteLine($"Set paster to {_car.Name}!");
    }
}

汽车车贴Paster类,通过继承CoolCar类,为对汽车进行装饰提供了可能。

public class Visor : CoolCar {
    public Visor(Car car) : base(car) {
    }
    public override void StartUp() {
        SetVisor();
        base.StartUp();
    }
    private void SetVisor() {
        Console.WriteLine($"Set visor to {_car.Name}!");
    }
}

汽车遮阳挡Visor 类,通过继承CoolCar类,为对汽车进行装饰提供了可能。

public class Program {
    private const string LINE_SPLIT = "-------------------------";
    private static Car _car = null;
    private static CoolCar _coolCar = null;
    public static void Main(string[] args) {
        _car = new Maserati();
        _coolCar = new Visor(_car);
        _coolCar.StartUp();
        Console.WriteLine(LINE_SPLIT);
        _car = new Fabbrica();
        _coolCar = new Paster(_car);
        _coolCar.StartUp();
        Console.WriteLine(LINE_SPLIT);
        Console.ReadKey();
    }
}

以上是调用方的代码,以下是这个案例的输出结果:

Set visor to Maserati!
Maserati is starting!
-------------------------
Set paster to Fabbrica!
Fabbrica is starting!
-------------------------

总结

优点

1、装饰者模式与继承关系的目的都是要扩展对象的功能,但是装饰者模式可以提供比继承更多的灵活性;

2、通过使用不同的具体装饰类以及这些装饰类的排列组合,开发者可以创造出很多不同行为的组合。


缺点

1、这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性;

2、装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂;

3、装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。


使用场景

1、需要扩展一个类的功能,或给一个类添加附加职责;

2、需要动态的给一个对象添加功能,这些功能可以再动态的撤销;

3、需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实;

4、当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸式增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。


相关文章
|
8天前
|
设计模式 Java Kotlin
Kotlin教程笔记(56) - 改良设计模式 - 装饰者模式
Kotlin教程笔记(56) - 改良设计模式 - 装饰者模式
18 0
|
15天前
|
设计模式 Java Kotlin
Kotlin 学习笔记- 改良设计模式 - 装饰者模式
Kotlin 学习笔记- 改良设计模式 - 装饰者模式
24 0
|
2月前
|
设计模式
设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)
这篇文章详细解释了工厂模式,包括简单工厂、工厂方法和抽象工厂三种类型。每种模式都通过代码示例展示了其应用场景和实现方法,并比较了它们之间的差异。简单工厂模式通过一个工厂类来创建各种产品;工厂方法模式通过定义一个创建对象的接口,由子类决定实例化哪个类;抽象工厂模式提供一个创建相关或依赖对象家族的接口,而不需要明确指定具体类。
设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)
|
18天前
|
设计模式 Java Kotlin
Kotlin教程笔记(56) - 改良设计模式 - 装饰者模式
Kotlin教程笔记(56) - 改良设计模式 - 装饰者模式
21 0
|
2月前
|
设计模式 Java
设计模式--适配器模式 Adapter Pattern
这篇文章介绍了适配器模式,包括其基本介绍、工作原理以及类适配器模式、对象适配器模式和接口适配器模式三种实现方式。
|
5月前
|
设计模式
设计模式-05建造者模式(Builder Pattern)
设计模式-05建造者模式(Builder Pattern)
|
5月前
|
设计模式 Java API
程序技术好文:设计模式:装饰者模式
程序技术好文:设计模式:装饰者模式
25 0
|
6月前
|
设计模式 安全 Java
【设计模式】JAVA Design Patterns——Curiously Recurring Template Pattern(奇异递归模板模式)
该文介绍了一种C++的编程技巧——奇异递归模板模式(CRTP),旨在让派生组件能继承基本组件的特定功能。通过示例展示了如何创建一个`Fighter`接口和`MmaFighter`类,其中`MmaFighter`及其子类如`MmaBantamweightFighter`和`MmaHeavyweightFighter`强制类型安全,确保相同重量级的拳手之间才能进行比赛。这种设计避免了不同重量级拳手间的错误匹配,编译时会报错。CRTP适用于处理类型冲突、参数化类方法和限制方法只对相同类型实例生效的情况。
【设计模式】JAVA Design Patterns——Curiously Recurring Template Pattern(奇异递归模板模式)
|
2月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
17天前
|
设计模式 Java Kotlin
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
本教程详细讲解Kotlin语法,适合希望深入了解Kotlin的开发者。对于快速学习Kotlin语法,推荐查看“简洁”系列教程。本文重点介绍了构建者模式在Kotlin中的应用与改良,包括如何使用具名可选参数简化复杂对象的创建过程,以及如何在初始化代码块中对参数进行约束和校验。
16 3

热门文章

最新文章