程序设计中的主要设计模式通常分为三大类,共23种:
1. 创建型模式(Creational Patterns)
-
单例模式(Singleton):确保一个类只有一个实例,并提供全局访问点。
-
工厂方法模式(Factory Method):定义创建对象的接口,由子类决定实例化哪个类。
-
抽象工厂模式(Abstract Factory):提供一个创建一系列相关或依赖对象的接口,而无需指定具体类。
-
建造者模式(Builder):将一个复杂对象的构建与其表示分离,使同样的构建过程可以创建不同的表示。
-
原型模式(Prototype):通过复制现有对象来创建新对象。
2. 结构型模式(Structural Patterns)
-
适配器模式(Adapter):将一个类的接口转换成客户希望的另一个接口。
-
桥接模式(Bridge):将抽象部分与实现部分分离,使它们可以独立变化。
-
组合模式(Composite):将对象组合成树形结构以表示“部分-整体”的层次结构。
-
装饰器模式(Decorator):动态地给对象添加职责,相比生成子类更为灵活。
-
外观模式(Facade):为子系统中的一组接口提供一个统一的接口。
-
享元模式(Flyweight):通过共享技术有效地支持大量细粒度对象。
-
代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。
3. 行为型模式(Behavioral Patterns)
-
责任链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者与接收者耦合。
-
命令模式(Command):将请求封装为对象,使你可以用不同的请求对客户进行参数化。
-
解释器模式(Interpreter):给定一个语言,定义其文法的一种表示,并定义一个解释器。
-
迭代器模式(Iterator):提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部表示。
-
中介者模式(Mediator):定义一个中介对象来封装一系列对象之间的交互。
-
备忘录模式(Memento):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
-
观察者模式(Observer):定义对象间的一对多依赖关系,当一个对象改变状态时,所有依赖者都会收到通知并自动更新。
-
状态模式(State):允许对象在其内部状态改变时改变其行为。
-
策略模式(Strategy):定义一系列算法,将它们封装起来,并使它们可以互相替换。
-
模板方法模式(Template Method):定义一个操作中的算法骨架,将一些步骤延迟到子类中。
-
访问者模式(Visitor):表示一个作用于某对象结构中的各元素的操作,使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。
4.组合模式(Composite Pattern)解释
组合模式是一种结构型设计模式,它允许你将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得客户端可以统一地处理单个对象和组合对象,从而简化了客户端代码。
组合模式的核心思想是:
-
组件(Component):定义了一个接口,用于访问和管理组件的子组件。它可以是抽象类或接口。
-
叶子节点(Leaf):表示树形结构中的叶子节点,它没有子节点。
-
复合节点(Composite):表示树形结构中的分支节点,它可以包含子节点(叶子节点或其他复合节点)。
通过这种方式,组合模式可以让你以一致的方式处理单个对象和组合对象,从而简化了代码的复杂性。
5.组合模式的C#演示代码
下面是一个简单的C#示例,展示了如何使用组合模式来实现一个文件系统的层次结构。在这个系统中,组件是文件系统中的节点(文件或文件夹),叶子节点是文件,复合节点是文件夹。
csharp
using System;
using System.Collections.Generic;
// 组件接口
public interface IFileSystemComponent
{
void Display(int depth);
}
// 叶子节点:文件
public class File : IFileSystemComponent
{
private string name;
public File(string name)
{
this.name = name;
}
public void Display(int depth)
{
Console.WriteLine(new string('-', depth) + name);
}
}
// 复合节点:文件夹
public class Folder : IFileSystemComponent
{
private string name;
private List<IFileSystemComponent> components = new List<IFileSystemComponent>();
public Folder(string name)
{
this.name = name;
}
public void AddComponent(IFileSystemComponent component)
{
components.Add(component);
}
public void RemoveComponent(IFileSystemComponent component)
{
components.Remove(component);
}
public void Display(int depth)
{
Console.WriteLine(new string('-', depth) + name);
// 递归显示子组件
foreach (var component in components)
{
component.Display(depth + 2);
}
}
}
// 客户端代码
class Program
{
static void Main(string[] args)
{
// 创建文件
IFileSystemComponent file1 = new File("File1.txt");
IFileSystemComponent file2 = new File("File2.txt");
IFileSystemComponent file3 = new File("File3.txt");
// 创建文件夹
Folder folder1 = new Folder("Folder1");
Folder folder2 = new Folder("Folder2");
// 将文件添加到文件夹中
folder1.AddComponent(file1);
folder1.AddComponent(file2);
folder2.AddComponent(file3);
// 将文件夹添加到另一个文件夹中
Folder rootFolder = new Folder("Root");
rootFolder.AddComponent(folder1);
rootFolder.AddComponent(folder2);
// 显示整个文件系统结构
rootFolder.Display(0);
}
}
6.代码说明
-
IFileSystemComponent接口:定义了文件系统组件的接口,包含一个
Display
方法,用于显示组件的名称和层次结构。 -
File类:表示文件系统中的文件,是叶子节点。它实现了
IFileSystemComponent
接口,并在Display
方法中显示文件的名称。 -
Folder类:表示文件系统中的文件夹,是复合节点。它实现了
IFileSystemComponent
接口,并包含一个List<IFileSystemComponent>
来存储子组件(文件或其他文件夹)。Folder
类还提供了AddComponent
和RemoveComponent
方法来管理子组件。在Display
方法中,它首先显示文件夹的名称,然后递归地显示所有子组件。 -
客户端代码:在
Main
方法中,我们创建了一些文件和文件夹,并将它们组合成一个树形结构。最后,我们调用根文件夹的Display
方法来显示整个文件系统的层次结构。
7.总结
组合模式通过将对象组合成树形结构来表示“部分-整体”的层次结构,使得客户端可以统一地处理单个对象和组合对象。这种模式非常适合用于需要处理树形结构的场景,如文件系统、菜单系统等。通过组合模式,我们可以简化客户端代码,并提高系统的灵活性和可扩展性。