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

相关推荐
颜淡慕潇24 分钟前
【K8S问题系列 |19 】如何解决 Pod 无法挂载 PVC问题
后端·云原生·容器·kubernetes
向前看-8 小时前
验证码机制
前端·后端
超爱吃士力架9 小时前
邀请逻辑
java·linux·后端
AskHarries11 小时前
Spring Cloud OpenFeign快速入门demo
spring boot·后端
isolusion12 小时前
Springboot的创建方式
java·spring boot·后端
zjw_rp13 小时前
Spring-AOP
java·后端·spring·spring-aop
TodoCoder13 小时前
【编程思想】CopyOnWrite是如何解决高并发场景中的读写瓶颈?
java·后端·面试
凌虚14 小时前
Kubernetes APF(API 优先级和公平调度)简介
后端·程序员·kubernetes
机器之心14 小时前
图学习新突破:一个统一框架连接空域和频域
人工智能·后端
.生产的驴15 小时前
SpringBoot 对接第三方登录 手机号登录 手机号验证 微信小程序登录 结合Redis SaToken
java·spring boot·redis·后端·缓存·微信小程序·maven