一、引言
设计模式是软件工程领域的宝贵财富,它总结了前人在软件开发过程中的经验教训。掌握设计模式,可以使我们的代码更加优雅、健壮。本文将带你了解23种设计模式,助你成为更优秀的程序员。
二、设计模式分类
设计模式分为三大类:创建型模式、结构型模式和行为型模式。
-
创建型模式:共5种,主要用于对象的创建。
-
结构型模式:共7种,主要用于处理类和对象之间的关系。
-
行为型模式:共11种,主要用于描述类和对象之间的交互。
三、23种设计模式详解
-
创建型模式
(1)单例模式:确保一个类只有一个实例,并提供一个全局访问点。
(2)工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。
(3)抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族。
(4)建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
(5)原型模式:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
-
结构型模式
(6)适配器模式:将一个类的接口转换成客户期望的另一个接口,使原本接口不兼容的类可以一起工作。
(7)装饰器模式:动态地给一个对象添加一些额外的职责,而不改变其接口。
(8)代理模式:为其他对象提供一种代理,以控制对这个对象的访问。
(9)外观模式:提供了一个统一的接口,用来访问子系统中的一群接口。
(10)桥接模式:将抽象部分与实现部分分离,使它们都可以独立地变化。
(11)组合模式:将对象组合成树形结构以表示“部分-整体”的层次结构。
(12)享元模式:运用共享技术有效地支持大量细粒度的对象。
-
行为型模式
(13)策略模式:定义一系列算法,将每个算法封装起来,并使它们可以相互替换。
(14)模板方法模式:定义一个操作中的算法骨架,将算法的一些步骤延迟到子类中实现。
(15)观察者模式:当一个对象的状态发生改变时,自动通知所有依赖于它的对象。
(16)状态模式:允许一个对象在其内部状态改变时改变它的行为。
(17)命令模式:将请求封装为一个对象,从而可以使用不同的请求、队列或日志来参数化其他对象。
(18)责任链模式:使多个对象都有机会处理请求,从而避免了请求发送者和接收者之间的耦合关系。
(19)中介者模式:用一个中介对象来封装一系列的对象交互。
(20)迭代器模式:提供一种方法顺序访问一个聚合对象中各个元素,而不暴露其内部的表示。
(21)访问者模式:表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。
(22)备忘录模式:捕获一个对象的内部状态,并在该对象之外保存这个状态。
(23)解释器模式:为语言创建解释器,用来解释该语言中的句子。
四、部分模式代码示例:
1、单例模式
单例模式确保一个类只有一个实例,并提供一个全局访问点。
public class Singleton {
private static Singleton instance;
// 私有构造函数,防止外部直接创建对象实例
private Singleton() {}
// 提供一个公共的静态方法,用于获取唯一实例
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
2、工厂方法模式
工厂方法模式定义了一个用于创建对象的接口,让子类决定实例化哪一个类。
// 抽象产品
interface Product {
void use();
}
// 具体产品A
class ConcreteProductA implements Product {
public void use() {
System.out.println("使用产品A");
}
}
// 具体产品B
class ConcreteProductB implements Product {
public void use() {
System.out.println("使用产品B");
}
}
// 抽象工厂
abstract class Factory {
abstract Product createProduct();
}
// 具体工厂A
class ConcreteFactoryA extends Factory {
public Product createProduct() {
return new ConcreteProductA();
}
}
// 具体工厂B
class ConcreteFactoryB extends Factory {
public Product createProduct() {
return new ConcreteProductB();
}
}
3、观察者模式
观察者模式定义了对象之间的一对多依赖关系,当一个对象改变状态时,所有依赖于它的对象都会得到通知并自动更新。
// 观察者接口
interface Observer {
void update(String event);
}
// 被观察者
class Subject {
private List<Observer> observers = new ArrayList<>();
public void addObserver(Observer observer) {
observers.add(observer);
}
public void removeObserver(Observer observer) {
observers.remove(observer);
}
public void notifyObservers(String event) {
for (Observer observer : observers) {
observer.update(event);
}
}
}
// 具体观察者
class ConcreteObserver implements Observer {
public void update(String event) {
System.out.println("观察者收到通知:" + event);
}
}
4、策略模式
策略模式定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的用户。
// 策略接口
interface Strategy {
void execute();
}
// 具体策略A
class ConcreteStrategyA implements Strategy {
public void execute() {
System.out.println("执行策略A");
}
}
// 具体策略B
class ConcreteStrategyB implements Strategy {
public void execute() {
System.out.println("执行策略B");
}
}
// 上下文
class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public void executeStrategy() {
strategy.execute();
}
}
5、代理模式 (Proxy)
代理模式为其他对象提供一种代理,以控制对这个对象的访问。
// 抽象主题接口
interface Subject {
void request();
}
// 具体主题
class RealSubject implements Subject {
public void request() {
System.out.println("RealSubject: Handling request.");
}
}
// 代理
class Proxy implements Subject {
private RealSubject realSubject;
public Proxy(RealSubject realSubject) {
this.realSubject = realSubject;
}
public void request() {
System.out.println("Proxy: Handling request.");
beforeRequest();
realSubject.request();
afterRequest();
}
private void beforeRequest() {
System.out.println("Proxy: before request.");
}
private void afterRequest() {
System.out.println("Proxy: after request.");
}
}
6、桥接模式 (Bridge)
桥接模式将抽象部分与实现部分分离,使它们都可以独立地变化。
// 抽象化角色
abstract class Shape {
protected DrawAPI drawAPI;
public Shape(DrawAPI drawAPI) {
this.drawAPI = drawAPI;
}
public abstract void draw();
}
// 实现化角色
class Circle extends Shape {
private int x, y, radius;
public Circle(DrawAPI drawAPI, int x, int y, int radius) {
super(drawAPI);
this.x = x;
this.y = y;
this.radius = radius;
}
public void draw() {
drawAPI.drawCircle(x, y, radius);
}
}
// 扩展抽象化角色
abstract class DrawAPI {
public abstract void drawCircle(int x, int y, int radius);
}
// 具体实现化角色
class RedCircleDrawAPI extends DrawAPI {
public void drawCircle(int x, int y, int radius) {
System.out.println("Drawing circle [" + x + ", " + y + ", " + radius + "] in red");
}
}
// 具体实现化角色
class GreenCircleDrawAPI extends DrawAPI {
public void drawCircle(int x, int y, int radius) {
System.out.println("Drawing circle [" + x + ", " + y + ", " + radius + "] in green");
}
}
7、装饰器模式 (Decorator)
装饰器模式动态地给一个对象添加一些额外的职责,而不改变其接口。
// 抽象构件
interface Beverage {
String getDescription();
double cost();
}
// 具体构件
class Espresso implements Beverage {
public String getDescription() {
return "Esp
五、总结
掌握23种设计模式,有助于我们在软件开发过程中更好地解决问题。然而,设计模式并非银弹,我们需要在实际项目中灵活运用,不断积累经验,才能发挥其最大价值。希望通过本文的介绍,你能对设计模式有更深入的了解,成为更优秀的程序员。