Skip to content

工厂模式

简单工厂、工厂方法和抽象工厂都是设计模式中的创建型模式,它们主要用于解耦对象的创建过程,使得代码更加灵活和可维护。

简单工厂模式

简单工厂模式也称为静态工厂方法模式。它定义一个工厂类,这个类可以根据传入的参数决定创建并返回哪一种产品对象。这种模式简化了客户端的代码,因为客户端不需要知道具体产品的类名,只需要知道所要产品的类型即可。

TIP

简单工厂让客户类和具体子类的实现解耦,客户类不再需要知道有哪些子类以及应当实例化哪个子类。因为客户类往往有多个,如果不使用简单工厂,所有的客户类都要知道所有子类的细节。而且一旦子类发生改变,例如增加子类,那么所有的客户类都要进行修改。

特点

  • 提供了一个统一的接口来创建一系列相关或相互依赖的对象,而无需向客户端暴露创建逻辑。
  • 不符合开闭原则,如果需要增加新的产品,需要修改工厂类的代码。

适用场景

  • 工厂类负责创建的对象较少,且客户端只关心所需产品而不关心创建细节。
  • 当产品种类相对固定,不会频繁变动时。
  • 在需要快速构建原型或者小规模应用时,作为临时解决方案,因为它简单且易于实现

存在的缺陷

  • 扩展性差:添加新产品时,需要修改工厂类的代码,违背了开闭原则。
  • 违反了单一职责原则:随着产品种类的增加,工厂类可能变得庞大且难以维护。
  • 不够灵活:不适用于产品等级结构复杂或多系列产品的创建场景。

体现的设计模式原则

  • 单一职责原则:工厂类专注于创建对象,与业务逻辑分离。
  • 迪米特法则(最少知识原则):客户端不需要知道具体产品的创建细节,只需与工厂类交互。

示例

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

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

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

// 简单工厂
class SimpleFactory {
    public static Product createProduct(String type) {
        if ("A".equals(type)) {
            return new ConcreteProductA();
        } else if ("B".equals(type)) {
            return new ConcreteProductB();
        }
        throw new IllegalArgumentException("Invalid type");
    }
}

public class SimpleFactoryDemo {
    public static void main(String[] args) {
        Product product = SimpleFactory.createProduct("A");
        product.show();
    }
}

工厂方法模式

工厂方法模式定义了一个用于创建对象的接口,但让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

特点:

  • 将对象的创建委托给子类,使得系统更易于扩展,符合开闭原则
  • 每个具体工厂类只负责一个具体产品类的实例化

适用场景:

  • 当一个类希望由它的子类来指定它所创建的对象时。
  • 一个类将创建对象的职责委托给多个帮助子类中的某一个,并且希望将哪一个帮助子类是代理者这一信息局部化。
java
// 抽象工厂
interface Factory {
    Product create();
}

// 具体工厂A
class ConcreteFactoryA implements Factory {
    @Override
    public Product create() {
        return new ConcreteProductA();
    }
}

// 具体工厂B
class ConcreteFactoryB implements Factory {
    @Override
    public Product create() {
        return new ConcreteProductB();
    }
}

public class FactoryMethodDemo {
    public static void main(String[] args) {
        Factory factory = new ConcreteFactoryA();
        Product product = factory.create();
        product.show();
    }
}

抽象工厂模式

抽象工厂模式提供一个接口,用于创建一系列或相关依赖对象的家族,而不需要指定它们具体的类。它强调的是为一系列相关或相互依赖的对象提供一个接口,而不是单一的产品对象。

特点:

  • 可以为一系列相关或相互依赖的对象提供一个高层接口,让客户端可以独立于这些对象的创建、组合和表示。
  • 支持产品族的创建,增加了系统的灵活性和可扩展性。

适用场景:

  • 当系统需要创建多个相关的对象,并且这些对象是成套出现时。
  • 当需要为产品对象提供多种不同的实现方案,并且客户端可以根据需要选择具体方案时。
java
// 新增产品接口
interface AnotherProduct {
    void display();
}

// 具体产品C(属于另一个产品族)
class ConcreteAnotherProductC implements AnotherProduct {
    @Override
    public void display() {
        System.out.println("ConcreteAnotherProductC");
    }
}

// 抽象工厂
interface AbstractFactory {
    Product createProduct();
    AnotherProduct createAnotherProduct();
}

// 具体抽象工厂
class ConcreteFactory1 implements AbstractFactory {
    @Override
    public Product createProduct() {
        return new ConcreteProductA();
    }

    @Override
    public AnotherProduct createAnotherProduct() {
        return new ConcreteAnotherProductC();
    }
}

public class AbstractFactoryDemo {
    public static void main(String[] args) {
        AbstractFactory factory = new ConcreteFactory1();
        Product product = factory.createProduct();
        product.show();
        AnotherProduct anotherProduct = factory.createAnotherProduct();
        anotherProduct.display();
    }
}

总结来说,简单工厂模式较为简单但不够灵活,适用于产品种类少且变化不大的情况;工厂方法模式通过引入子类增强了可扩展性;抽象工厂模式则更进一步,适合处理产品族,即多个相关联或相互依赖的产品系列的创建。

Released under the MIT License.