在编程中,你可能会遇到这样的问题:

  • 同样的功能要写好多次?
  • 代码结构混乱,改一个地方牵一发动全身?
  • 不知道怎么组织代码,让别人更容易看懂?

别担心,设计模式就是为了解决这些问题而存在的!

一、什么是设计模式?

设计模式(Design Pattern)是前人总结出来的一套通用、可复用的代码结构模板,用来解决开发中的一些常见问题。

你可以把它理解为:

“别人已经踩过的坑,已经总结成了经验,你只需要学会怎么用。”


二、为什么要学设计模式?

优点 说明
提高代码可维护性 代码结构清晰,容易修改
提高代码复用率 一个模式可以在多个项目中使用
更容易协作开发 大家都懂的设计语言,沟通更顺畅
提升编程思维 学会“如何组织代码”而不是“怎么写代码”

三、10 种常见设计模式详解(适合新手)


1. 工厂模式(Factory Pattern)

场景:你不想直接 new 一个对象,而是想“统一创建方式”。
举个生活例子:

你想买一台电脑,但你不关心它是怎么组装的,只要它能运行。你去找“组装工厂”下单,它就给你一台电脑。

代码示例:
function createComputer(type) {
    if (type === "gaming") {
        return { cpu: "i9", gpu: "RTX4090" };
    } else if (type === "office") {
        return { cpu: "i5", gpu: "集成显卡" };
    }
}

let myPc = createComputer("gaming");
✅ 使用场景:
  • 创建对象的过程复杂,想隐藏细节
  • 统一调用接口创建不同对象

2. 观察者模式(Observer Pattern)

场景:当某个对象发生变化时,通知其他对象做出反应。
举个生活例子:

你关注了一个微信公众号,公众号一更新文章,你就收到通知。

代码示例:
class Subject {
    constructor() {
        this.observers = [];
    }

    subscribe(fn) {
        this.observers.push(fn);
    }

    notify(data) {
        this.observers.forEach(fn => fn(data));
    }
}

let subject = new Subject();

subject.subscribe(msg => console.log("收到通知:" + msg));

subject.notify("新文章发布了!"); // 输出:收到通知:新文章发布了!
✅ 使用场景:
  • 状态变化通知多个对象
  • 实现事件机制(如 Vue 的 $emit)

3. 策略模式(Strategy Pattern)

场景:根据不同的条件,执行不同的策略。
举个生活例子:

你去餐厅点餐,根据你选择的套餐(A/B/C),服务员给你不同的菜品。

代码示例:
let strategies = {
    "A": () => console.log("套餐A:鱼香肉丝 + 汤"),
    "B": () => console.log("套餐B:宫保鸡丁 + 米饭"),
    "C": () => console.log("套餐C:牛肉面")
};

function orderMeal(type) {
    strategies[type]();
}

orderMeal("B"); // 输出:套餐B:宫保鸡丁 + 米饭
✅ 使用场景:
  • 根据不同条件执行不同逻辑
  • 替代大量 if-else 判断

4. 单例模式(Singleton Pattern)

场景:确保一个类只有一个实例。
举个生活例子:

一个公司只有一个 CEO,无论你在哪里调用,都是同一个。

代码示例:
class CEO {
    constructor() {
        if (!CEO.instance) {
            this.name = "张总";
            CEO.instance = this;
        }
        return CEO.instance;
    }
}

let ceo1 = new CEO();
let ceo2 = new CEO();

console.log(ceo1 === ceo2); // true
✅ 使用场景:
  • 全局配置、数据库连接、登录状态等只需要一个实例

5. 代理模式(Proxy Pattern)

场景:控制对某个对象的访问,比如加权限、缓存等。
举个生活例子:

你想见明星,不能直接找本人,得通过经纪人(代理)来安排。

代码示例:
let star = {
    name: "明星A",
    sing() {
        console.log("明星唱歌了");
    }
};

let agent = new Proxy(star, {
    get(target, prop) {
        if (prop === "sing") {
            console.log("经纪人同意了,可以唱歌");
            return target[prop];
        }
        console.log("不允许访问");
    }
});

agent.sing(); // 输出:经纪人同意了,可以唱歌
✅ 使用场景:
  • 权限控制
  • 缓存、日志、性能监控

6. 组合模式(Composite Pattern)

场景:把对象组织成树形结构,统一处理叶子节点和组合节点。
举个生活例子:

一个文件夹里可以放文件,也可以放子文件夹,统一管理。

 代码示例:
class File {
    constructor(name) {
        this.name = name;
    }

    display() {
        console.log("文件:" + this.name);
    }
}

class Folder {
    constructor(name) {
        this.name = name;
        this.children = [];
    }

    add(child) {
        this.children.push(child);
    }

    display() {
        console.log("文件夹:" + this.name);
        this.children.forEach(child => child.display());
    }
}

let folder = new Folder("文档");
folder.add(new File("简历.docx"));
folder.add(new File("项目说明.txt"));

folder.display();
// 输出:
// 文件夹:文档
// 文件:简历.docx
// 文件:项目说明.txt
✅ 使用场景:
  • 文件系统、菜单树、组织结构图等

7. 装饰模式(Decorator Pattern)

📌 场景:动态地给对象添加功能,不改变原有结构。
举个生活例子:

你买了一台电脑,可以随时加装内存、硬盘、键盘等配件。

代码示例:
function Computer() {
    this.cost = 5000;
}

function withRam(computer) {
    computer.cost += 500;
    return computer;
}

function withSSD(computer) {
    computer.cost += 1000;
    return computer;
}

let myPc = new Computer();
myPc = withRam(myPc);
myPc = withSSD(myPc);

console.log("总价:" + myPc.cost); // 输出:总价:6500
✅ 使用场景:
  • 不想修改原对象,但想增强功能
  • 动态添加功能(如权限、日志、缓存)

8. 命令模式(Command Pattern)

场景:将请求封装成对象,方便统一处理。
举个生活例子:

你用遥控器按“开机”按钮,遥控器会发送“开机命令”给电视。

代码示例:
class Light {
    on() {
        console.log("灯打开了");
    }

    off() {
        console.log("灯关了");
    }
}

class Command {
    constructor(light) {
        this.light = light;
    }

    execute() {
        this.light.on();
    }
}

let light = new Light();
let command = new Command(light);
command.execute(); // 输出:灯打开了
✅ 使用场景:
  • 撤销/重做操作
  • 请求排队、记录日志

9. 外观模式(Facade Pattern)

场景:为复杂的接口提供一个简化版的接口。
举个生活例子:

你买了一个“一键启动”的智能车,不用管发动机、油门、点火器,只要按一个按钮。

代码示例:
class Engine {
    start() {
        console.log("发动机启动");
    }
}

class Lights {
    on() {
        console.log("车灯亮了");
    }
}

class CarFacade {
    constructor() {
        this.engine = new Engine();
        this.lights = new Lights();
    }

    startCar() {
        this.lights.on();
        this.engine.start();
        console.log("汽车启动完成");
    }
}

let car = new CarFacade();
car.startCar();
// 输出:
// 车灯亮了
// 发动机启动
// 汽车启动完成
✅ 使用场景:
  • 简化复杂 API 的使用
  • 隐藏实现细节

10. 中介者模式(Mediator Pattern)

场景:多个对象之间通信太复杂,引入一个“中间人”来协调。
举个生活例子:

飞机和飞机之间不能直接通信,而是通过“空管中心”来协调飞行。

代码示例:
class Airplane {
    constructor(name, mediator) {
        this.name = name;
        this.mediator = mediator;
    }

    send(message) {
        this.mediator.sendMessage(message, this);
    }

    receive(message) {
        console.log(this.name + " 收到消息:" + message);
    }
}

class AirTrafficControl {
    constructor() {
        this.airplanes = [];
    }

    register(airplane) {
        this.airplanes.push(airplane);
    }

    sendMessage(message, sender) {
        this.airplanes.forEach(plane => {
            if (plane !== sender) {
                plane.receive(message);
            }
        });
    }
}

let mediator = new AirTrafficControl();

let planeA = new Airplane("PlaneA", mediator);
let planeB = new Airplane("PlaneB", mediator);

mediator.register(planeA);
mediator.register(planeB);

planeA.send("我要降落"); // PlaneB 收到消息:我要降落
✅ 使用场景:
  • 多个组件之间通信频繁
  • 解耦多个对象之间的依赖

✅ 总结:10 种设计模式一览表(适合新手记忆)

模式 一句话说明 使用场景
工厂模式 用一个函数统一创建对象 创建对象的过程复杂
观察者模式 对象变化时通知其他人 状态变化通知
策略模式 不同条件执行不同逻辑 替代 if-else
单例模式 一个类只能有一个实例 全局唯一对象
代理模式 控制对象访问 权限、缓存
组合模式 树形结构统一处理 文件系统、菜单
装饰模式 动态增强功能 不修改原对象添加功能
命令模式 把请求封装成对象 撤销/重做
外观模式 简化复杂接口 隐藏实现细节
中介者模式 多个对象通信用中间人 解耦多个组件
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐