结构型模式
适配器模式(Adapter Pattern)
适配器模式(Adapter Pattern)是一种结构型设计模式,它允许不兼容的接口之间可以一起工作。这种模式通常用于系统后期维护和扩展过程中,帮助已存在的系统与第三方库、API 或者是遗留系统进行交互,而无需修改原有代码。
适配器模式的组成
适配器模式通常包括以下几个组件:
示例:电源适配器
假设有一个简单的场景:一个美国制造的电器只能接受120伏的电压,而欧洲的标准电压是230伏。我们需要一个电源适配器来使这个电器能在欧洲正常工作。
首先,定义目标接口,即客户希望使用的接口:
然后是已存在的类,即被适配者:
接着,实现适配器类,使其兼容目标接口:
最后,客户端代码演示如何使用适配器:
在这个示例中,SocketAdapter 类通过将 AmericanSocket 类包装进一个实现了 IEuropeanSocket 接口的适配器中,使得原本只能接受120伏电压的美国电器可以在230伏的欧洲电压下安全工作。适配器负责接口之间的转换和兼容性处理,客户端代码则可以保持不变,依然使用期望的接口进行操作。这样的设计增强了代码的可维护性和扩展性.
桥接模式(Bridge Pattern)
桥接模式(Bridge Pattern)是一种结构型设计模式,用于将抽象与其实现分离,使得两者可以独立地变化。这种模式通过提供一个桥接结构,使得抽象部分的代码可以与接口实现部分的代码分离,从而减少彼此间的依赖关系。
桥接模式的组成
桥接模式通常包含以下几个部分:
示例:遥控器和电视
假设我们要设计一个遥控器系统,不同品牌的电视可以通过不同类型的遥控器进行控制。遥控器就是抽象部分,而电视就是实现部分。
1. 实现者接口(Implementor)
2. 具体实现(Concrete Implementor)
为两种品牌的电视实现上述接口:
3. 抽象(Abstraction)
定义遥控器的抽象类:
4. 扩展抽象(Refined Abstraction)
实现具体的遥控器类:
5. 客户端使用
桥接模式使得抽象部分和实现部分可以独立扩展,不仅提高了系统的灵活性,还使得代码更易于维护。在这个例子中,添加一个新品牌的电视或者改变遥控器的设计不会影响到另一方,这正是桥接模式所提供的优势。
组合模式(Composite Pattern)
组合模式(Composite Pattern)是一种结构型设计模式,它允许你将对象组合成树形结构以表示部分-整体的层次结构。组合模式使得客户端对单个对象和组合对象的使用具有一致性。
组合模式的组成
组合模式主要包括以下几个角色:
示例:文件系统
在这个示例中,我们将使用组合模式来构建一个简单的文件系统,包括文件和文件夹。
1. 组件接口
2. 叶节点(Leaf)
3. 复合组件(Composite)
4. 客户端使用
使用以及执行结果:
在这个例子中,Directory 类(复合组件)可以包含其他 Directory 对象或 File 对象(叶节点),形成一个树形结构。每个组件都实现了 FileSystemComponent 接口,这使得客户端在处理文件和文件夹时可以具有一致的方式。通过调用 Display 方法,可以展示整个文件系统的结构,展示每个文件和文件夹的层次。这种设计使得添加或删除新的文件类型或文件夹时,对其他代码的影响最小,体现了组合模式的优势,即“使用户对单个对象和组合对象的使用具有一致性”。
装饰模式(Decorator Pattern)
装饰模式(Decorator Pattern)是一种结构型设计模式,它允许用户在不修改现有对象的结构的情况下,向对象添加新的功能。装饰模式通过创建一个包含目标对象的包装对象来实现新功能的添加,这样既扩展了对象的功能,也遵守了开闭原则(对扩展开放,对修改关闭)。
装饰模式的组成
装饰模式主要涉及以下几个角色:
示例:咖啡店
在这个例子中,我们将使用装饰模式来模拟咖啡店的订单系统,其中顾客可以选择不同类型的咖啡,并可添加多种调料。
1. 抽象组件(Component)
2. 具体组件(ConcreteComponent)
定义几种咖啡:
3. 装饰角色(Decorator)
4. 具体装饰(ConcreteDecorator)
定义几种调料装饰:
5. 客户端使用
实际调用和结果输出如下
在这个示例中,Espresso 和 HouseBlend 是具体的咖啡,分别实现了 Beverage 抽象类。Mocha 和 Hand 是装饰者,它们继承自 CondimentDecorator,这是一个抽象装饰类。每个装饰者类增加了额外的行为(添加调料)并调整了价格。通过装饰者,可以灵活地添加或修改对象的行为,同时保持代码的简洁和可维护性。这种方式非常适合于功能频繁变化的系统。
外观模式(Facade Pattern)
外观模式(Facade Pattern)是一种常用的软件设计模式,它提供了一个高层次的接口,使得系统更加容易使用。外观模式常常用于为复杂的系统或库提供一个简单的接口,减少系统间的依赖,增加子系统的独立性和可移植性。
设计目的
外观模式的主要目的是隐藏系统的复杂性,提供一个简化的接口给客户端。通过这种方式,如果后续系统内部发生变化,客户端代码不需要改动;只需要在外观类中调整即可。
使用场景
实现步骤
示例
假设有一个复杂的音频系统,包含了多个组件,如音量控制、信号处理、音频播放等。我们可以创建一个外观类,来简化和统一这些操作。
C#代码实现
首先,定义一些子系统类:
接下来,创建外观类:
最后,使用方式以及运行效果:
在上述例子中,AudioFacade 类提供了一个简单的接口 PlaySound,客户端通过这个接口可以很容易地播放音频而不需要直接与复杂的子系统交互。这样,客户端代码变得更简单,同时也增强了系统各部分之间的独立性。
享元模式(Flyweight Pattern)
享元模式(Flyweight Pattern)是一种用于性能优化的结构型设计模式。这个模式通过共享尽可能多的相似对象来减少内存使用,特别适用于处理大量对象时,其中许多对象由重复的状态组成。
设计目的
享元模式的主要目的是在有大量相似对象的情况下,通过共享尽可能多的对象以减少内存消耗。这通常是通过将这些对象的状态分为“内部状态”(intrinsic)和“外部状态”(extrinsic)来实现的:
使用场景
示例
假设有一个文档编辑器,它可以设置字符的样式。每个字符可以是一个对象,但是样式(如字体、大小)很可能在多个字符中是相同的。这里,样式可以作为内部状态,由享元对象共享,而每个字符的位置可以作为外部状态由客户端代码来管理。
C#代码实现
首先,定义享元类及接口:
然后,创建享元工厂:
具体使用和运行结果如下:
代理模式(Proxy Pattern)
代理模式(Proxy Pattern)是一种结构型设计模式,它通过提供一个替代品或代表其他对象来控制对这个对象的访问。代理模式可以用于多种情景,例如延迟初始化、访问控制、日志记录和智能引用等。它主要用于控制和管理对象的访问。
设计目的
代理模式的主要目的是:
使用场景
示例
假设有一个文档加载和显示系统,我们想通过使用代理模式来控制对文档的访问,假设加载文档是一个资源密集的操作。
C#代码实现
首先,定义一个文档接口和实现该接口的实际类:
接着,创建代理类:
使用方式和运行效果如下:
以上就是结构型设计模式的所有演示内容,感兴趣可以上gitee获取以上测试的源码:
https://gitee.com/dreamer_j/design-patterns.git
本文分享自 Dotnet Dancer 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!