设计模式学习之简单工厂

本文介绍了设计模式中的简单工厂模式,包括定义、示例代码及优缺点。简单工厂模式用于根据参数创建不同类的实例,实现代码解耦,但在产品种类增多时可能导致代码复杂度增加。文章通过披萨店的例子展示了简单工厂模式的应用,并指出在产品种类增多时可以考虑使用工厂方法模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

设计模式系列往期文章

  1. 设计模式学习之策略模式
  2. 设计模式学习之策略模式在前端的应用

前言 简单工厂不是一个标准的设计模式,但是非常简单又好用,在介绍工厂模式和抽象工厂模式前我们先介绍简单工厂。
在这里插入图片描述

1 定义

简单工厂模式(也叫静态工厂模式)是一种创建型设计模式,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类或接口。以下图为例举个例子:
在这里插入图片描述

  • API定义客户所需要的功能接口
  • Impl为API接口的具体实现类
  • Factory是简单工厂,通过选择合适的实现类来创建API接口对象
  • Client是客户端,通过Factory去获取API接口对象,然后面向API接口编程

使用接口,能够更好的封装隔离代码——只要接口不变,其内部实现的变化不会影响到Client的使用,从而使得系统更灵活,具有更好的扩展性和可维护性。

2 示例代码

2.1 示例1

以上面的类图为例,实现代码如下:

public interface Api {
    public void operation(String s);
}

public class ImplA implements Api{
    @Override
    public void operation(String s) {
        System.out.println("ImplA的实现代码" + s);
    }
}

public class ImplB implements Api{
    @Override
    public void operation(String s) {
        System.out.println("ImplB的实现代码" + s);
    }
}

// 简单工厂类,通过Factory创建对象,将客户端和具体实现隔离开。
public class Factory {
    public static Api createApi(int cond) {
        Api api = null;
        if (cond == 1) {
            api = new ImplA();
        } else {
            api = new ImplB();
        }
        return api;
    }
}

public class Client {
    public static void main(String[] args) {
        Api api = Factory.createApi(3);

        api.operation("task");
    }
}

2.2 示例2

以披萨店为例,一个披萨店可以制作各种口味的披萨,可以使用简单工厂模式定义一个静态方法orderPizza,该方法接收一个披萨类型参数,然后返回对应的披萨实例:

// 披萨接口,定义披萨的行为
public interface Pizza {
    void prepare(); // 准备
    void bake(); // 烘焙
    void cut(); // 切片
    void box(); // 打包
}

// 奶酪披萨类,实现披萨接口
public class CheesePizza implements Pizza {
    @Override
    public void prepare() {
        System.out.println("准备奶酪披萨的原料");
    }

    @Override
    public void bake() {
        System.out.println("烘焙奶酪披萨");
    }

    @Override
    public void cut() {
        System.out.println("切片奶酪披萨");
    }

    @Override
    public void box() {
        System.out.println("打包奶酪披萨");
    }
}

// 海鲜披萨类,实现披萨接口
public class SeafoodPizza implements Pizza {
    @Override
    public void prepare() {
        System.out.println("准备海鲜披萨的原料");
    }

    @Override
    public void bake() {
        System.out.println("烘焙海鲜披萨");
    }

    @Override
    public void cut() {
        System.out.println("切片海鲜披萨");
    }

    @Override
    public void box() {
        System.out.println("打包海鲜披萨");
    }
}

// 披萨店类,提供一个静态方法根据参数创建不同种类的披萨对象
public class PizzaStore {
    public static Pizza orderPizza(String type) {
        Pizza pizza = null;
        if (type.equals("cheese")) {
            pizza = new CheesePizza();
        } else if (type.equals("seafood")) {
            pizza = new SeafoodPizza();
        }
        // 如果有其他种类的披萨,就需要修改这个方法的逻辑,增加判断分支

        if (pizza != null) {
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
        }
        return pizza;
    }
}

// 测试类,调用披萨店的静态方法创建和使用披萨对象
public class Test {
    public static void main(String[] args) {
        Pizza cheesePizza = PizzaStore.orderPizza("cheese"); // 创建奶酪披萨对象
        Pizza seafoodPizza = PizzaStore.orderPizza("seafood"); // 创建海鲜披萨对象
        // 如果想要其他种类的披萨,就需要传入不同的参数,但是如果没有对应的产品类和判断逻辑,就会返回null
    }
}

3 总结

3.1 优点

  • 使用接口,将具体的实现封装了起来,做到了解耦
  • 通过引入工厂类,可在不修改任何客户端代码的情况下更换和增加新的具体产品类,提高了系统的灵活性。

3.2 缺点

  • 工厂类集中了所有产品创建逻辑,职责过重,一旦发生异常,整个系统将受影响。
  • 使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度。
  • 系统扩展困难,一旦增加新产品不得不修改工厂逻辑,在产品类型较多时,可能造成逻辑过于复杂。

3.3 适用场景

对于产品种类相对较少的情况,考虑使用简单工厂模式。使用简单工厂模式的客户端只需要传入工厂类的参数,不需要关心如何创建对象的逻辑,可以很方便地创建所需产品。

不过,随着产品种类的增多,工厂生产也需要对应的增加,工厂内部的代码就需要不断的调整,那么就会违反SOLID原则中的开闭原则:一个软件实体应当对扩展开放,对修改关闭。那怎么解决呢?这个时候就需要使用到工厂方法模式,详见下文。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值