从简单到复杂:三种工厂模式的对比与应用

在软件设计中,创建型设计模式用于处理对象创建的复杂性。本文将对比三种常见的创建型设计模式:简单工厂模式、工厂方法模式和抽象工厂模式。

一,简单工厂模式


定义:简单工厂模式(Simple Factory Pattern)定义了一个工厂类,该类可以根据传入的参数决定创建哪一种产品实例。

结构

  • 产品(Product):定义产品的接口。
  • 具体产品(ConcreteProduct):实现具体产品。
  • 工厂(Factory):定义一个方法,根据参数创建具体产品实例。

优点

  • 简单易懂,适合小规模系统。
  • 客户端无需知道具体产品类,降低耦合度。

缺点

  • 工厂类集中了所有产品创建逻辑,违反单一职责原则。
  • 不易于扩展,一旦增加新产品,需要修改工厂类。

二,工厂方法模式


定义:工厂方法模式(Factory Method Pattern)定义了一个创建对象的接口,但由子类决定实例化哪一个类。这样,工厂方法将实例化操作推迟到子类。

结构

  • 抽象产品(Product):定义产品的接口。
  • 具体产品(ConcreteProduct):实现具体产品。
  • 抽象工厂(Creator):声明工厂方法,返回产品对象。
  • 具体工厂(ConcreteCreator):实现工厂方法,返回具体产品实例。

优点

  • 代码符合开闭原则,易于扩展。
  • 客户端无需知道具体产品类,降低耦合度。

缺点

  • 每增加一个产品,需要增加一个具体工厂,增加了系统复杂性。

三,抽象工厂模式


定义:抽象工厂模式(Abstract Factory Pattern)提供了一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。

结构

  • 抽象产品(AbstractProduct):定义产品的接口。
  • 具体产品(ConcreteProduct):实现具体产品。
  • 抽象工厂(AbstractFactory):声明创建一系列产品的方法。
  • 具体工厂(ConcreteFactory):实现创建具体产品的系列方法。

优点

  • 保持产品族的一致性,确保相关产品一起使用。
  • 符合开闭原则,易于扩展。

缺点

  • 增加了系统的复杂性,尤其是当产品族和产品等级结构增加时。
  • 扩展产品族较为困难,需要修改抽象工厂接口。

四,示例代码对比


简单工厂模式

// 产品接口
interface Product {
    void use();
}

// 具体产品A
class ConcreteProductA implements Product {
    public void use() {
        System.out.println("Using Product A");
    }
}

// 具体产品B
class ConcreteProductB implements Product {
    public void use() {
        System.out.println("Using Product B");
    }
}

// 简单工厂类
class SimpleFactory {
    public static Product createProduct(String type) {
        switch (type) {
            case "A":
                return new ConcreteProductA();
            case "B":
                return new ConcreteProductB();
            default:
                throw new IllegalArgumentException("Unknown product type");
        }
    }
}

// 客户端代码
public class SimpleFactoryDemo {
    public static void main(String[] args) {
        Product productA = SimpleFactory.createProduct("A");
        productA.use();

        Product productB = SimpleFactory.createProduct("B");
        productB.use();
    }
}

工厂方法模式

// 产品接口
interface Product {
    void use();
}

// 具体产品A
class ConcreteProductA implements Product {
    public void use() {
        System.out.println("Using Product A");
    }
}

// 具体产品B
class ConcreteProductB implements Product {
    public void use() {
        System.out.println("Using Product B");
    }
}

// 抽象工厂
abstract class Factory {
    public abstract Product createProduct();
}

// 具体工厂A
class ConcreteFactoryA extends Factory {
    public Product createProduct() {
        return new ConcreteProductA();
    }
}

// 具体工厂B
class ConcreteFactoryB extends Factory {
    public Product createProduct() {
        return new ConcreteProductB();
    }
}

// 客户端代码
public class FactoryMethodDemo {
    public static void main(String[] args) {
        Factory factoryA = new ConcreteFactoryA();
        Product productA = factoryA.createProduct();
        productA.use();

        Factory factoryB = new ConcreteFactoryB();
        Product productB = factoryB.createProduct();
        productB.use();
    }
}

抽象工厂模式

// 产品接口
interface ProductA {
    void use();
}

interface ProductB {
    void use();
}

// 具体产品A1
class ConcreteProductA1 implements ProductA {
    public void use() {
        System.out.println("Using Product A1");
    }
}

// 具体产品A2
class ConcreteProductA2 implements ProductA {
    public void use() {
        System.out.println("Using Product A2");
    }
}

// 具体产品B1
class ConcreteProductB1 implements ProductB {
    public void use() {
        System.out.println("Using Product B1");
    }
}

// 具体产品B2
class ConcreteProductB2 implements ProductB {
    public void use() {
        System.out.println("Using Product B2");
    }
}

// 抽象工厂
interface AbstractFactory {
    ProductA createProductA();
    ProductB createProductB();
}

// 具体工厂1
class ConcreteFactory1 implements AbstractFactory {
    public ProductA createProductA() {
        return new ConcreteProductA1();
    }

    public ProductB createProductB() {
        return new ConcreteProductB1();
    }
}

// 具体工厂2
class ConcreteFactory2 implements AbstractFactory {
    public ProductA createProductA() {
        return new ConcreteProductA2();
    }

    public ProductB createProductB() {
        return new ConcreteProductB2();
    }
}

// 客户端代码
public class AbstractFactoryDemo {
    public static void main(String[] args) {
        AbstractFactory factory1 = new ConcreteFactory1();
        ProductA productA1 = factory1.createProductA();
        ProductB productB1 = factory1.createProductB();
        productA1.use();
        productB1.use();

        AbstractFactory factory2 = new ConcreteFactory2();
        ProductA productA2 = factory2.createProductA();
        ProductB productB2 = factory2.createProductB();
        productA2.use();
        productB2.use();
    }
}

五,对比总结


复杂度

  • 简单工厂模式最简单,适用于小规模系统。
  • 工厂方法模式适中,适用于需要扩展单一产品的系统。
  • 抽象工厂模式最复杂,适用于需要创建一系列相关产品的系统。

扩展性

  • 简单工厂模式扩展性最差,需要修改工厂类。
  • 工厂方法模式扩展单一产品较为容易。
  • 抽象工厂模式扩展产品族较为容易,但扩展单一产品较为复杂。

使用场景

  • 简单工厂模式适用于产品种类较少且变化不频繁的场景。
  • 工厂方法模式适用于需要创建单一产品且产品种类不多的场景。
  • 抽象工厂模式适用于需要创建一系列相关产品的场景,确保产品族的一致性。

如果你对设计模式、软件架构、编程技巧等内容感兴趣,欢迎关注我们的同名微信公众号【技术拾光者】。在这里,我们将定期分享最新的技术文章和实用的编程技巧,帮助你不断提升自己的技术水平。

扫描下方二维码,立即关注我们吧!
技术拾光者

感谢你的阅读和支持,我们期待与你在微信公众号上交流更多有趣的技术话题!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术拾光者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值