工厂设计模式(三种)详解

2023-05-16

https://www.jianshu.com/p/38493eb4ffbd

什么是工厂设计模式?
工厂设计模式,顾名思义,就是用来生产对象的,在java中,万物皆对象,这些对象都需要创建,如果创建的时候直接new该对象,就会对该对象耦合严重,假如我们要更换对象,所有new对象的地方都需要修改一遍,这显然违背了软件设计的开闭原则,如果我们使用工厂来生产对象,我们就只和工厂打交道就可以了,彻底和对象解耦,如果要更换对象,直接在工厂里更换该对象即可,达到了与对象解耦的目的;所以说,工厂模式最大的优点就是:解耦

本篇主要介绍三种工厂设计模式的使用:
1、简单工厂
2、工厂方法
3、抽象工厂

简单工厂设计模式

定义:一个工厂方法,依据传入的参数,生成对应的产品对象;
角色:
1、抽象产品 
2、具体产品
3、具体工厂 
4、产品使用者
使用说明:先将产品类抽象出来,比如,苹果和梨都属于水果,抽象出来一个水果类Fruit,苹果和梨就是具体的产品类,然后创建一个水果工厂,分别用来创建苹果和梨;代码如下:

水果接口

public interface Fruit {
    void whatIm();
}

具体类 苹果

public class Apple implements Fruit {
    @Override
    public void whatIm() {
        //苹果
    }
}

具体类 梨

public class Pear implements Fruit {
    @Override
    public void whatIm() {
        //梨
    }
}

具体工厂 水果工厂

public class FruitFactory {

    public Fruit createFruit(String type) {

        if (type.equals("apple")) {//生产苹果
            return new Apple();
        } else if (type.equals("pear")) {//生产梨
            return new Pear();
        }

        return null;
    }
}

产品使用

 FruitFactory mFactory = new FruitFactory();
 Apple apple = (Apple) mFactory.createFruit("apple");//获得苹果
 Pear pear = (Pear) mFactory.createFruit("pear");//获得梨

就这样,一个非常简单的工厂设计模式就完成了,但是有没有发现什么问题呢?
对,那就是如果我想吃香蕉,想吃橘子呢,我万一什么都想吃呢??所以,以上的这种方式,每当我想添加一种水果,就必然要修改工厂类,这显然违反了开闭原则,亦不可取;所以简单工厂只适合于产品对象较少,且产品固定的需求,对于产品变化无常的需求来说显然不合适;所以我们来看下一种方式;

工厂方法设计模式

定义:将工厂提取成一个接口或抽象类,具体生产什么产品由子类决定;
角色:
抽象产品类
具体产品类
抽象工厂类
具体工厂类
使用说明:和上例中一样,产品类抽象出来,这次我们把工厂类也抽象出来,生产什么样的产品由子类来决定;
代码如下:
水果接口 苹果类和梨类 代码和上例一样

工厂接口

public interface FruitFactory {
    Fruit createFruit();//生产水果
}

苹果工厂

public class AppleFactory implements FruitFactory {
    @Override
    public Fruit createFruit() {
        return new Apple();
    }
}

梨工厂

public class PearFactory implements FruitFactory {
    @Override
    public Fruit createFruit() {
        return new Pear();
    }
}

使用

AppleFactory appleFactory = new AppleFactory();
PearFactory pearFactory = new PearFactory();
Apple apple = (Apple) appleFactory.createFruit();//获得苹果
Pear pear = (Pear) pearFactory.createFruit();//获得梨

以上这种方式,虽然解耦了,也遵循了开闭原则,但是问题根本还是没有解决啊,换汤没换药,如果我需要的产品很多的话,需要创建非常多的工厂,所以这种方式的缺点也很明显;

抽象工厂设计模式

定义:为创建一组相关或者是相互依赖的对象提供的一个接口,而不需要指定它们的具体类。
角色:和工厂方法一样
抽象工厂和工厂方法的模式基本一样,区别在于,工厂方法是生产一个具体的产品,而抽象工厂可以用来生产一组相同,有相对关系的产品;重点在于一组,一批,一系列;举个例子,假如生产小米手机,小米手机有很多系列,小米note、红米note等;假如小米note生产需要的配件有825的处理器,6英寸屏幕,而红米只需要650的处理器和5寸的屏幕就可以了;用抽象工厂来实现:

cpu接口和实现类

public interface Cpu {
    void run();

    class Cpu650 implements Cpu {
        @Override
        public void run() {
            //625 也厉害
        }
    }

    class Cpu825 implements Cpu {
        @Override
        public void run() {
            //825 处理更强劲
        }
    }
}

屏幕接口和实现类

public interface Screen {

    void size();

    class Screen5 implements Screen {

        @Override
        public void size() {
            //5寸
        }
    }

    class Screen6 implements Screen {

        @Override
        public void size() {
            //6寸
        }
    }
}

工厂接口

public interface PhoneFactory {

    Cpu getCpu();//使用的cpu

    Screen getScreen();//使用的屏幕
}

具体工厂实现类:小米手机工厂

public class XiaoMiFactory implements PhoneFactory {
    @Override
    public Cpu getCpu() {
        return new Cpu.Cpu825();//高性能处理器
    }

    @Override
    public Screen getScreen() {
        return new Screen.Screen6();//6寸大屏
    }
}

具体工厂实现类:红米手机工厂

public class HongMiFactory implements PhoneFactory {

    @Override
    public Cpu getCpu() {
        return new Cpu.Cpu650();//高效处理器
    }

    @Override
    public Screen getScreen() {
        return new Screen.Screen5();//小屏手机
    }
}

以上例子可以看出,抽象工厂可以解决一系列的产品生产的需求,对于大批量,多系列的产品,用抽象工厂可以更好的管理和扩展;

三种工厂方式总结:
1、对于简单工厂和工厂方法来说,两者的使用方式实际上是一样的,如果对于产品的分类和名称是确定的,数量是相对固定的,推荐使用简单工厂模式;
2、抽象工厂用来解决相对复杂的问题,适用于一系列、大批量的对象生产;

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

工厂设计模式(三种)详解 的相关文章

  • 输入一个英文句子,翻转句子中的单词,要求单词内的字符顺序不变。 如:I am a student. 转换成 student. a am I

    输入一个英文句子 xff0c 翻转句子中的单词 xff0c 要求单词内的字符顺序不变 如 xff1a I am a student 转换成 student a am I 算法分析 xff1a 1 通过ReverseString xff08
  • OpenMLDB开源社区贡献者体系今日发布

    关于OpenMLDB OpenMLDB 是一个开源机器学习数据库 xff0c 提供企业级 FeatureOps 全栈解决方案 OpenMLDB 致力于闭环解决 AI 工程化落地的数据治理难题 xff0c 并且已经在上百个企业级人工智能场景中
  • 排序算法

    影响排序算法性能的几个要素 xff1a 1 时间性能 2 辅助空间 3 算法的复杂性 直接插入排序算法的基本操作是将一个记录插入到已经排好序的有序表中 xff0c 从而得到一个新的 xff0c 记录数增加一的有序表 void InsertS
  • c语言常用小知识点总结1

    define 用来定义宏常量 格式 xff1a define 标识符 大写字母 常量 define PI 3 14 注意后面是不加 分号的 常用字母的ASCII码 39 a 39 61 97 39 A 39 61 65 39 0 39 61
  • 数据结构学习笔记1

    程序设计 61 数据结构 43 算法 谈谈算法 数据结构与算法是 好基友 xff0c 如果单独谈数据结构 xff0c 或者单独谈算法是没什么意义的 来一个牛叉的算法吧 xff01 计算1 43 2 43 3 43 4 43 100 xff0
  • Oracle面试题附带答案

    1 你要对操纵Oracle数据库中的数据 下列哪个选项表示Oracle中select语句的功能 xff0c 并且不需要使用子查询 xff08 C xff09 A xff0e 可以用select语句改变Oracle中的数据 B xff0e 可
  • C结构体中数据的内存对齐问题

    转自 xff1a http www cnblogs com qwcbeyond archive 2012 05 08 2490897 html 32位机一般默认4字节对齐 xff08 32位机机器字长4字节 xff09 xff0c 64位机
  • 解决codeblocks无法调试的问题

    错误提示 xff1a ERROR You need to specify a debugger program in the debuggers 39 s settings For MinGW compilers it 39 s 39 gd
  • 求出现在字符串1而没有出现在字符串2中的字符

    编写一个函数 xff0c 它的功能是将未在字符串s中出现 xff0c 而在字符串t中出现的字符 xff0c 型参一个新的字符串放在u中 xff0c u中的字符按原字符的顺序排列 xff0c 但要去掉重复字符 至少会想到去考察t xff0c
  • 什么情况下需要建立索引? 索引的作用?为什么能够提高查询速度?(索引的原理) 索引有什么副作用吗?

    https www cnblogs com Berryxiong p 6249427 html 为什么能够提高查询速度 xff1f 索引就是通过事先排好序 xff0c 从而在查找时可以应用二分查找等高效率的算法 一般的顺序查找 xff0c
  • 100w测试数据,为什么加了索引查询反而变慢了?

    建表 xff1a create table tb test fval varchar 50 插入测试数据 xff1a DELIMITER CREATE DEFINER 61 96 root 96 64 96 localhost 96 PRO
  • linux环境下使用gdb调试c和c++ 学习笔记

    第二十三课 xff1a GDB简介 哔哩哔哩 bilibili gdb调试 xff1a 1 gcc a c b c c c o app g g 编译器会保留函数名和变量名 2 启动gdb gdb 可执行程序的名字 xff08 gdb app
  • ubuntu下eth0网卡信息不见了

    ubuntu终端下命令ifconfig的问题解决 问题一 ifconfig之后只显示lo 没有看到eth0 问题二 ifconfig之后显示eth0 xff0c 但是没有显示静态IP地址 xff0c 即无inet 地址 广播 掩码 问题三
  • 计算机指令

    指令系统的设计原则包括 xff1a 完备性 xff1a 该有的都要有 有效性 xff1a 简洁 加速常用操作 没有歧义 规整性 xff1a 对称 均匀 一致 xff08 简单源于规整 xff09 兼容性 xff1a 之前 之后的都能用 下面
  • shell基础学习笔记1

    shell是什么 xff1f shell是一个命令解释器 xff0c 他为用户提供了一个向linux内核发送请求以便运行程序的界面系统级程序 xff0c 用户可以用shell来启动 挂起 停止甚至编写一些程序 其实就是输入命令的那个交互界面
  • linux达人养成学习笔记1

    2 4 分区之分区设备文件名与挂载 1 swap分区 xff0c 没有挂载点 xff0c 是文件系统类型 xff08 交换分区 xff0c 电脑内存 lt 4G xff0c 可分为内存2倍 xff1b gt 4G分同等大小 xff09 2
  • shell编程之变量学习小结

    在Bash中 xff0c 变量的默认类型都是字符串型 变量的分类 1 用户自定义变量 xff1a 变量可以自定义 xff0c 但是对系统生效的环境变量名和变量作用是固定的 2 环境变量 xff1a 这种变量中主要保存的是和系统操作环境相关的
  • 程序员的自我修养

    1 Provide Options Don 39 t make lame Excuses 提供各种选择 xff0c 不要找蹩脚的借口 2 Don 39 t live with Broken Windows 不要容忍破窗户 3 Be a ca
  • 二阶三阶四阶魔方旋转公式

  • 什么是回调函数?

    为了弄明白这种函数的奥妙 xff0c 首先提出三个问题 xff1a 1 回调函数是什么东西 xff1f 2 回调函数怎么开发 xff0c 怎么使用 xff1f 3 回调函数的作用 xff0c 应该在什么情况下使用 xff1f 带着问题来学习

随机推荐