网站首页 > 技术文章 正文
工厂模式的实现主要分为三种,分别是简单工厂模式(Simple Factory)、工厂方法模式(Factory Method)和抽象工厂模式(Abastract Factory );但是简单工厂模式不属于23种GOF设计模式之一。工厂模式在各种开源框架里使用非常普遍,例如Spring框架大量使用工程模式。下面分别介绍一下这三种实现。
0x01: 简单工厂模式
简单工厂模式也被称为静态工厂模式;简单工厂模式可以将产品的使用和生产完全分开,客户端只需要知道需要什么产品,如何来使用产品就可以了,而具体的产品生产任务由具体的工厂类来实现。工厂类根据传进来的参数生产具体的产品供消费者使用。这种模式使得更加利于扩展,当有新的产品加入时仅仅需要在工厂中加入新产品的构造就可以了。类图如下
简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。该模式中包含的角色及其职责:
- 工厂(Creator)角色:简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法可以被外界直接调用,创建所需的产品对象。
- 抽象产品(IProduct)角色:简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
- 具体产品(Concrete Product)角色:是简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。
抽象产品(IProduct)角色
public interface IFruit {
/**
* 种植水果方法
*/
void plant();
}
抽象产品(IProduct)角色
//实现种植苹果
public class Apple implements IFruit {
public void plant() {
System.out.println("种植苹果");
}
}
//实现种植橙子
public class Orange implements IFruit {
public void plant() {
System.out.println("种植橙子");
}
}
具体产品(Concrete Product)角色
public class PlantFruitsFactory {
public static IFruit plantFruit(String fruitType) {
//这里使用的if判断,用switch一样的道理
if ("Apple".equals(fruitType)){
return new Apple();
}else if ("Orange".equals(fruitType)){
return new Orange();
}else {
return null;
}
}
}
测试用例
public class ClientCmd{
public static void main(String[] args) {
IFruit fruit = PlantFruitsFactory.plantFruit("Apple");
fruit.plant();
fruit = PlantFruitsFactory.plantFruit("Orange");
fruit.plant();
}
}
0x02: 工厂方法模式
工厂方法(Factory Method)模式的定义是一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅是负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。类图如下:
- 抽象工厂(Creator)角色:是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。
- 具体工厂(Concrete Creator)角色:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程序调用以创建产品对象。
- 抽象产品(Product)角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。
- 具体产品(Concrete Product)角色:该角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应。
抽象产品(Product)角色
//抽象产品类
public abstract class IMessage{
//抽象产品方法
public void send();
}
具体产品(Concrete Product)角色
//继承抽象类实现产品EmailMessage类
public class EmailMessage extends IMessage{
//实现抽象产品方法
@Overide
public void send(){
System.out.println("send Email Message~~");
}
}
//继承抽象类实现产品SmsMessage类
public class SmsMessage extends IMessage{
//实现抽象产品方法
@Overide
public void send(){
System.out.println("send Sms Message ~~~ ");
}
}
抽象工厂(Creator)角色
//工厂抽象类
public abstract class Factory {
//抽象工厂方法
public abstract IMessage createMessage();
}
具体工厂(Concrete Creator)角色
//具体工厂类EmailMessageFactory
public class EmailMessageFactory extends Factory {
@Overide
public IMessage createMessage() {
System.out.println("生产了一个EmailMessage ");
return new EmailMessage();
}
}
//具体工厂类SmsMessageFactory
public class SmsMessageFactory extends Factory {
@Overide
public IMessage createMessage() {
System.out.println("生产了一个SmsMessage");
return new SmsMessage();
}
}
测试用例
//调用方代码
public class ClientCmd {
public static void main(String[] args) {
//产生一个Email工厂
Factory factory = new EmailMessageFactory();
factory .createMessage().send();
//产生一个短信工厂
factory = new SmsMessageFactory();
orangeFactory.createMessage().send();
}
}
0x03: 抽象工厂模式
抽象工厂模式相对于工厂方法模式来说,就是工厂方法模式是针对一个产品系列的,而抽象工厂模式是针对多个产品系列的,即工厂方法模式是一个产品系列一个工厂类,而抽象工厂模式是多个产品系列一个工厂类。在抽象工厂模式中,客户端不再负责对象的创建,而是把这个责任丢给了具体的工厂类,客户端只负责对对象的调用,从而明确了各个类的职责。并且当一系列相互关联的产品被设计到一个工厂类里后,客户端的调用将会变得非常简单,而且如果要更换这一系列的产品,则只需要更换一个工厂类即可。类图如下
抽象工厂模式中存在四种角色,分别是抽象工厂角色,具体工厂角色,抽象产品角色,具体产品角色。
- 抽象工厂角色:担任这个角色的是工厂方法模式的核心,它是与应用系统商业逻辑无关的。
- 具体工厂角色:这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。
- 抽象产品角色:担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。
- 具体产品角色:抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部充满了应用系统的商业逻辑。
抽象产品角色
//抽象形状类
public abstract class Shape {
public abstract void sayShape();
}
//抽象颜色类
public abstract class Color {
public abstract void sayColor();
}
具体产品角色
//矩形类
public class Retangle extends Shape {
@Overide
public void sayShape() {
System.out.println("Hi, I'm Retangle!");
}
}
//圆形类
public class Circle extends Shape {
@Overide
public void sayShape() {
System.out.println("Hi, I'm Circle!");
}
}
//红色类
public class Red extends Color {
@Overide
public void sayColor() {
System.out.println("Hi, I'm Red!");
}
}
//白色类
public class White extends Color {
@Overide
public void sayColor() {
System.out.println("Hi, I'm White!");
}
}
抽象工厂角色
//抽象工厂类
public abstract class ShapeFactory {
public abstract Shape createShape();
public abstract Color createColor();
}
具体工厂角色
//红色的圆
public class RedCircleFactory extends ShapeFactory {
@Overide
public Shape createShape() {
return new Circle();
}
@Overide
public Color createColor() {
return new Red();
}
}
//白色的圆
public class WhiteCircleFactory extends ShapeFactory {
@Overide
public Shape createShape() {
return new Circle();
}
@Overide
public Color createColor() {
return new White();
}
}
测试用例
public class ClientCmd {
public static void main(String[] args){
//红色的圆
ShapeFactory factory = new RedCircleFactory();
factory.createShape().sayShape();
factory.createColor().sayShapeColor();
//白色的圆
ShapeFactory factory = new WhiteCircleFactory();
factory.createShape().sayShape();
factory.createColor().sayShapeColor();
}
}
猜你喜欢
- 2024-12-19 C++的23种设计模式(上篇-创建型模式)
- 2024-12-19 25000 字详解 23 种设计模式(多图 + 代码)
- 2024-12-19 开源的的二维绘图引擎,EChart在用的图形渲染器——ZRender
- 2024-12-19 手机拍大片诀窍记心间 掌上PS应用合集
- 2024-12-19 搞科研常用技能和绘图学习 科研绘图工具
- 2024-12-19 「服装小知识」服装各部位名称学习(中英对照)
- 2024-12-19 10分钟教你如何看懂GIA证书 怎么看gia证书的详细信息
- 2024-12-19 图片四个角怎么能做成圆弧角?这几种制作方法操作起来很简单!
- 2024-12-19 苹果梨篇:大庙香水梨 大香水梨品种介绍
- 2024-12-19 教你用OpenCV 和 Python实现圆物检测
- 1507℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 505℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 484℃MySQL service启动脚本浅析(r12笔记第59天)
- 465℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 462℃启用MySQL查询缓存(mysql8.0查询缓存)
- 442℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 422℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 418℃MySQL server PID file could not be found!失败
- 最近发表
-
- netty系列之:搭建HTTP上传文件服务器
- 让deepseek教我将deepseek接入word
- 前端大文件分片上传断点续传(前端大文件分片上传断点续传怎么操作)
- POST 为什么会发送两次请求?(post+为什么会发送两次请求?怎么回答)
- Jmeter之HTTP请求与响应(jmeter运行http请求没反应)
- WAF-Bypass之SQL注入绕过思路总结
- 用户疯狂点击上传按钮,如何确保只有一个上传任务在执行?
- 二 计算机网络 前端学习 物理层 链路层 网络层 传输层 应用层 HTTP
- HTTP请求的完全过程(http请求的基本过程)
- dart系列之:浏览器中的舞者,用dart发送HTTP请求
- 标签列表
-
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- chromepost (65)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- linux删除一个文件夹 (65)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)