破解代码:深入解析Java工厂模式

面试室里的工厂模式:小A的答题现场

面试那天,小A坐在面试官对面,手心冒了一点汗。

面试官一脸淡定地问:"小A,你对工厂模式熟悉吗?能聊聊它的用法和优缺点吗?"

小A心想:终于来了!这是我复习过的内容!他调整了下呼吸,露出一个自信的微笑:"当然,工厂模式可是我写代码的时候经常用到的设计模式之一。要不,我就从简单工厂开始聊起?"


开场:什么是工厂模式?

小A拿起桌上的笔,随手画了几个圈:"我们用个简单的比喻,工厂模式就像现实中的商品工厂。工厂根据订单的需求生产不同的产品。比如说,你下单要一杯咖啡,我就送你拿铁;你说要奶茶,OK,我立刻送你一杯珍珠奶茶。客户并不需要关心这杯饮料是怎么做出来的,只要知道下单就能拿到它。"

他继续解释:"在程序中,工厂模式的作用和这个例子一样,就是把对象创建的复杂过程隐藏起来,只暴露出一个简单的接口。这样,用户用起来更轻松,代码也更灵活。"


第一步:简单工厂模式

小A接着说:"举个简单工厂的例子吧!比如说我有个SimpleFactory类,专门用来生成饮料。"

他用笔写下了一段代码:

typescript 复制代码
// 饮料接口
interface Drink {
    void serve();
}

// 具体产品
class Coffee implements Drink {
    public void serve() {
        System.out.println("Here is your Coffee!");
    }
}

class Tea implements Drink {
    public void serve() {
        System.out.println("Here is your Tea!");
    }
}

// 简单工厂
class SimpleFactory {
    public static Drink createDrink(String type) {
        if (type.equalsIgnoreCase("coffee")) {
            return new Coffee();
        } else if (type.equalsIgnoreCase("tea")) {
            return new Tea();
        } else {
            throw new IllegalArgumentException("Unknown drink type!");
        }
    }
}
​

"在这个工厂里,SimpleFactory负责创建不同的饮料,而客户代码只需要调用它的createDrink方法,完全不用关心饮料是怎么生成的。"


第二步:工厂方法模式

面试官点了点头,小A知道要升级难度了。他擦了擦手心,说:"不过呢,简单工厂有个小问题。如果我想增加一种新的饮料,比如说奶昔,就得修改SimpleFactory类。这违背了开闭原则,对扩展开放、对修改关闭。"

小A继续说:"所以我们有了工厂方法模式,每个产品都对应一个工厂。比如现在我要生产奶昔和果汁,我可以这样设计:"

csharp 复制代码
// 工厂接口
interface DrinkFactory {
    Drink createDrink();
}

// 具体工厂
class CoffeeFactory implements DrinkFactory {
    public Drink createDrink() {
        return new Coffee();
    }
}

class TeaFactory implements DrinkFactory {
    public Drink createDrink() {
        return new Tea();
    }
}
​

他补充道:"这样一来,每次增加新的饮料,只需要新建一个工厂类,而不用修改原有的代码结构。"


第三步:真实场景------支付系统

小A看了看面试官的表情,发现他还挺有兴趣,于是决定再深入一点:"工厂模式不仅仅是一个教学例子,实际上它在很多场景下都很实用。我就用支付系统来举个例子吧!"

"假设我们有不同的支付方式:支付宝支付、微信支付。用户只需要选择支付方式,不需要关心支付的内部逻辑。用工厂模式实现起来就很简单:"

typescript 复制代码
// 支付接口
interface Payment {
    void pay(double amount);
}

// 具体支付方式
class Alipay implements Payment {
    public void pay(double amount) {
        System.out.println("Paid " + amount + " using Alipay.");
    }
}

class WeChatPay implements Payment {
    public void pay(double amount) {
        System.out.println("Paid " + amount + " using WeChat Pay.");
    }
}

// 工厂
class PaymentFactory {
    public static Payment createPayment(String type) {
        if ("Alipay".equalsIgnoreCase(type)) {
            return new Alipay();
        } else if ("WeChatPay".equalsIgnoreCase(type)) {
            return new WeChatPay();
        }
        throw new IllegalArgumentException("Unsupported payment type!");
    }
}
​

"现在,当我调用PaymentFactory.createPayment("Alipay")时,就能生成一个支付宝支付对象,去完成支付操作了。"


第四步:优缺点

"工厂模式虽然好用,但也不是万能的,"小A诚恳地补充,"它有它的优点和缺点。"

  • 优点:

    1. **解耦代码:**客户端和具体类的实现分离,方便扩展。
    2. **灵活性:**增加新产品时,只需新增工厂类,符合开闭原则。
    3. **复用性:**工厂模式集中管理对象创建逻辑,减少冗余代码。
  • 缺点:

    1. **增加复杂度:**每新增一个产品,就需要新增一个工厂类。
    2. **不适合简单场景:**如果对象创建逻辑很简单,用工厂模式反而显得臃肿。

总结:设计模式的本质

小A最后说道:"工厂模式的本质,是一种面向接口编程的思想。我们通过抽象接口,隔离了对象的实现细节,同时增强了代码的可扩展性。"

"不过,设计模式是工具,而不是束缚。使用工厂模式时,要根据实际需求权衡它的适用性。最重要的,是写出既优雅又符合业务需求的代码。"


面试官微微一笑:"不错,小A。接下来的问题,我们聊聊单例模式吧。"

小A心里松了一口气:看来这一关稳了!

相关推荐
明月_清风2 小时前
Muse 登顶 App Store 第一,SDK 直接开源:AI Agent 开始进入下一个阶段
人工智能·后端
hsfxuebao4 小时前
Loop Engineering 保姆级教程 + 项目实战
人工智能·后端
打工仔折腾 AI5 小时前
从 Demo 到生产级 Agent:8 个关键设计机制与 Python 实现拆解
java·jvm·人工智能·后端·python·langchain·ai agent 实战
架构技术专栏5 小时前
交叉熵:AI 怎样给概率预测打分
后端
IT_陈寒7 小时前
SpringBoot自动配置坑了我一把,原来是这样绕过去的
前端·人工智能·后端
要努力啊4697 小时前
用 Codex 加速 Java 开发:从代码生成到测试覆盖的完整实战
后端
dora7 小时前
LangChain4j 新手入门实战教程(Java版)
后端·langchain·agent
蜗牛互联网7 小时前
MongoDB Atlas Agent Engine之后,如何用版本门禁防止陈旧写入
java·数据库·人工智能·后端·mongodb
付威20237 小时前
Rust 生命周期:为什么要有它,实际代码里到底怎么用?
后端
海岳云舟7 小时前
spring使用kafka的三种方式(listener、container、stream)
后端