Skip to content

简单工厂模式

引言

在面向对象编程中,简单工厂模式(Simple Factory Pattern) 是一种常用的设计模式,用于封装对象的创建逻辑。它通过一个独立的工厂类来负责创建对象,从而解耦调用者与具体类之间的依赖关系。

诞生背景

简单工厂模式的出现源于软件开发中对“高内聚、低耦合”原则的追求。随着系统复杂度增加,直接使用 new 创建对象会导致代码难以维护和扩展。因此,引入工厂类来集中管理对象的创建,简化客户端代码。

演进过程

  • 直接实例化:早期代码中直接使用 new ClassName() 创建对象。
  • 引入简单工厂:将创建逻辑封装在工厂类中,通过工厂类创建对象。
  • 工厂方法引入:为了提高可维护性,开始使用静态方法封装对象创建逻辑。
  • 抽象工厂模式:随着需求变化,进一步演进为支持多种产品族的抽象工厂模式。

核心概念

  • 工厂类(Factory):负责创建具体产品对象。
  • 抽象产品类(Product):定义产品的公共接口。
  • 具体产品类(ConcreteProduct):实现产品接口的具体类。

通用实现

java实现

java
// 抽象产品类
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) {
        if ("A".equals(type)) {
            return new ConcreteProductA();
        } else if ("B".equals(type)) {
            return new ConcreteProductB();
        }
        return null;
    }
}

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

php实现

php
// 抽象产品类
interface Product {
    public function use();
}

// 具体产品类 A
class ConcreteProductA implements Product {
    public function use() {
        echo "Using Product A\n";
    }
}

// 具体产品类 B
class ConcreteProductB implements Product {
    public function use() {
        echo "Using Product B\n";
    }
}

// 工厂类
class SimpleFactory {
    public static function createProduct($type) {
        if ($type === "A") {
            return new ConcreteProductA();
        } else if ($type === "B") {
            return new ConcreteProductB();
        }
        return null;
    }
}

// 客户端代码
class Client {
    public static function main() {
        $product = SimpleFactory::createProduct("A");
        if ($product !== null) {
            $product->use();
        }
    }
}

Client::main();

应用场景

  • 当一个类不知道它所必须创建的对象的类时。
  • 当一个类希望由子类来决定所创建的对象时。
  • 当客户端只需要知道传入工厂类的参数即可创建对象时。

案例

在支付系统中,根据不同支付方式(支付宝、微信、银联)创建不同的支付策略对象,使用简单工厂模式可以统一管理支付方式的创建逻辑。

优点

  • 解耦:客户端无需关心对象的创建细节,只需传递参数。
  • 统一管理:对象创建逻辑集中在一个类中,便于维护。
  • 易于扩展:新增产品只需修改工厂类,符合开闭原则(部分)。

缺点

  • 违反开闭原则:每次新增产品类型都需要修改工厂类逻辑。
  • 职责过重:工厂类承担了过多创建逻辑,易造成类膨胀。
  • 可读性差:随着产品种类增多,if-elseswitch-case 逻辑复杂。

扩展

  • 结合配置文件:通过读取配置文件决定创建哪个产品,避免硬编码。
  • 使用反射机制:通过类名动态创建对象,提升灵活性。
  • 升级为工厂方法模式:将创建逻辑延迟到子类,提高可扩展性。

模式协作

简单工厂模式通常与以下模式协作:

  • 工厂方法模式:作为其简化版本。
  • 策略模式:工厂用于创建不同的策略对象。
  • 适配器模式:工厂用于创建不同类型的适配器。

延伸思考

  1. 是否应该将工厂类设计为单例?
  • 是的,工厂类通常无状态,适合使用单例模式。
  1. 是否支持泛型?
  • 可以通过泛型实现更通用的工厂类。
  1. 如何处理异常情况?
  • 应对未知类型进行异常处理,避免返回 null

总结

简单工厂模式是一种实用的设计模式,适用于对象创建逻辑较为简单的场景。它通过引入工厂类实现解耦和集中管理,但也有一定的局限性。在实际开发中,可以根据需求选择是否升级为更复杂的工厂方法模式或抽象工厂模式。