找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

975

积分

0

好友

139

主题
发表于 前天 16:04 | 查看: 4| 回复: 0

在编程的世界里,掌握扎实的算法与数据结构功底固然重要,但构建灵活、可维护的软件系统,则更依赖于精妙的软件设计思想,即设计模式。为了帮助初学者更好地理解和记忆,我们不妨用一种有趣的视角——武侠江湖,来解读几种经典的设计模式。

单例模式:天下只此一人的掌门绝学

单例模式的核心是确保一个类只有一个实例,并提供一个全局访问点。这好比一个武林大派,天下只能有一位掌门,号令一出,莫敢不从。

其实现的关键在于将构造函数私有化,防止外部随意创建,并通过一个静态方法提供唯一的实例访问。

public class 明教教主 {
    private static 明教教主 唯一教主;

    private 明教教主() { // 构造函数私有,如同闭关,外人不得擅入
    }

    public static 明教教主 获取教主() {
        if (唯一教主 == null) {
            唯一教主 = new 明教教主(); // 开坛即位,创建唯一实例
        }
        return 唯一教主;
    }

    public void 号令天下() {
        System.out.println("圣火令出,莫敢不从!");
    }
}

但简单的实现(懒汉式)在多线程环境下可能产生多个“掌门”,造成混乱。因此,进阶的“双重检查锁定”版本应运而生,它在保证性能的同时确保了线程安全。

public static 明教教主 获取教主() {
    if (唯一教主 == null) {         // 第一重检查:快速探视
        synchronized(明教教主.class) { // 加锁,重兵把守
            if (唯一教主 == null) {    // 第二重检查:再次确认
                唯一教主 = new 明教教主();
            }
        }
    }
    return 唯一教主;
}

工厂模式:无招胜有招的剑法总纲

工厂模式的核心是定义一个创建对象的接口,但将具体创建哪个类实例的决定推迟到子类或一个独立的工厂类中。这如同令狐冲的独孤九剑,不拘泥于固定招式,针对不同敌人使出最合适的剑法。

首先,定义一个统一的“剑法”接口。

interface 剑法 {
    void 出招();
}

class 华山剑法 implements 剑法 {
    public void 出招() { System.out.println("苍松迎客!"); }
}

class 辟邪剑法 implements 剑法 {
    public void 出招() { System.out.println("流星飞堕!"); }
}

然后,创建一个“剑法工厂”,由它来负责根据需求打造具体的宝剑(实例)。

class 剑法工厂 {
    public static 剑法 打造宝剑(String 剑法名) {
        switch(剑法名) {
            case “华山“: return new 华山剑法();
            case “辟邪“: return new 辟邪剑法();
            default: throw new IllegalArgumentException(“无此剑法“);
        }
    }
}

使用者无需关心剑法是如何打造的,只需通过工厂获取并使用即可,实现了创建与使用的解耦。

剑法 我的剑 = 剑法工厂.打造宝剑(“华山“);
我的剑.出招(); // 输出:苍松迎客!

观察者模式:消息灵通的江湖情报网

观察者模式定义了对象间的一种一对多的依赖关系,当一个对象(被观察者)状态改变时,所有依赖于它的对象(观察者)都会得到通知并自动更新。这就像丐帮的情报系统,总舵一有消息,所有分舵立刻知晓。

首先定义观察者接口。

interface 江湖消息监听 {
    void 收到消息(String 消息);
}

实现具体的观察者,例如各个丐帮分舵。

class 丐帮分舵 implements 江湖消息监听 {
    private String 分舵名;
    public 丐帮分舵(String 分舵名) {
        this.分舵名 = 分舵名;
    }
    @Override
    public void 收到消息(String 消息) {
        System.out.println(分舵名 + “收到消息:“ + 消息);
    }
}

定义被观察者(消息中心),负责维护观察者列表并发送通知。

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

class 江湖消息中心 {
    private List<江湖消息监听> 所有分舵 = new ArrayList<>();

    public void 添加分舵(江湖消息监听 分舵) {
        所有分舵.add(分舵);
    }

    public void 发布消息(String 消息) {
        for(江湖消息监听 分舵 : 所有分舵) {
            分舵.收到消息(消息);
        }
    }
}

适配器模式:化解冲突的乾坤大挪移

适配器模式将一个类的接口转换成客户期望的另一个接口,使原本因接口不兼容而无法一起工作的类可以协同工作。这正如张无忌的乾坤大挪移,能将异种真气化为己用。

假设我们现有的系统使用的是“九阳神功”接口。

interface 九阳神功 {
    void 纯阳内力();
}

但新引入的一个模块(如西域武功)提供的是不兼容的“阴寒真气”。

class 西域内功 {
    public void 阴寒真气() {
        System.out.println(“寒冰绵掌!“);
    }
}

此时,创建一个适配器,让西域内功也能以九阳神功的方式运转。

class 乾坤大挪移适配器 implements 九阳神功 {
    private 西域内功 异种真气;

    public 乾坤大挪移适配器(西域内功 真气) {
        this.异种真气 = 真气;
    }

    @Override
    public void 纯阳内力() {
        // 适配过程:调用原有功能,并进行转化或包装
        异种真气.阴寒真气();
        System.out.println(“经乾坤大挪移,转化为至阳内力!“);
    }
}

策略模式:随心所欲的武功切换

策略模式定义了一系列算法,并将每一个算法封装起来,使它们可以相互替换。它让算法的变化独立于使用它的客户。这好比一位武林高手,可以根据对手不同,随时切换华山剑法、太极拳或六脉神剑。

定义统一的策略接口。

interface 攻击策略 {
    void 执行();
}

实现多种具体的策略(算法)。

class 华山剑法策略 implements 攻击策略 {
    @Override
    public void 执行() {
        System.out.println(“发动「有凤来仪」!“);
    }
}

class 太极拳策略 implements 攻击策略 {
    @Override
    public void 执行() {
        System.out.println(“发动「如封似闭」!“);
    }
}

定义上下文(Context),它持有一个策略对象,并能动态切换。

class 武林高手 {
    private 攻击策略 当前策略;

    public void 设置策略(攻击策略 策略) {
        this.当前策略 = 策略;
    }

    public void 发起攻击() {
        if (当前策略 != null) {
            当前策略.执行();
        }
    }
}

使用时,高手可以自由切换对敌策略。

武林高手 高手 = new 武林高手();
高手.设置策略(new 华山剑法策略());
高手.发起攻击(); // 输出:发动「有凤来仪」!

高手.设置策略(new 太极拳策略());
高手.发起攻击(); // 输出:发动「如封似闭」!

总结

通过以上武侠比喻,我们生动地阐述了单例、工厂、观察者、适配器和策略这五种常见设计模式的核心思想。理解设计模式,关键在于领悟其解决特定问题的“心法”,而非死记硬背“招式”。在实际的Java项目开发或任何面向对象编程中,识别出代码中存在的“坏味道”,并适时地运用合适的设计模式进行重构,才能逐步提升软件设计的功力,构建出更加健壮、灵活的系统。




上一篇:FastJSON序列化Joda Money引发支付中断:日志打印中的整型溢出问题与解决方案
下一篇:VS Code JS/TS Modernizer:AI驱动的老项目现代化与依赖升级工具
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-17 14:57 , Processed in 0.163938 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表