设计模式 - 简单工厂模式

目录

一、基本概念

二、组成部分

三、举例说明

3.1 定义产品接口

 3.2 定义具体产品类

3.3 定义工厂类

3.4 客户端代码

四、优缺点

4.1 优点

4.2 缺点

五、总结

5.1 适用场景

5.2 不适用场景

5.3 替代模式


简单工厂模式(Simple Factory Pattern)虽然不是 GoF 设计模式的一部分,但在实际开发中非常常见。简单工厂模式主要用于创建对象,它提供了一个静态方法来创建对象,而不是使用构造函数或工厂方法。简单工厂模式的主要目的是隐藏对象创建的细节,使客户端代码不必关心具体的创建逻辑。

一、基本概念

简单工厂模式的核心思想是定义一个工厂类,这个工厂类负责创建各种不同的产品对象。客户端通过调用工厂类的一个静态方法来获取所需的产品对象,而不需要知道产品的具体创建细节。

二、组成部分

  1. 工厂类(Factory):负责创建产品对象。
  2. 产品接口或抽象类(Product):定义了产品对象应该实现的方法。
  3. 具体产品类(Concrete Products):实现了产品接口或继承自抽象类,代表具体的对象。

三、举例说明

假设我们需要创建不同类型的披萨(Pizza),并且我们希望有一个工厂类来负责创建这些披萨。

3.1 定义产品接口

public interface Pizza {
    void prepare();
    void bake();
    void cut();
    void box();
}

 3.2 定义具体产品类

public class CheesePizza implements Pizza {
    @Override
    public void prepare() {
        System.out.println("Preparing Cheese Pizza");
    }

    @Override
    public void bake() {
        System.out.println("Baking Cheese Pizza");
    }

    @Override
    public void cut() {
        System.out.println("Cutting Cheese Pizza");
    }

    @Override
    public void box() {
        System.out.println("Boxing Cheese Pizza");
    }
}

public class PepperoniPizza implements Pizza {
    @Override
    public void prepare() {
        System.out.println("Preparing Pepperoni Pizza");
    }

    @Override
    public void bake() {
        System.out.println("Baking Pepperoni Pizza");
    }

    @Override
    public void cut() {
        System.out.println("Cutting Pepperoni Pizza");
    }

    @Override
    public void box() {
        System.out.println("Boxing Pepperoni Pizza");
    }
}

3.3 定义工厂类

public class SimplePizzaFactory {
    public Pizza createPizza(String type) {
        Pizza pizza = null;
        switch (type.toLowerCase()) {
            case "cheese":
                pizza = new CheesePizza();
                break;
            case "pepperoni":
                pizza = new PepperoniPizza();
                break;
            default:
                throw new IllegalArgumentException("Unknown pizza type: " + type);
        }
        return pizza;
    }
}

3.4 客户端代码

public class Client {
    public static void main(String[] args) {
        SimplePizzaFactory factory = new SimplePizzaFactory();
        Pizza cheesePizza = factory.createPizza("cheese");
        cheesePizza.prepare();
        cheesePizza.bake();
        cheesePizza.cut();
        cheesePizza.box();

        Pizza pepperoniPizza = factory.createPizza("pepperoni");
        pepperoniPizza.prepare();
        pepperoniPizza.bake();
        pepperoniPizza.cut();
        pepperoniPizza.box();
    }
}

 

四、优缺点

4.1 优点

  1. 封装性好:客户端不需要关心产品的创建细节,只需要知道如何使用产品。
  2. 易于扩展:当需要增加新的产品时,只需要修改工厂类,而不需要修改客户端代码。
  3. 符合开闭原则:对扩展开放,对修改关闭。

4.2 缺点

  1. 违反开闭原则:当需要增加新产品时,工厂类的代码需要修改。
  2. 类的静态方法不易扩展:如果工厂类变得庞大,难以维护。
  3. 单个工厂类包含太多逻辑:可能导致工厂类过于复杂。

五、总结

简单工厂模式通过将对象的创建逻辑封装在一个静态工厂方法中,简化了客户端代码。然而,随着产品的增加,工厂类可能会变得庞大,难以管理和维护。此外,当需要添加新的产品时,需要修改工厂类,这违反了开闭原则。

在实际应用中,可以根据项目的具体需求选择是否使用简单工厂模式。如果产品的类型相对固定,并且未来扩展的可能性较小,那么简单工厂模式是一个不错的选择。如果产品类型可能会频繁变动,那么可以考虑使用其他的创建型模式,如工厂方法模式或抽象工厂模式。

5.1 适用场景

  1. 产品种类有限

    如果产品种类相对较少且稳定,未来扩展的可能性不大,那么可以使用简单工厂模式。这样可以避免工厂类变得过于庞大。
  2. 静态方法适合场景

    如果创建的产品对象不需要复杂的创建逻辑,并且创建过程可以很好地封装在一个静态方法中,那么简单工厂模式是一个合适的选择。
  3. 减少客户端代码复杂性

    如果客户端代码需要频繁地创建产品对象,并且这些对象的创建过程需要一定的逻辑处理,那么简单工厂模式可以帮助隐藏这些逻辑,简化客户端代码。
  4. 中央控制点

    如果希望有一个中央控制点来统一管理所有产品的创建,那么简单工厂模式可以提供这样的功能。

5.2 不适用场景

  1. 产品种类经常变动

    如果产品种类在未来可能会频繁增加或删除,那么使用简单工厂模式会导致工厂类频繁修改,不利于维护。此时更适合使用工厂方法模式或抽象工厂模式。
  2. 工厂类过于庞大

    如果工厂类已经包含了大量的产品创建逻辑,那么继续在同一个类中增加更多的产品可能会导致类过于复杂,难以理解和维护。此时应该考虑重构工厂类或使用其他模式。
  3. 需要支持子类扩展

    如果希望子类能够扩展或覆盖产品的创建逻辑,那么简单工厂模式可能不是一个好的选择,因为它的静态方法不容易被继承或覆盖。这时可以考虑使用工厂方法模式。

5.3 替代模式

  1. 工厂方法模式

    如果需要支持子类扩展产品的创建逻辑,或者产品种类可能会增加,那么工厂方法模式是一个更好的选择。它允许子类通过继承来扩展产品的创建逻辑。
  2. 抽象工厂模式

    如果需要创建一系列相关的产品族,并且这些产品族之间存在依赖关系,那么抽象工厂模式更为合适。它可以创建一组相关的产品对象,而不需要指定它们的具体类。
  3. 建造者模式

    如果产品的创建过程非常复杂,涉及到多个步骤,并且这些步骤可能会发生变化,那么建造者模式可以更好地应对这种情况。
### 抽象工厂模式概述 抽象工厂模式是一种创建型设计模式,其核心在于提供了一种方式来创建一系列相关或相互依赖的对象,而不必指定它们的具体类[^2]。通过这种方式,客户端能够使用统一的接口来获取所需的产品实例,从而降低了系统组件之间的耦合度。 #### 模式的结构与工作原理 该模式主要由四个部分组成: - **抽象工厂(Abstract Factory)**:定义了一个用于创建一族具体产品对象的方法集合。 - **具体工厂(Concrete Factory)**:实现了抽象工厂所声明的操作,负责生产特定种类的产品系列。 - **抽象产品(Abstract Product)**:为每一种可能被生产的物品设定了通用接口。 - **具体产品(Concrete Product)**:实际要创建出来的实体类,继承自相应的抽象产品并实现其功能。 当客户请求某个类型的对象时,会调用相应工厂里的方法得到想要的结果;由于整个过程中只涉及到高层模块对于低层模块的引用(即仅知道如何操作抽象级别的成员),因此即使内部逻辑发生变化也不会影响到外部使用者。 #### 应用场景分析 此模式非常适合应用于以下情况: - 当应用程序存在多个可互换的产品线,并希望保持独立性以便于扩展新特性时不破坏现有代码; - 需要在运行期间动态决定应该采用哪一套设计方案来进行构建; - 要求确保同一版本下的各个组成部分始终一致地协同运作。 例如,在图形库中可以根据不同的渲染引擎选择合适的形状绘制器(如OpenGL vs DirectX)。再比如操作系统风格切换工具里根据不同主题调整窗口控件外观等都是很好的例子。 #### Java实现案例展示 下面给出一段简单的Java代码片段用来说明上述概念的应用: ```java // 定义两个层次的产品接口 public interface GUIFactory { Button createButton(); } public interface Button { void paint(); } ``` 接着分别针对Windows和MacOS平台定制化各自的GUI元素: ```java // Windows风格按钮 class WinButton implements Button { public void paint() { System.out.println("Render a button in the Windows style."); } } // MacOS风格按钮 class MacButton implements Button { public void paint() { System.out.println("Render a button in the macOS style."); } } ``` 最后建立对应的工厂类完成最终组装: ```java // 创建适用于Windows系统的UI部件制造者 class WinFactory implements GUIFactory { @Override public Button createButton() { return new WinButton(); } } // 创建适用于macOS系统的UI部件制造者 class MacFactory implements GUIFactory { @Override public Button createButton() { return new MacButton(); } } ``` 这样就可以很容易地根据当前环境配置选取适当的主题样式了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

何苏三月

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

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

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

打赏作者

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

抵扣说明:

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

余额充值