Chiriri's blog Chiriri's blog
首页
  • Java

    • JavaSE
    • JavaEE
    • 设计模式
  • Python

    • Python
    • Python模块
    • 机器学习
  • Golang

    • Golang
    • gRPC
  • 服务器

    • Linux
    • MySQL
    • NoSQL
    • Kubernetes
  • 项目

    • 传智健康
    • 畅购商城
  • Hadoop生态

    • Hadoop
    • Zookeeper
    • Hive
    • Flume
    • Kafka
    • Azkaban
    • Hbase
    • Scala
    • Spark
    • Flink
  • 大数据项目

    • 离线数仓
  • 青训营

    • 第四届青训营
  • HTML

    • HTML
    • JavaScript
  • Vue

    • Vue2
    • TypeScript
    • Vue3
    • Uni-APP
  • 数据结构与算法
  • C语言
  • 考研数据结构
  • 计算机组成原理
  • 计算机操作系统
  • Java基础

    • Java基础
    • Java集合
    • JUC
    • JVM
  • 框架

    • Spring
    • Dubbo
    • Spring Cloud
  • 数据库

    • MySQL
    • Redis
    • Elasticesearch
  • 消息队列

    • RabbitMQ
    • RocketMQ
  • 408

    • 计算机网络
    • 操作系统
    • 算法
  • 分类
  • 标签
  • 归档
  • 导航站
GitHub (opens new window)

Iekr

苦逼后端开发
首页
  • Java

    • JavaSE
    • JavaEE
    • 设计模式
  • Python

    • Python
    • Python模块
    • 机器学习
  • Golang

    • Golang
    • gRPC
  • 服务器

    • Linux
    • MySQL
    • NoSQL
    • Kubernetes
  • 项目

    • 传智健康
    • 畅购商城
  • Hadoop生态

    • Hadoop
    • Zookeeper
    • Hive
    • Flume
    • Kafka
    • Azkaban
    • Hbase
    • Scala
    • Spark
    • Flink
  • 大数据项目

    • 离线数仓
  • 青训营

    • 第四届青训营
  • HTML

    • HTML
    • JavaScript
  • Vue

    • Vue2
    • TypeScript
    • Vue3
    • Uni-APP
  • 数据结构与算法
  • C语言
  • 考研数据结构
  • 计算机组成原理
  • 计算机操作系统
  • Java基础

    • Java基础
    • Java集合
    • JUC
    • JVM
  • 框架

    • Spring
    • Dubbo
    • Spring Cloud
  • 数据库

    • MySQL
    • Redis
    • Elasticesearch
  • 消息队列

    • RabbitMQ
    • RocketMQ
  • 408

    • 计算机网络
    • 操作系统
    • 算法
  • 分类
  • 标签
  • 归档
  • 导航站
GitHub (opens new window)
  • JavaSE

  • JavaEE

  • Linux

  • MySQL

  • NoSQL

  • Python

  • Python模块

  • 机器学习

  • 设计模式

    • 设计模式的概念
    • 创建型模式
    • 单例(Singleton)模式
    • 原型(Prototype)模式
    • 工厂(Factory)模式
      • 简单工厂(Simple Factory )
      • 工厂方法(Factory Method)
      • 抽象工厂(Abstract Factory)
      • 工厂模式的退化
      • 应用场景
      • 工厂模式小结
    • 建造者(Builder)模式
    • 结构型模式(Structural Pattern)
    • 适配器模式(Adapter Pattern)
    • 桥接模式(Bridge Pattern)
    • 装饰器模式(Decorator、Wrapper(包装) Pattern)
    • 代理模式(Proxy Pattern)
    • 外观模式(Facade Pattern)
    • 组合模式(Composite Pattern)
    • 享元模式(Flyweight Pattern)
    • 行为型模式(Behavioral Patterns)
    • 模板方法(Template Method)
    • 策略(Strategy)模式
    • 状态(State)模式
    • 中介者(Mediator)模式
    • 观察者(Observer)模式
    • 备忘录(Memento)模式
    • 解释器(Interpreter)模式
    • 命令(Command)模式
    • 迭代器(Iterator)模式
    • 访问者(Visitor)模式
    • 职责链(Chain of Responsibility)模式
    • 总结
  • 传智健康

  • 畅购商城

  • 博客项目

  • JVM

  • JUC

  • Golang

  • Kubernetes

  • 硅谷课堂

  • C

  • 源码

  • 神领物流

  • RocketMQ

  • 短链平台

  • 后端
  • 设计模式
Iekr
2022-04-21
目录

工厂(Factory)模式

# 工厂(Factory)模式

工厂模式(Factory Pattern)提供了一种创建对象的最佳方式。我们不必关心对象的创建细节,只需要根据不同情况获取不同产品即可。难点:写好我们的工厂

# 简单工厂 (Simple Factory)

只定义一个具体工厂,由该工厂判断生产哪个产品。

缺点:违背开闭,扩展不易

image-20220421160551890

三个角色

Factory:工厂角色, WuLinFactory

/**
 * 简单工厂
 * 1.产品数量极少
 */
public class WuLinFactory {

    //简单工厂一切从简
    public AbstractCar newCar(String type) {
        if ("van".equals(type)) {
            return new VanCar();
        } else if ("mini".equals(type)) {
            return new MinCar();
        }
        return null;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Product:抽象产品角色,Car

/**
 * 工厂产品
 */
public abstract class AbstractCar {

    String engine;

    public abstract void run();
}
1
2
3
4
5
6
7
8
9

ConcreteProduct:具体产品角色, VanCar、MiniCar

public class MinCar extends AbstractCar {
    public MinCar() {
        this.engine = "四缸发动机";
    }

    @Override
    public void run() {
        System.out.println(engine + "被生产");
    }
}
1
2
3
4
5
6
7
8
9
10
public class VanCar extends AbstractCar {

    public VanCar() {
        this.engine = "单杠柴油机";
    }

    @Override
    public void run() {
        System.out.println(engine + "被生产");
    }
}
1
2
3
4
5
6
7
8
9
10
11

测试方法:

public static void main(String[] args) {
    WuLinFactory factory = new WuLinFactory();
    AbstractCar van = factory.newCar("van");
    AbstractCar mini = factory.newCar("mini");
    AbstractCar qwq = factory.newCar("qwq");
    van.run();
    System.out.println(van);
    mini.run();
    System.out.println(mini);
    System.out.println(qwq);
}
1
2
3
4
5
6
7
8
9
10
11

# 工厂方法 (Factory Method)

将工厂抽象化,定义多个生产工厂,每个工厂只负责自己生产的产品。

缺点:系统复杂度增加,产品单一

image-20220421163043007

四个角色

Product:抽象产品

/**
 * 工厂产品
 *
 * 怎么把一个功能提升一个层次:定义抽象(抽象类、接口)
 * 抽象类,接口 就会有多实现 多实现自然有多功能
 */
public abstract class AbstractCar {

    String engine;

    public abstract void run();
}
1
2
3
4
5
6
7
8
9
10
11
12

ConcreteProduct:具体产品

三个具体产品

/**
 * 继承工厂抽象产品 为一个具体的产品
 */
public class VanCar extends AbstractCar {

    public VanCar() {
        this.engine = "单杠柴油机";
    }

    @Override
    public void run() {
        System.out.println(engine + "被生产");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class MiniCar extends AbstractCar {
    public MiniCar() {
        this.engine = "四缸发动机";
    }

    @Override
    public void run() {
        System.out.println(engine + "被生产");
    }
}
1
2
3
4
5
6
7
8
9
10
public class RacingCar extends AbstractCar {

    public RacingCar() {
        this.engine = "V8发动机";
    }

    @Override
    public void run() {
        System.out.println(engine + "被生产");
    }
}
1
2
3
4
5
6
7
8
9
10
11

Factory:抽象工厂

将生产方法抽象化

public abstract class AbstractCarFactory {

    public abstract AbstractCar newCar();
}
1
2
3
4

ConcreteFactory:具体工厂

有多少个产品就有多少个工厂

public class WulinMiniCarFactory extends AbstractCarFactory{
    @Override
    public AbstractCar newCar() {
         return new MiniCar();
    }
}
1
2
3
4
5
6
public class WulinRacingCarFactory extends AbstractCarFactory{
    @Override
    public AbstractCar newCar() {
        return new RacingCar();
    }
}
1
2
3
4
5
6
public class WulinVanCarFactory extends AbstractCarFactory{
    @Override
    public AbstractCar newCar() {
        return new VanCar();
    }
}
1
2
3
4
5
6

测试类

    public static void main(String[] args) {
        AbstractCarFactory carFactory = new WulinRacingCarFactory();
        AbstractCar abstractCar = carFactory.newCar();
        abstractCar.run();

        carFactory = new WulinMiniCarFactory();
        AbstractCar abstractCar1 = carFactory.newCar();
        abstractCar1.run();


        carFactory = new WulinVanCarFactory();
        AbstractCar abstractCar2 = carFactory.newCar();
        abstractCar2.run();
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 抽象工厂 (Abstract Factory)

image-20220421163551231

image-20220421163712346

将工厂抽象化 抽象方法为生产抽象类别,需要什么产品就创建什么工厂来生成。

抽象产品族:即抽象类别

public abstract class AbstractCar {

    String engine;

    public abstract void run();
}
1
2
3
4
5
6
public abstract class AbstractMask {

    Integer price;

    public abstract void protecteMe();
}
1
2
3
4
5
6

产品等级结构:生具体产品族的具体产品

public class MiniCar extends AbstractCar {
    public MiniCar() {
        this.engine = "四缸发动机";
    }

    @Override
    public void run() {
        System.out.println(engine + "被生产");
    }
}
1
2
3
4
5
6
7
8
9
10
public class VanCar extends AbstractCar {

    public VanCar() {
        this.engine = "单杠柴油机";
    }

    @Override
    public void run() {
        System.out.println(engine + "被生产");
    }
}
1
2
3
4
5
6
7
8
9
10
11
public class N95Mask extends AbstractMask {
    public N95Mask() {
        this.price = 2;
    }

    @Override
    public void protecteMe() {
        System.out.println("N95口罩被生产 价位为" + price);
    }
}
1
2
3
4
5
6
7
8
9
10
public class CommonMask extends AbstractMask {

    public CommonMask() {
        this.price = 1;
    }

    @Override
    public void protecteMe() {
        System.out.println("普通口罩被生成 价格为" + price);
    }
}
1
2
3
4
5
6
7
8
9
10
11

总厂规范:工厂全部产品族

可以再次细分工厂产品族,不生成的类别返回 null,生成的类别为抽象(abstract)方法,让生成工厂实现单一类别的生成产品。

/**
 * 总厂规范
 */
public abstract class WulinFactory {
    abstract AbstractCar newCar();

    abstract AbstractMask newMask();
}
1
2
3
4
5
6
7
8

生成工厂:生成指定产品族的指定产品

public class WulinMiniCarFatory extends WulinFactory {
    @Override
    protected AbstractCar newCar() {
        return new MiniCar();
    }

    @Override
    AbstractMask newMask() {
        return null;
    }
}
1
2
3
4
5
6
7
8
9
10
11
public class WulinVanCarFatory extends WulinFactory {

    @Override
    protected AbstractCar newCar() {
        return new VanCar();
    }

    @Override
    AbstractMask newMask() {
        return null;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
public class WulinN95MaskFactory extends WulinFactory{
    @Override
    protected AbstractCar newCar() {
        return null;
    }

    @Override
    AbstractMask newMask() {
        return new N95Mask();
    }
}
1
2
3
4
5
6
7
8
9
10
11
public class WulinCommonMaskFactory extends WulinFactory{
    @Override
    protected AbstractCar newCar() {
        return null;
    }

    @Override
    AbstractMask newMask() {
        return new CommonMask();
    }
}
1
2
3
4
5
6
7
8
9
10
11

测试方法:

    public static void main(String[] args) {
        WulinFactory wulinFactory = new WulinCommonMaskFactory();
        AbstractMask commonMask = wulinFactory.newMask();
        commonMask.protecteMe(); //只生成普通口罩


        wulinFactory = new WulinN95MaskFactory();
        AbstractMask N95 = wulinFactory.newMask();
        N95.protecteMe(); //生成N95

        wulinFactory = new WulinMiniCarFatory();
        AbstractCar miniCar = wulinFactory.newCar();
        miniCar.run();

        wulinFactory = new WulinVanCarFatory();
        AbstractCar vanCar = wulinFactory.newCar();
        vanCar.run();


    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 工厂模式的退化

  • 当抽象工厂模式中每一个具体工厂类只创建一个产品对象,也就是只存在一个产品等级结构时,抽象工厂模式退化成工厂方法模式;当工厂方法模式中抽象工厂与具体工厂合并,提供一个统一的工厂来创建产品对象,并将创建对象的工厂方法设计为静态方法时,工厂方法模式退化成简单工厂模式。

# 应用场景

  • NumberFormat、SimpleDateFormat
  • LoggerFactory:
  • SqlSessionFactory:MyBatis
  • BeanFactory:Spring 的 BeanFactory(就是为了造出 bean)

JDK 中的 Calendar 类中,就使用了简单工厂模式

import java.util.Calendar;
public class Factory {
    public static void main(String[] args) {
// TODOAuto-generated method stub
// getInstance 是 Calendar 静态方法
        Calendar cal = Calendar.getInstance();
// 注意月份下标从 0 开始,所以取月份要+1
        System.out.println("年:" + cal.get(Calendar.YEAR));
        System.out.println("月:" + (cal.get(Calendar.MONTH) + 1));
        System.out.println("日:" + cal.get(Calendar.DAY_OF_MONTH));
        System.out.println("时:" + cal.get(Calendar.HOUR_OF_DAY));
        System.out.println("分:" + cal.get(Calendar.MINUTE));
        System.out.println("秒:" + cal.get(Calendar.SECOND));
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

Calendar.java

package com.atguigu.jdk;
import java.util.Calendar;
public class Factory {
    public static void main(String[] args) {
// TODOAuto-generated method stub
// getInstance 是 Calendar 静态方法
        Calendar cal = Calendar.getInstance();
// 注意月份下标从 0 开始,所以取月份要+1
        System.out.println("年:" + cal.get(Calendar.YEAR));
        System.out.println("月:" + (cal.get(Calendar.MONTH) + 1));
        System.out.println("日:" + cal.get(Calendar.DAY_OF_MONTH));
        System.out.println("时:" + cal.get(Calendar.HOUR_OF_DAY));
        System.out.println("分:" + cal.get(Calendar.MINUTE));
        System.out.println("秒:" + cal.get(Calendar.SECOND));
    }
}
public static Calendar getInstance() {
    return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
}
private static Calendar createCalendar(TimeZone zone,
                                       Locale aLocale) { //根据 TimeZone zone, locale 创建对应的实例
    CalendarProvider provider =
        LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
        .getCalendarProvider();
    if (provider != null) {
        try {
            return provider.getInstance(zone, aLocale);
        } catch (IllegalArgumentException iae) {
// fall back to the default instantiation
        }
    }
    Calendar cal = null;
    if (aLocale.hasExtensions()) {
        String caltype = aLocale.getUnicodeLocaleType("ca");
        if (caltype != null) {
            switch (caltype) {
            case "buddhist":
                cal = new BuddhistCalendar(zone, aLocale);
                break;
            case "japanese":
                cal = new JapaneseImperialCalendar(zone, aLocale);
                break;
            case "gregory":
                cal = new GregorianCalendar(zone, aLocale);
                break;
            }
        }
    }
    if (cal == null) {
        // If no known calendar type is explicitly specified,
        // perform the traditional way to create a Calendar:
        // create a BuddhistCalendar for th_TH locale,
        // a JapaneseImperialCalendar for ja_JP_JP locale, or
        // a GregorianCalendar for any other locales.
        // NOTE: The language, country and variant strings are interned.
        if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
            cal = new BuddhistCalendar(zone, aLocale);
        } else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja"
                   && aLocale.getCountry() == "JP") {
            cal = new JapaneseImperialCalendar(zone, aLocale);
        } else {
            cal = new GregorianCalendar(zone, aLocale);
        }
    }
    return cal;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

# 工厂模式小结

  1. 工厂模式的意义将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦。从而提高项目的扩展和维护性。
  2. 三种工厂模式 (简单工厂模式、工厂方法模式、抽象工厂模式)
  3. 设计模式的依赖抽象原则
  • 创建对象实例时,不要直接 new 类,而是把这个 new 类的动作放在一个工厂的方法中,并返回。有的书上说,变量不要直接持有具体类的引用。
  • 不要让类继承具体类,而是继承抽象类或者是实现 interface (接口)
  • 不要覆盖基类中已经实现的方法。
编辑 (opens new window)
上次更新: 2023/12/13, 06:06:02
原型(Prototype)模式
建造者(Builder)模式

← 原型(Prototype)模式 建造者(Builder)模式→

最近更新
01
k8s
06-06
02
进程与线程
03-04
03
计算机操作系统概述
02-26
更多文章>
Theme by Vdoing | Copyright © 2022-2025 Iekr | Blog
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式