Java面试必备:工厂模式与抽象工厂模式的区别

Java面试题 - 工厂模式和抽象工厂模式有什么区别?

回答重点

工厂模式关注的是创建单一类型对象,定义一个抽象方法,由子类实现具体对象的实例化。

抽象工厂模式关注的是创建一族相关对象,提供一个接口来创建一组相关的或互相依赖的对象,而无需指定它们的具体类。


引言

在面向对象编程中,工厂模式和抽象工厂模式都是常用的创建型设计模式,它们都用于对象的创建,但有着不同的应用场景和实现方式。本文将详细探讨这两种模式的区别,并通过示例和流程图帮助理解。

工厂模式 (Factory Pattern)

工厂模式是一种创建对象的设计模式,它提供了一个创建对象的接口,但允许子类决定实例化哪一个类。工厂方法让类的实例化推迟到子类。

结构

«abstract»
Creator
+factoryMethod() : Product
+someOperation()
ConcreteCreatorA
+factoryMethod() : Product
ConcreteCreatorB
+factoryMethod() : Product
«interface»
Product
+doSomething()
ConcreteProductA
+doSomething()
ConcreteProductB
+doSomething()

示例代码

// 产品接口
interface Button {
    void render();
}

// 具体产品
class WindowsButton implements Button {
    public void render() {
        System.out.println("Rendering a Windows button");
    }
}

class HTMLButton implements Button {
    public void render() {
        System.out.println("Rendering an HTML button");
    }
}

// 创建者
abstract class Dialog {
    public abstract Button createButton();
    
    public void render() {
        Button button = createButton();
        button.render();
    }
}

// 具体创建者
class WindowsDialog extends Dialog {
    public Button createButton() {
        return new WindowsButton();
    }
}

class WebDialog extends Dialog {
    public Button createButton() {
        return new HTMLButton();
    }
}

适用场景

  • 当一个类不知道它需要创建哪个类的对象时
  • 当一个类希望由其子类来指定它所创建的对象时
  • 当类将创建对象的职责委托给多个帮助子类中的某一个时

抽象工厂模式 (Abstract Factory Pattern)

抽象工厂模式提供了一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

结构

«interface»
AbstractFactory
+createProductA() : AbstractProductA
+createProductB() : AbstractProductB
ConcreteFactory1
+createProductA() : AbstractProductA
+createProductB() : AbstractProductB
ConcreteFactory2
+createProductA() : AbstractProductA
+createProductB() : AbstractProductB
«interface»
AbstractProductA
«interface»
AbstractProductB
ProductA1
ProductA2
ProductB1
ProductB2

示例代码

// 抽象产品A
interface Checkbox {
    void paint();
}

// 具体产品A
class WindowsCheckbox implements Checkbox {
    public void paint() {
        System.out.println("Painting a Windows checkbox");
    }
}

class HTMLCheckbox implements Checkbox {
    public void paint() {
        System.out.println("Painting an HTML checkbox");
    }
}

// 抽象产品B
interface Button {
    void render();
}

// 具体产品B
class WindowsButton implements Button {
    public void render() {
        System.out.println("Rendering a Windows button");
    }
}

class HTMLButton implements Button {
    public void render() {
        System.out.println("Rendering an HTML button");
    }
}

// 抽象工厂
interface GUIFactory {
    Button createButton();
    Checkbox createCheckbox();
}

// 具体工厂1
class WindowsFactory implements GUIFactory {
    public Button createButton() {
        return new WindowsButton();
    }
    
    public Checkbox createCheckbox() {
        return new WindowsCheckbox();
    }
}

// 具体工厂2
class HTMLFactory implements GUIFactory {
    public Button createButton() {
        return new HTMLButton();
    }
    
    public Checkbox createCheckbox() {
        return new HTMLCheckbox();
    }
}

适用场景

  • 系统需要独立于其产品的创建、组合和表示时
  • 系统需要配置多个产品族中的一个时
  • 需要提供一个产品类库,且只想显示它们的接口而不是实现时

主要区别

工厂模式
抽象工厂模式
工厂模式
抽象工厂模式
工厂模式
抽象工厂模式
设计模式比较
抽象级别
产品数量
扩展方式
创建单一产品
创建产品族
一个方法创建一个产品
多个方法创建多个相关产品
通过添加新的工厂子类扩展
需要修改接口和所有实现类
  1. 抽象级别

    • 工厂模式:关注单个产品的创建
    • 抽象工厂模式:关注相关产品族的创建
  2. 方法数量

    • 工厂模式:一个工厂方法
    • 抽象工厂模式:多个工厂方法(每个产品一个)
  3. 扩展性

    • 工厂模式:添加新产品类型容易(只需添加新的工厂子类)
    • 抽象工厂模式:添加新产品族容易,但添加新产品类型困难(需要修改接口和所有实现类)
  4. 复杂度

    • 工厂模式:相对简单
    • 抽象工厂模式:更复杂,涉及多个产品和工厂

何时使用哪种模式

单一产品
多个相关产品
需要创建对象
需要创建的产品数量?
考虑工厂模式
考虑抽象工厂模式
系统未来可能需要扩展?
工厂模式更合适
简单工厂可能足够
产品族需要保持一致?
抽象工厂模式
可能需要多个工厂模式
  • 使用工厂模式

    • 当系统需要独立于其对象的创建、组合和表示时
    • 当系统需要配置多个子类中的一个,并且每个子类都需要管理自己的对象创建时
    • 当需要提供灵活性,以便将来可以轻松添加新产品类型时
  • 使用抽象工厂模式

    • 当系统需要独立于其产品的创建、组合和表示时
    • 当系统需要配置多个产品族中的一个时
    • 当需要强调一系列相关产品对象的设计以便进行联合使用时
    • 当需要提供一个产品类库,且只想显示它们的接口而不是实现时

结论

工厂模式和抽象工厂模式都是创建型设计模式,但它们的应用场景和抽象级别不同。工厂模式关注单个产品的创建,而抽象工厂模式关注相关产品族的创建。选择哪种模式取决于你的具体需求:如果需要创建单一产品,工厂模式可能更合适;如果需要创建一组相关的产品,抽象工厂模式可能是更好的选择。

理解这两种模式的区别有助于你在设计系统时做出更明智的决策,创建更灵活、更可维护的代码结构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值