程序设计中的主要设计模式通常分为三大类,共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.外观模式(Facade Pattern)简介
外观模式是一种结构型设计模式,它为复杂的子系统提供一个简化的接口。外观模式通过定义一个高层接口,使得客户端更容易使用子系统,而无需了解其内部的复杂性。
外观模式的主要角色:
-
Facade(外观):提供一个简化的接口,封装了子系统的复杂性。客户端通过外观类与子系统交互。
-
Subsystem Classes(子系统类):实现子系统的功能。外观类将这些类组合在一起,提供一个统一的接口。
5.外观模式的适用场景:
-
简化复杂系统:当系统非常复杂时,外观模式可以为客户端提供一个简单的接口,隐藏系统的复杂性。
-
解耦客户端与子系统:外观模式可以将客户端与子系统解耦,使得子系统的变化不会影响到客户端。
-
分层设计:外观模式可以用于分层设计中,为每一层提供一个统一的接口。
6.C# 代码示例
下面是一个简单的C#示例,展示了如何使用外观模式来简化一个家庭影院系统的操作。
csharp
using System;// 子系统类:DVD播放器
public class DvdPlayer
{public void On(){Console.WriteLine("DVD Player is on");}public void Play(string movie){Console.WriteLine("Playing movie: " + movie);}public void Off(){Console.WriteLine("DVD Player is off");}
}// 子系统类:投影仪
public class Projector
{public void On(){Console.WriteLine("Projector is on");}public void WideScreenMode(){Console.WriteLine("Projector is in widescreen mode");}public void Off(){Console.WriteLine("Projector is off");}
}// 子系统类:音响系统
public class SoundSystem
{public void On(){Console.WriteLine("Sound System is on");}public void SetVolume(int level){Console.WriteLine("Sound System volume set to " + level);}public void Off(){Console.WriteLine("Sound System is off");}
}// 外观类:家庭影院外观
public class HomeTheaterFacade
{private DvdPlayer _dvdPlayer;private Projector _projector;private SoundSystem _soundSystem;public HomeTheaterFacade(DvdPlayer dvdPlayer, Projector projector, SoundSystem soundSystem){_dvdPlayer = dvdPlayer;_projector = projector;_soundSystem = soundSystem;}public void WatchMovie(string movie){Console.WriteLine("Get ready to watch a movie...");_dvdPlayer.On();_projector.On();_projector.WideScreenMode();_soundSystem.On();_soundSystem.SetVolume(10);_dvdPlayer.Play(movie);}public void EndMovie(){Console.WriteLine("Shutting down the home theater...");_dvdPlayer.Off();_projector.Off();_soundSystem.Off();}
}// 客户端代码
public class Client
{public static void Main(string[] args){// 创建子系统对象DvdPlayer dvdPlayer = new DvdPlayer();Projector projector = new Projector();SoundSystem soundSystem = new SoundSystem();// 创建外观对象HomeTheaterFacade homeTheater = new HomeTheaterFacade(dvdPlayer, projector, soundSystem);// 使用外观类来简化操作homeTheater.WatchMovie("Inception");Console.WriteLine("\nMovie is playing...\n");homeTheater.EndMovie();}
}
7.代码解析
-
子系统类:
DvdPlayer
、Projector
和SoundSystem
是子系统类,分别代表家庭影院系统中的不同组件。每个类都有自己的方法,如打开、关闭、播放等。 -
外观类:
HomeTheaterFacade
是外观类,它封装了子系统的复杂性,并提供了一个简化的接口WatchMovie
和EndMovie
。客户端只需要调用这两个方法,就可以完成看电影和关闭家庭影院的操作。 -
客户端代码:客户端通过创建子系统对象并将其传递给外观类来使用外观模式。然后,客户端只需调用外观类的方法,而无需直接与子系统类交互。
8.总结
外观模式通过提供一个简化的接口,隐藏了系统的复杂性,使得客户端更容易使用系统。它特别适用于复杂系统,可以将客户端与子系统解耦,使得子系统的变化不会影响到客户端。在实际应用中,外观模式可以用于简化API、分层设计等场景。