设计模式学习笔记-工厂模式

2023-11-19

设计模式学习笔记-工厂模式

作用

  • 实现了创建者和调用者的分离
  • 详细分类
    • 简单工厂模式
      • 用来生产同一等级结构中的任意产品(对于增加新的产品,必须要扩展已有的代码)
    • 工厂方法模式
      • 用来生产同一等级结构中的固定产品(支持增加任意产品)
    • 抽象工厂模式
      • 围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂

在工厂模式中该满足的OOP七大原则

  • 开闭原则
  • 依赖倒置原则
  • 迪米特法则

核心本质

  • 实例化对象不适用new,用工厂方法代替
  • 将选择实现类,创建对象统一管理和控制,从而将调用者和实现类解耦

以往的使用方式(以买车举例)

我们先定义一个车的接口,代表了我们所要买的东西是一辆车

public interface Car{
    void name();
}

接着我们去定义具体的车的类型,哪种车

public class Porsche implements Car{
    @Override
    public void name(){
        System.out.println("Porsche");
    }
}

接着是我们的消费者类,干这件事的主体

public class Consumer{
    public static void main(String[] args){
        Car porsche = new Porsche();
   
   		porsche.name();
    }
}

在这种情况下,我们必要要清楚该接口以及其所有的实现类,但在真实情况下,我们只需要知道其接口,即其主要是个什么东西,而不需要去知道其实现类。

简单工厂模式(静态工厂模式)

那么,去实现这样一种写法,我们就需要使用工厂模式。首先定义一个车的工厂:

public class CarFactory{
    
    // 我们根据客户需求的不同车的名字去获取该车
    public static Car getCar(String carName){
        if(carName.equals("Porsche"))
            return new Porsche();
        else if(carName.equals("Ferrari"))
            return new Ferrari();
        else
            return null;
    }
    
}

那么在消费者的类中,我们只需传入想要的东西的一些属性我们就可获得

public class Consumer{
    
    public static void main(String[] args){
        
        Porsche porsche = CarFactory.getCar("Porsche");
        Ferrari ferrari = CarFactory.getCat("Ferrari");
        ....
            
        Porsche.name();
        Ferrari.name();
        ....
            
    }
    
}

但是即便在这种情况下,这个CarFactory类仍然存在着问题,它并不满足开闭原则,即我们每想增加一种类型的车的时候,就需要在代码逻辑之间去增加、修改,代码的冗余度高而且对于代码的维护十分不便利,那我们该如何去优化这个工厂呢,有的人可能会想,那么在工厂中,对于客户想要什么类型的车就返回什么车就好了

public class CarFactory{
    public static Car getPorsche(){
        return new Porsche();
    }
    
    public static Car getFerrari(){
        return new Ferrari();
    }
}

在这种方式下,虽然优化了工厂,使我们在新增车辆种类时不必去修改原有的代码逻辑,但我们还是需要在该工厂中新增一个新的方法,仍然是不满足开闭原则,而简单工厂模式的弊端就是当增加一个新的产品时,如果不修改代码是做不到的

工厂方法模式

同样的,在这种模式下,我们仍需要车工厂,但是不同的是,我们不再是使用一个车工厂去生产所有的车,而是让每一个车有其对应的车工厂,那么首先我们定义一个接口,去规范所有的车工厂

public interface CarFactory{
    // 获取车辆
    Car getCar();
}

拿Porsche举例,要想获得指定的车,那么就需要指定的车工厂:

public class PorscheFactory implements CarFactory{
    
    // 获取Porsche
    @Override
    public Car getCar(){
        return new Porsche(); 
    }
}

那么在消费者想消费指定车辆时,只需从指定车工厂获取即可

public class Consumer{
    
    Public static void main(String[] args){
        Porsche porsche = new PorscheFactory().getCar();
        
        porsche.name();
    }
    
}

而在这种模式下,当我们想要新增一个车的种类(例如:Lambo)时,可以发现,我们只需增加一个Lambo的类,增加一个LamboFactory的类,而此时我们并没有去修改原来的代码,但弊端就是代码量显著提高了

两者区别

  • 结构复杂度上看

    • 简单工厂模式的结构复杂度显然是要低于工厂方法模式
  • 代码复杂度上看

    • 简单工厂模式的代码复杂度低于工厂方法模式
  • 编程复杂度

    • 简单工厂模式的编程复杂度低于工厂方法模式
  • 管理复杂度

    • 简单工厂模式因为所有的代码都集合在一个工厂中,管理起来是要低于工厂方法模式的

那么,综上来看,如果是根据设计原则,那么我们优先使用工厂方法模式,而如果是根据实际业务,我们优先使用简单工厂模式。

应用场景

  • JDK中Calendar的getInstance方法
  • JDBC中Connection对象的获取
  • Spring中IOC容器创建管理bean对象
  • 反射中Class对象中的newInstance方法
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

设计模式学习笔记-工厂模式 的相关文章

  • 最简单的方式来理解阻抗、反射和端接

    1 阻抗失配与反射 在深入学习电磁场之后 就觉得高中物理老师不应该用水流来比喻电流 结果到了自己去和别人讲阻抗反射 发现用水来做比喻还是很方便轻松的 所以之前在电源滤波的系列文章中 高速先生就多次请 水 来友情出演 这不 欢迎我们的 水 小

随机推荐

  • Simulink仿真模型中的常数符号赋值

    对模型中的参数或者是常数符号赋值可以通过下面两种方法 在MATLAB的命令行中直接赋值 然后再运行仿真模型 如下图 在file gt model properties的initFcn 中进行设置
  • AI芯片,是噱头还是趋势?

    随着AlphaGo的诞生 深度学习 日益普及 人工智能开始从智能化工具向智能机器进军 原有的MCU已无法满足深度学习的高速海量数据运算要求 AI芯片便应运而生 如今嵌入式芯片领域正面临AI芯片的新一轮机遇 那么在AI成为风口的当下 AI芯片
  • 2022年高级性能测试岗面试题【面试必看】

    昨天一个前同事找我 问有没有性能测试岗位的面试题 正好之前帮业务团队加面过几次性能测试岗位的候选人 我将面试时候会问的一些问题以及要考察的点列了出来 供大家参考 一 介绍下最近做过的项目 背景 预期指标 系统架构 场景设计及遇到的性能问题
  • oobabooga-text-generation-webui可能是最好的语言模型启动器(包含手把手安装教程)

    原文 oobabooga text generation webui可能是最好的语言模型启动器 包含手把手安装教程 哔哩哔哩 引言 问 oobabooga是什么 oobabooga text generation webui是一个用于运行类
  • HeadFirst 设计模式学习笔记10——MVC分析

    1 M V C Model View Controller 模式 视图 控制器 这是一种范型 模型对象正是应用系统存在的理由 你设计的对象 包含了数据 逻辑和其他在你的应用领域创建定制的类 视图通常是控件 用来显示和编辑 控制器位于二者中间
  • 3.3 C++多继承与虚基类

    书接上回 继承存在二义性 上图中 A是虚基类 virtual的继承方式就是虚继承 参考下文章 C 虚继承和虚基类详解 知乎 zhihu com
  • apache和iis文件解析漏洞原理及修复

    Apache文件解析漏洞是指攻击者可以利用Apache服务器的文件解析功能 通过构造特殊的URL 访问服务器上的敏感文件 从而获取服务器上的敏感信息 IIS文件解析漏洞是指攻击者可以利用IIS服务器的文件解析功能 通过构造特殊的URL 访问
  • 面试官:如何用a标签实现文件下载?(一文带你手撕知识点)

    前言 大家好 今天给大家带来前端小知识 前端利用a标签实现文件 图片 下载 也就是教大家利用a标签或者是 window open 来实现下载功能 文章目录 前言 常用方式 方法分析 代码实现 常用方式 a href url 下载 a a标签
  • Weex简介及环境搭建(mac版)

    1 Weex简介及特点 weex 是一个使用 Web 开发体验来开发高性能原生应用的框架 在Ios和Android上都实现了一个渲染引擎 并提供了一套基础的内置组件 渲染出来的都是原生组件 提供了一套基础的内置模块 可以通过这些模块来调用一
  • 校园网服务器系统需求分析,校园网建设需求分析.doc

    校园网建设需求分析校园网建设需求分析 文档日期2012 5 9编号002项目名称北京市信息职业技术学院东校区校园网建设项目部门网建部开始时间2012 5 9结束时间2012 5 文档名称北京市信息职业技术学院东校区校园网建设项目需求分析文
  • 放弃Dubbo,选择最流行的Spring Cloud微服务架构实践与经验总结

    51CTO com原创稿件 Spring Cloud 在国内中小型公司能用起来吗 从 2016 年初一直到现在 我们在这条路上已经走了一年多 在使用 Spring Cloud 之前 我们对微服务实践是没有太多的体会和经验的 从最初的开源软件
  • uniapp git忽略unpackage文件

    最近在写整理一个app框架 遇到git提交时unpackage文件无法忽略的问题 1 第一反应是创建 gitignore文件 并写入unpackage目录 本以为大功告成 奈何还是不行 思考 可能是由于该文件已经被提交过 处于被跟踪状态 所
  • opencv安装教程python3.8_Python3.8 安装 OpenCV 库

    我是 Python 小新 本文演示如何在 Windows 10 下为 Python 安装 OpenCV 库 事实上 借助于强大的包管理工具 pip 只需要一条安装命令就可搞定 打开命令提示符 输入如下命令 pip install openc
  • Openframework在VS2010中的配置

    Openframework在VS2010中的配置 首先去官网下载Openframework 下载后最好解压到C盘根目录下 不然会出现各种问题 我也不知道怎么解决 随便打开其中的例程 然后右击该工程 选择属性 如下图 接着在C C 常规选项里
  • 基于MATLAB的WSN网络时间同步仿真

    目录 1 算法概述 2 仿真效果 3 matlab仿真源码 1 算法概述 WSN时间同步 时钟偏移与同步问题 主讲教师 马小林 1 时钟偏移与同步问题 1 时钟偏移与同步问题 时钟偏移 时钟之间的时间差 Clock Offset WSN系统
  • 【王道·计算机网络】第一章 计算机网络基本体系

    一 计算机网络概述 1 概念 计算机网络是一个将分散的 具有独立功能的计算机系统 通过通信设备与线路连接起来 由功能完善的软件实现资源共享和信息传递的系统 简而言之 计算机网络就是一些互联的 通过通信链路互联互通 自治的计算机系统的集合 2
  • pycharm:Updating Indices 解决办法

    pycharm Updating Indices 解决办法 右下角一直在update 然后我的文件夹里面文件很多 都是图片流 pycharm相当于预加载这些 然后在左侧可以查看 但是这个过程比较慢 解决的方法是让pycharm直接无视某些文
  • Window下用caffe实现MNIST训练

    本博包含MNIST原始数据的格式转化 以及分类训练 1 数据转化 Caffe源码中src caffe caffe examples mnist convert mnist data cpp提供的实现代码并不能直接在Windows下运行 这里
  • Filebeat监控 日志监控

    介绍 filebeat提供了两种监控 一种直接推送到ES集群 第二种就是Metricbeat 这里介绍第一种 也就四部 第1步 创建认证 账号密码 这一步基本可以略过了 如果你的filebeat在运行 你肯定已经有账号密码了 第2步 配置f
  • 设计模式学习笔记-工厂模式

    设计模式学习笔记 工厂模式 作用 实现了创建者和调用者的分离 详细分类 简单工厂模式 用来生产同一等级结构中的任意产品 对于增加新的产品 必须要扩展已有的代码 工厂方法模式 用来生产同一等级结构中的固定产品 支持增加任意产品 抽象工厂模式