破解代码:深入解析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心里松了一口气:看来这一关稳了!

相关推荐
考虑考虑22 分钟前
docker compose环境变量替换
运维·后端·自动化运维
武雄(小星Ai)1 小时前
飞书API上传26MB文件偶发失败:错误码9499与空响应体排坑实录
后端·api·排坑实录
徐小夕1 小时前
JitWord 4.0 万字分享:从协同工具到AI Word操作系统,聊聊3年产品创业史
前端·vue.js·后端
geovindu3 小时前
CSharp: Observer Pattern
开发语言·后端·观察者模式·设计模式·c#·.netcore·行为模式
Flynt3 小时前
把公司项目迁到 Spring Boot 4.0:编译通过只是开始
java·spring boot·后端
IT_陈寒4 小时前
Redis误用keys命令把生产环境搞崩了,血的教训
前端·人工智能·后端
她的男孩4 小时前
多租户和数据权限怎么共存?扒完拦截器注册链路,我找到 4 个隐蔽的坑
java·后端·架构
用户8356290780514 小时前
使用 Python 设置 Excel 页眉和页脚
后端·python
步行cgn4 小时前
IoC 控制反转:从概念到 Spring 的实现
后端
爱勇宝4 小时前
没有 Fn 键关触控板?我做了一个双击即用的 Windows 小工具
前端·后端·程序员