创建型设计模模式---工厂模式

本文详细介绍了工厂模式的概念及其在软件设计中的应用。通过对比简单工厂、工厂方法和抽象工厂三种模式的特点,结合咖啡制造实例,展示了如何通过工厂模式解耦对象创建与使用,降低系统复杂度。

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

设计模式

序号内容链接地址
1设计模式七大原则https://blog.csdn.net/qq_39668819/article/details/115390615
2创建型设计模式–工厂模式https://blog.csdn.net/qq_39668819/article/details/115375928
3创建型设计模式–抽象工厂模式https://blog.csdn.net/qq_39668819/article/details/115390992
4创建型设计模式–单例模式https://blog.csdn.net/qq_39668819/article/details/115396191
5创建型设计模式–建造者模式https://blog.csdn.net/qq_39668819/article/details/115396212
6创建型设计模式—原型模式https://blog.csdn.net/qq_39668819/article/details/115396227
7结构型设计模式—代理模式https://blog.csdn.net/qq_39668819/article/details/115480346
8结构型设计模式—适配器模式https://blog.csdn.net/qq_39668819/article/details/115499090
9结构型设计模式—桥接模式https://blog.csdn.net/qq_39668819/article/details/115560823
10结构型设计模式—装饰模式https://blog.csdn.net/qq_39668819/article/details/115582291
11结构型设计模式—外观模式https://blog.csdn.net/qq_39668819/article/details/115643900
12结构型设计模式—享元模式https://blog.csdn.net/qq_39668819/article/details/115680930
13结构型设计模式—组合模式https://blog.csdn.net/qq_39668819/article/details/115720713
14行为型设计模式—模板方法模式https://blog.csdn.net/qq_39668819/article/details/115774426
15行为型设计模式—策略模式https://blog.csdn.net/qq_39668819/article/details/115804292
16行为型设计模式—命令模式https://blog.csdn.net/qq_39668819/article/details/115877361
17行为型设计模式—责任链模式https://blog.csdn.net/qq_39668819/article/details/115981287
18行为型设计模式—状态模式https://blog.csdn.net/qq_39668819/article/details/116077215
19行为型设计模式—观察者模式https://blog.csdn.net/qq_39668819/article/details/116141223
20行为型设计模式—中介者模式https://blog.csdn.net/qq_39668819/article/details/116177694
21行为型设计模式—迭代器模式https://blog.csdn.net/qq_39668819/article/details/116213033
22行为型设计模式—访问者模式https://blog.csdn.net/qq_39668819/article/details/116246907
23行为型设计模式—备忘录模式https://blog.csdn.net/qq_39668819/article/details/116333844
24行为型设计模式—解释器模式https://blog.csdn.net/qq_39668819/article/details/116379466

创建型模式

创建型模式的主要关注点是 “怎样创建对象?”,它的主要特点是“将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节,对象的创建由相关的工厂来完成。就像我们去商场购买商品时,不需要知道商品是怎么生产出来一样,因为它们由专门的厂商生产。

工厂模式

工厂模式用于对象的创建,使得客户从具体的产品对象中被解耦,是一种创建型模式。其主要分为简单工厂、工厂方法、抽象工厂模式三种。本文从一个具体的例子逐步深入分析,来体会三种工厂模式的应用场景和利弊。

这里以制造咖啡为例分别介绍三种工厂模式。

简单工厂

该模式对对象创建管理方式最为简单,因为其仅仅简单的对不同类对象的创建进行了一层薄薄的封装。该模式通过向工厂传递类型来指定要创建的对象。

UML 类图如下:
在这里插入图片描述

模式的结构:

  • 简单工厂:是简单工厂模式的核心,负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
  • 抽象产品:是简单工厂创建的所有对象的父类,负责描述所有实例共有的公共接口。
  • 具体产品:是简单工厂模式的创建目标。

我们知道 coffee 只是一种泛举,在点购咖啡时需要指定具体的咖啡种类:美式咖啡、卡布奇诺、拿铁等等

interface Coffee {
    /**
     * 获取咖啡名称
     * @return
     */
    public String getName();
}

class Americano implements Coffee {

    @Override
    public String getName() {
        return "美式咖啡";
    }
}

class Cappuccino implements Coffee {

    @Override
    public String getName() {
        return "卡布奇洛";
    }
}

class Latte implements Coffee {

    @Override
    public String getName() {
        return "拿铁";
    }
}

创建咖啡的简单工厂

public class SimpleFactory {

    public static void main(String[] args) {
        CoffeeFactory coffeeFactory = new CoffeeFactory();
        Coffee americano = coffeeFactory.createCoffee("americano");
        Coffee cappuccino = coffeeFactory.createCoffee("cappuccino");
        Coffee latte = coffeeFactory.createCoffee("latte");

        System.out.println(americano.getName());
        System.out.println(cappuccino.getName());
        System.out.println(latte.getName());

        System.out.println();

        Coffee americano2 = coffeeFactory.createAmericano();
        System.out.println(americano2.getName());
        Coffee cappuccino2 = CoffeeFactory.createCappuccino();
        System.out.println(cappuccino2.getName());
    }
}

/**
 * 简单工厂
 */
class CoffeeFactory {

    public Coffee createAmericano() {
        return new Americano();
    }

    public static Coffee createCappuccino() {
        return new Cappuccino();
    }

    public Coffee createCoffee(String type) {
        switch (type) {
            case "americano":
                return new Americano();
            case "cappuccino":
                return new Cappuccino();
            case "latte":
                return new Latte();
            default:
                return null;
        }
    }
}

总结:

实例化对象的时候不再使用 new Object() 形式,可以根据用户的选择条件来实例化相关的类。对于客户端来说,去除了具体的类的依赖。只需要给出具体实例的描述给工厂,工厂就会自动返回具体的实例对象。

优点:我们可以对创建的对象进行一些 “加工” ,而使用者不需要关注,因为工厂隐藏了这些细节。如果没有工厂的话,那我们是不是就得自己写这些代码,这就好比本来可以在工厂里生产的东西,拿来自己手工制作,不仅麻烦以后还不好维护。

缺点:如果需要在方法里写很多与对象创建有关的业务代码,而且需要的创建的对象还不少的话,我们要在这个简单工厂类里编写很多个方法,每个方法里都得写很多相应的业务代码,而每次增加子类或者删除子类对象的创建都需要打开这简单工厂类来进行修改。这会导致这个简单工厂类很庞大臃肿、耦合性高,而且增加、删除某个子类对象的创建都需要打开简单工厂类来进行修改代码也违反了开-闭原则。

工厂方法模式

和简单工厂模式中工厂负责生产所有产品相比,工厂方法模式将生成具体产品的任务分发给具体的产品工厂。定义了一个创建对象的工厂接口,但由工厂子类决定要实例化的类是哪一个,工厂方法让类把实例化推迟到了子类。

其UML类图如下:

20210330150220891

也就是定义一个抽象工厂,其定义了产品的生产接口,但不负责具体的产品,将生产任务交给不同的派生类工厂。这样不用通过指定类型来创建对象了。

模式的结构:

  • 抽象工厂:提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品。
  • 具体工厂:主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
  • 抽象产品:定义了产品的规范,描述了产品的主要特性和功能。
  • 具体产品:实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。

场景延伸:不同地区咖啡工厂受制于环境、原料等因素的影响,制造出的咖啡种类有限。中国咖啡工厂能制造卡布奇诺、拿铁,而美国咖啡工厂仅能制造美式咖啡、拿铁。【依然使用上面创建的产品类】

public class FactoryMethod {

    public static void main(String[] args) {
        CoffeeFactory chinaCoffeeFactory = new ChinaCoffeeFactory();
        System.out.println("中国工厂生产的咖啡: ");
        Coffee[] chinaCoffees = chinaCoffeeFactory.createCoffee();
        printOut(chinaCoffees);

        System.out.println();

        CoffeeFactory americaCoffeeFactory = new AmericaCoffeeFactory();
        System.out.println("美国工厂生产的咖啡: ");
        Coffee[] americaCoffees = americaCoffeeFactory.createCoffee();
        printOut(americaCoffees);
    }

    static void printOut(Coffee[] c){
        for (Coffee coffee : c) {
            System.out.println(coffee.getName());
        }
    }
}

/**
 * 咖啡工厂接口
 */
interface CoffeeFactory {
    /**
     * 生产咖啡
     * @return
     */
    public Coffee[] createCoffee();
}

/**
 * 中国咖啡工厂
 */
class ChinaCoffeeFactory implements CoffeeFactory {

    @Override
    public Coffee[] createCoffee() {
        return new Coffee[]{new Cappuccino(), new Latte()};
    }
}

/**
 * 美国咖啡工厂
 */
class AmericaCoffeeFactory implements CoffeeFactory {

    @Override
    public Coffee[] createCoffee() {
       return new Coffee[]{new Americano(), new Latte()};
    }
}

总结:

工厂方法模式是对简单工厂模式进一步的解耦,因为在工厂方法模式中是一个子类对应一个工厂类,而这些工厂类都实现于一个抽象接口。这相当于是把原本会因为业务代码而庞大的简单工厂类,拆分成了一个个的工厂类,这样代码就不会都耦合在同一个类里了。

工厂模式中,要增加产品类时也要相应地增加工厂类,代码量增加了不少。但是实现了对简单工厂的解耦,实例对象可以通过相应的工厂创建,而不必再耦合到一个工厂类中,同时也符合开-闭原则。工厂方法模式克服了简单工厂会违背开-闭原则的缺点,又保持了封装对象创建过程的优点。但工厂方法模式的缺点是每增加一个产品类,就需要增加一个对应的工厂类,增加了额外的开发量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值