浅学【Java】设计模式
本文最后更新于244 天前,其中的信息可能已经过时,如有错误请发送邮件到2067863254@qq.com

我们用一种“人间清醒”的方式来聊聊Java设计模式。你会发现,它们不是高深莫测的理论,而是前辈程序员们总结出来的“最佳拍档秘籍”。

第一章:设计模式是啥?为啥要学?

想象一下,你要装修房子。 你不会每次装修都从“如何制造一颗钉子”开始吧?你会直接去宜家或者建材市场,选择现成的、设计好的​​家具模板​​,比如一个“比利”书柜或一个“马尔姆”床架。这些模板是经过无数家庭验证的,知道怎么设计最稳固、最实用、最美观。 ​​设计模式就是软件世界里的“家具模板”​​。 它们不是现成的代码库,而是一套​​被反复验证的、针对特定问题的优秀代码设计经验总结​​。 ​​为什么要学?​

  1. ​避免重复造轮子​​:遇到经典问题,直接用成熟方案,省时省力。
  2. ​代码更优雅、更易维护​​:用上设计模式的代码,就像用了宜家模块化家具的家,结构清晰,后期要换个“沙发”(修改功能)很容易,不会牵一发动全身。
  3. ​便于沟通​​:你只要说“这里我们用了个‘观察者模式’”,所有懂行的同事立刻就能明白你的设计意图,沟通成本极低。

第二章:三大派别,各有神通

设计模式经典著作《设计模式》中总结了23种模式,分为三大类,我们用公司部门来类比:

类型核心关注点好比公司里的…经典模式举例
​创建型模式​​解决“对象创建”的难题​​,让创建对象更灵活​HR招聘部门​​:负责用不同方式(校招、社招、猎头)“创建”员工对象单例、工厂、建造者
​结构型模式​​解决“类与对象组合”的难题​​,搭建清晰稳定的结构​架构部/行政部​​:设计部门架构(组合),提供统一接口(适配)适配器、装饰者、代理
​行为型模式​​解决“对象间通信”的难题​​,让对象各司其职又高效协作​工作流与沟通机制​​:如何分配任务(责任链),如何发布通知(观察者)观察者、策略、责任链

第三章:快速掌握几个最常用的模式

我们挑几个最实用、最能体现思想的模式来“尝尝鲜”。

模式一:单例模式 —— 皇帝的“独一无二”

​生活场景​​:一个国家只能有一个皇帝,一个公司只能有一个CEO。 ​​代码问题​​:有些对象,比如数据库连接池、配置文件管理器、日志工具,整个程序里只需要一个实例。搞出多个实例既浪费资源,又可能导致状态混乱。 ​​单例模式的做法​​:​​保证一个类只有一个实例,并提供一个全局访问点。​​ ​​Java代码(饿汉式,最简单的一种):​

public class Emperor {
    // 1. 私有静态实例,类加载时就创建好(所以叫“饿汉”)
    private static final Emperor instance = new Emperor();

    // 2. 私有构造方法,堵死外界用`new`创建实例的路!
    private Emperor() {
        System.out.println("我是唯一的皇帝!");
    }

    // 3. 公共的静态方法,供外界获取这个唯一实例
    public static Emperor getInstance() {
        return instance;
    }

    public void rule() {
        System.out.println("朕即天下!");
    }
}

// 使用方式
public class Kingdom {
    public static void main(String[] args) {
        // Emperor e = new Emperor(); // 错误!构造方法是私有的。

        // 正确方式:通过getInstance获取唯一实例
        Emperor emperor1 = Emperor.getInstance();
        Emperor emperor2 = Emperor.getInstance();

        emperor1.rule(); // 输出:朕即天下!

        // 验证是否是同一个对象
        System.out.println(emperor1 == emperor2); // 输出:true,是同一个对象!
    }
}

​核心思想​​:​​把构造器“关起来”(私有化),只留一个“门”(getInstance方法)获取唯一对象。​


模式二:工厂模式 —— 专业的“代工厂”

​生活场景​​:你想买一辆车。你不会自己去炼钢、造轮胎、组装,你会直接去“宝马4S店”或“奔驰4S店”告诉销售:“我要一辆SUV”。4S店会帮你把车造好、配置好,你直接提车就行。 ​​代码问题​​:在代码中,当你需要创建一个对象时,如果创建过程很复杂(比如依赖很多配置),或者你希望创建逻辑与使用逻辑分离(使用者不关心对象怎么来的),就可以用工厂模式。 ​​工厂模式的做法​​:​​定义一个创建对象的接口,但让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。​​ ​​Java代码:​

// 1. 产品接口:车
interface Car {
    void drive();
}

// 2. 具体产品:宝马和奔驰
class BMW implements Car {
    @Override
    public void drive() {
        System.out.println("开宝马...");
    }
}

class Benz implements Car {
    @Override
    public void drive() {
        System.out.println("开奔驰...");
    }
}

// 3. 核心:工厂接口
interface CarFactory {
    Car createCar(); // 工厂的核心职责:造车
}

// 4. 具体工厂:宝马工厂和奔驰工厂
class BMWFactory implements CarFactory {
    @Override
    public Car createCar() {
        // 这里可能有很多复杂的制造逻辑
        return new BMW();
    }
}

class BenzFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new Benz();
    }
}

// 使用方式:客户买车
public class Customer {
    public static void main(String[] args) {
        // 要去宝马4S店
        CarFactory factory = new BMWFactory();
        Car myCar = factory.createCar(); // 告诉4S店:给我造一辆
        myCar.drive(); // 输出:开宝马...

        // 换一家店
        factory = new BenzFactory();
        myCar = factory.createCar();
        myCar.drive(); // 输出:开奔驰...
    }
}

​核心思想​​:​​将“对象创建”这个动作抽象出来,与“对象使用”分离开。使用者只面对抽象接口(Car和CarFactory),不关心具体实现,非常符合“依赖倒置”原则,大大提升了代码的灵活性。​


模式三:观察者模式 —— 微信公众号的“订阅-通知”机制

​生活场景​​:你关注了一个微信公众号(成为观察者)。当公众号发布新文章时(被观察者状态改变),所有关注者都会收到推送通知。 ​​代码问题​​:当一个对象(目标对象)的状态发生改变时,如何自动通知所有依赖它的对象(观察者对象),并且这些对象之间是松耦合的? ​​观察者模式的做法​​:​​定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。​​ ​​Java代码(Java自身就提供了java.util.Observer接口,但我们这里手写一个更直观):​

import java.util.ArrayList;
import java.util.List;

// 1. 被观察者/主题 (Subject) - 好比微信公众号平台
class WeChatOfficialAccount {
    private String name;
    private String latestArticle; // 状态:最新文章
    private List<Follower> followers = new ArrayList<>(); // 维护所有观察者

    public WeChatOfficialAccount(String name) {
        this.name = name;
    }

    // 核心方法:发布新文章
    public void publishArticle(String articleTitle) {
        this.latestArticle = articleTitle;
        System.out.println(name + " 发布了新文章:《" + articleTitle + "》");
        notifyAllFollowers(); // 状态改变,通知所有观察者!
    }

    // 供观察者订阅和取消订阅
    public void addFollower(Follower follower) {
        followers.add(follower);
    }
    public void removeFollower(Follower follower) {
        followers.remove(follower);
    }

    // 通知所有的观察者
    private void notifyAllFollowers() {
        for (Follower follower : followers) {
            follower.update(this.name, this.latestArticle); // 调用观察者的更新方法
        }
    }
}

// 2. 观察者接口 (Observer) - 定义粉丝应有的行为
interface Follower {
    void update(String accountName, String articleTitle); // 收到通知后更新自己
}

// 3. 具体观察者 (ConcreteObserver) - 真实的粉丝
class User implements Follower {
    private String userName;

    public User(String userName) {
        this.userName = userName;
    }

    @Override
    public void update(String accountName, String articleTitle) {
        // 每个粉丝收到通知后的反应
        System.out.println("【" + userName + "】收到通知:公众号【" + accountName + "】有新文章《" + articleTitle + "》可阅读!");
    }
}

// 使用方式
public class WeChatWorld {
    public static void main(String[] args) {
        // 创建公众号(被观察者)
        WeChatOfficialAccount account = new WeChatOfficialAccount("全栈编程宝典");

        // 创建用户(观察者)
        User userA = new User("小明");
        User userB = new User("小红");

        // 用户关注公众号
        account.addFollower(userA);
        account.addFollower(userB);

        // 公众号发布文章 -> 自动通知所有关注者
        account.publishArticle("设计模式其实很简单");

        System.out.println("---------------");
        // 小红取关
        account.removeFollower(userB);
        // 再发布文章,只有小明能收到
        account.publishArticle("Java并发编程实战");
    }
}

​核心思想​​:​​解耦!被观察者只负责维护一个观察者列表并在状态改变时通知,它不关心观察者具体是谁、做了什么。观察者则负责在收到通知后采取行动。双方通过接口耦合,职责清晰。​


给你的学习路线图

  1. ​理解思想,而非背诵代码​​:永远记住每个模式要解决什么​​痛点​​。先问“为什么”,再看“怎么做”。
  2. ​从常用模式开始​​:
    • ​创建型​​:重点掌握 ​​单例(Singleton)​​、​​工厂方法(Factory Method)​​。
    • ​结构型​​:重点掌握 ​​适配器(Adapter)​​、​​装饰者(Decorator)​​。
    • ​行为型​​:重点掌握 ​​观察者(Observer)​​、​​策略(Strategy)​​。
  3. ​结合项目思考​​:在看代码或自己写代码时,有意识地想:“这里是不是可以用某个设计模式来优化?”
  4. ​不要过度设计​​!设计模式是“利器”,但不是“银弹”。如果业务逻辑很简单,直接new一个对象就完事了,非要用上工厂模式反而把简单问题复杂化。

总结

设计模式就是编程界的“孙子兵法”或“棋谱定式”,是前人智慧的结晶。你现在可能觉得有点抽象,这非常正常! ​​最好的学习方式就是:​

  1. ​看懂上面的例子​​。
  2. ​自己动手敲一遍​​。
  3. ​尝试在你自己的小项目中找一个地方用上去​​(比如,用单例模式管理你的配置类)。

当你真正用模式解决了一个实际问题后,你就会豁然开朗,真正理解它的妙处。加油!有任何问题随时再来问我。

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇