01:工厂模式基础使用

news/2025/3/12 22:32:37/文章来源:https://www.cnblogs.com/linxiaoki/p/18768775

创建型模式对类的实例化过程进行了抽象,能够将软件模块中对象的创建和对象的使用分离。其隐藏了类的实例的创建细节。包括简单工厂模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式、单例模式。
工厂模式并不是一个独立的设计模式,而是三种功能接近的设计模式(简单工厂模式、工厂方法模式、抽象工厂模式)的统称。

工厂模式举例

创建对象如果需要一系列的初始化操作,一般来说可以写在构造函数里,不过这样的话会导致构造函数的代码变得太长,降低程序的可读性。所以,我们可以增加一个特殊的类,即工厂类,用来负责对象的创建工作。

假设我们需要一个被广泛引用的“口罩类”,其初始化的代码也比较复杂:

public class Mask{// 构造函数public Mask(){// ...// 100行初始化代码k}
}

简单工厂模式

1. 我们可以构建一个“口罩工厂”专门负责创建口罩对象,把口罩的初始化代码迁移到工厂类的创建方法中:
public class Mask{public Mask();
}// 口罩工厂
public class MaskFactoy{public Mask createMask(){Mask mask = new Mask();// ...// 100行初始化代码retrun mask;}
}
2.1 假设口罩类存在子类,可以将口罩类作为抽象接口,子类(高级口罩和低级口罩)实现接口。
public interface IMask{void show();
} public class HighEndMask implements IMask{@Overridepublic void show(){System.out.println("我是高端口罩");}
}public class LowEndMask implements IMask{@Overridepublic void show(){System.out.println("我是低端口罩");}
}
2.2 创建工厂
public class MaskFactory{public IMask createMask(type){IMask mask = null;if("高端口罩".equals(type)){mask = new HighEndMask();// ...// HighEndMask 的100行初始化代码}else if("低端口罩".equals(type)){mask = new LowEndMask();// ...// LowEndMask 的100行初始化代码}return mask;}
}
2.3 只要传入对应的类型名称,就可以创建相应的口罩对象:
public class Test{public staic void main(String[]){MaskFactory factory = new MaskFactory();IMask maskA = factory.createMask("高端口罩");IMask maskB = factory.createMask("低端口罩");maskA.show();maskB.show();}
}

工厂方法模式

如果增加新的口罩子类,口罩工厂的创建方法中就要新增if-else判断,不符合面向对象的开发-封闭原则。所以我们可以为每个口罩子类创建对应的工厂子类,这些工厂子类分别实现抽象的工厂接口。(多态)

开放-封闭原则,即在程序中对扩展开放,对修改封闭。如果每次业务改动都要新增if-else,就涉及对旧有代码的修改,容易出错,可读性也不好。

1.2 所以我们可以修改简单工厂模式中2.2的内容,重构一下工厂类的逻辑:
public interface IMaskFactory{IMask createMask(); 
}public class HighEndMaskFactory implements IMaskFactory{@Overridepublic IMask createMask(){IMask mask = new HighEndMask(); // ...// 100行初始化代码return mask;}
}public class LowEndMaskFactory implements IMaskFactory{@Overridepublic IMask createMask(){IMask mask = new LowEndMask();// ...// 100行初始化代码return mask;}
}
1.2 使用
public class Test{public static void main(String[]){IMaskFactory factoryA = new HighEndMaskFactory();IMask maskA = factoryA.createMask();maskA.show();IMaskFactory factoryB = new LowEndMaskFactory();IMask maskB = factoryB.createMask();maskB.show();}
}

抽象工厂模式

如果需要创建子类越来越多,不只有口罩,还有防毒面具、防护服之类的,难道每一个子类都需要对应一个工厂吗?
解决:如果带创建的产品非常多,不需要为每个产品配上一个工厂类(比如高端口罩,低端口罩,高端防护服,低端防护服),而是可以把这些产品进行分组(把产品分为高端组和低端组,不同产品有工厂类的不同方法来创建)。

1.1 创建产品类,口罩和防护服
// 口罩接口和两个实现子类
public interface IMask{void showMask();
}public class HighEndMask implements IMask{@Overridepublic void showMask(){System.out.println("我的高端口罩");}
}public class LowEndMask implements IMask{@Overridepublic void showMask(){System.out.println("我的低端口罩");}
}// 防护服接口和两个实现子类
public interface IProjectiveSuit{void showSuit();
}public class HighEndProjectSuit implements IProjectiveSuit{@Overridepublic void showSuit(){System.out.println("我的高端防护服");}
}public class LowEndProjectSuit implements IProjectiveSuit{@Overridepublic void showSuit(){System.out.println("我的低端防护服");}
}
1.2 工厂类
// 区别在此,工厂方法模式创建 IMaskFactory 接口,分别实现高端口罩与低端口罩两个工厂子类
// 而抽象工厂模式,也是抽象出高端和低端两个工厂子类,在里面实现创建口罩和防护服类的方法
public interface IFactory{void createMask();void createSuit();
}public class HighEndFactory implements IFactory{@Overridepublic IMask createMask(){IMask mask = new HighEndMask();// ...// 100行初始化代码return mask;}@Overridepublic IProjectiveSuit createSuit(){IProjectiveSuit suit = new HighEndProjectSuit();// ...// 100行初始化代码return suit;}
}
public class LowEndFactory implements IFactory{@Overridepublic IMask createMask(){IMask mask = new LowEndMask();// ...// 100行初始化代码return mask;}@Overridepublic IProjectiveSuit createSuit(){IProjectiveSuit suit = new LowEndProjectSuit();// ...// 100行初始化代码return suit;}
}
1.3 使用
public class Test{public void Main(String[]){// 创建工厂IFactory factoryA = new HighEndFactory();IFactory factoryB = new LowEndFactory();// 创建高端口罩,高端防护服IMask maskA = factoryA.createMask();IProjectiveSuit suitA = factoryA.createSuit();// 创建低端口罩,低端防护服IMask maskB = factoryB.createMask();IProjectiveSuit suitB = factoryB.createSuit();// 使用maskA.showMask();maskB.showMask();suitA.showSuit();maskB.showSuit();}
}

参考

设计模式教程
[微信公众号:程序员小灰]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/897910.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

0:c#教程-概述

查看和调试 .net 源码 ildsm 工具查看程序集,SDK 目录下 ilspy 反汇编工具 1.3 C#面向对象编程基础 如何表达信息 --> 选择合适的数据结构 如何处理信息 --> 算法和程序控制结构 如何实现 --> 软件系统架构,面向对象的分析与设计 怎样构造求解问题的算法? 算法,…

2,CSS

CSS盒子模型IE盒模型 border-box width和height是盒子最终的尺寸(添加box-sizing:border-box ) 标准盒模型 content-box width和height只是内容的尺寸(默认)width height background-color border padding margin (box-sizing)CSS布局实践 display 定义了元素生成的显…

Linux使用:Vim常用命令

多文件编辑 操作 c #c 是“修改(change)”(即删除后进入插入模式),后面可以接一个移动命令 cw #删除一个单词并进入插入模式 c2w 或者 2cw #删除两个单词并进入插入模式ctrl + h/w/u #删除前一个字符,前一个单词,前一行w/W #下一个单词开头 e/E # 下一个单词结尾 …

3, Bootstrap 按钮

按钮 按钮样式类背景颜色描述btn btn-default白色带渐变的默认灰色按钮。btn btn-primary深蓝色在一组按钮中的主动作按钮。btn btn-success绿色替代默认按钮。btn btn-info浅蓝色成功或正确的行动。btn btn-warning橙色表明此操作应注意。btn btn-danger红色表示危险或潜在的负…

Linux使用:文件与文件系统的压缩、打包与备份

8.2 Linux系统的压缩指令压缩文件扩展名:*.tar,*.tar.gz,*.tgz,*.gz,*.Z,*.xz 一般需要先用tar将许多文件打包成一个文件,再进行压缩。(因为gzip、bzip2、xz一次只能针对一个文件来压缩和解压缩)。gzip后缀:*.gz 可以解开:compress,zip,gzip压缩的文件(*.Z,*.zip,*.gz) gzip…

服务器上搭建oneindex

更新php 由于需要 php5.6+ 版本,需要从php5.4更新yum provides php #自带的只有5.4版本rpm -Uvh https://mirror.webtatic.com/yum/el7/epel-release.rpm #更新源rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpmyum remove php-common -y #移…

SpringMVC 入门

SpringMVC开发步骤 添加依赖<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://mave…

20241123实验一《python程序设计》实验报告

标题“20241123 实验一《Python程序设计》实验报告” 实验报告模板如下: 20241123 2025.3.12 《Python程序设计》实验一报告 课程:《Python程序设计》 班级: 2411 姓名: 胡钧涛 学号:20241123 实验教师:王志强 实验日期:2025年3月12日 必修/选修: 公选课 1.实验内容 1.…

MySQL的limit优化2

一、底层原理 在 MySQL 8.0 中,当使用 LIMIT offset, count 进行分页查询时,如果 offset 非常大(例如 LIMIT 200000, 10),性能会显著下降。 这是因为 MySQL 需要扫描 offset + count 行数据,然后丢弃前 offset 行,只返回最后的 count 行 二、基本语法与功能LIMIT子句的基…

20242216 2024-2025-2 《Python程序设计》实验一报告

20242126 2024-2025-2 《Python程序设计》实验x报告 课程:《Python程序设计》 班级: 2421 姓名: 邹清楠 学号:20242126 实验教师:王志强 实验日期:2025年3月12日 必修/选修: 公选课 1.实验内容 1.熟悉Python开发环境; 2.练习Python运行、调试技能;(第一次调试时的选…

今日总结(计网以及对Android Studio的进一步学习)

所花时间:130minutes 代码量(行):130 博客量:8 了解的知识点:今天学习了计网的信道复用技术以及对于前一节课的通信系统中涉及的计算问题的复习。 主要为码元与比特的关系,一个码元所携带的比特数 = 1og2x其中x为状态数,比如在计算 中会告诉你状态数,以及码元传输速率…

python公选实验一

20242113《Python程序设计》实验一报告 课程:《Python程序设计》 班级: 2421 姓名: 陈铂翔 学号:20242113 实验教师:王志强 实验日期:2025年3月12日 必修/选修: 公选课 1.实验内容 1.熟悉Python开发环境; 2.练习Python运行、调试技能;(编写书中的程序,并进行调试分…