登录
/
注册
首页
论坛
其它
首页
科技
业界
安全
程序
广播
Follow
关于
导读
排行榜
发帖说明
登录
/
注册
账号
自动登录
找回密码
密码
登录
立即注册
搜索
搜索
关闭
CSDN热搜
程序园
精品问答
技术交流
资源下载
本版
帖子
用户
软件
问答
教程
代码
写记录
写博客
小组
VIP申请
VIP网盘
网盘
联系我们
发帖说明
道具
勋章
任务
淘帖
动态
分享
留言板
导读
设置
我的收藏
退出
腾讯QQ
微信登录
返回列表
首页
›
业界区
›
业界
›
设计模式-工厂方法
设计模式-工厂方法
[ 复制链接 ]
蒙飘
2025-6-6 09:47:47
程序园永久vip申请,500美金$,无限下载程序园所有程序/软件/数据/等
工厂方法模式
简单工厂的不足
上节的简单工厂,需要拓展时比如修改工厂类,违背了设计模式的开闭原则
简单工厂类直接生成各个子类产品,而工厂方法则有一个抽象工厂类,声明了创建产品的工厂方法,而各个不同的子类产品交由各个不同的具体工厂去完成创建,拓展时,只需要新建一个具体工厂即可,具有更好的灵活性和拓展性
在工厂方法模式中,存在4个角色:
抽象产品
具体产品
抽象工厂
声明了创建产品的抽象方法,返回抽象产品,由具体工厂去实现创建具体产品的方法
具体工厂
实现创建产品的抽象方法,创建并返回某一种具体产品
工厂方法模式下的多日志工厂
Log(抽象产品)
抽象Log声明了一个记录日志的方法
package com.example.fxfactory.model;
import java.io.IOException;
public abstract class Log {
public abstract void doLog() throws IOException;
}
复制代码
ConsoleLog(具体产品)
Log的具体类,控制台日志,它将doLog重写为在控制台打印日志信息
package com.example.fxfactory.model;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ConsoleLog extends Log{
@Override
public void doLog() {
Date date = new Date();
SimpleDateFormat pattern = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str = pattern.format(date) + " console log";
System.out.println(str);
}
}
复制代码
FileLog(具体产品)
Log的另一个具体类,文件日志,它将doLog重写为记录日志到filelog.txt文件中去
package com.example.fxfactory.model;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class FileLog extends Log {
@Override
public void doLog() throws IOException {
File dir = new File("./log");
if (!dir.exists()) {
dir.mkdirs();
}
File checkFile = new File("./log","filelog.txt");
FileWriter writer = null;
try {
if (!checkFile.exists()) {
checkFile.createNewFile();
}
writer = new FileWriter(checkFile, true);
Date date = new Date();
SimpleDateFormat pattern = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str = pattern.format(date) + " file log";
writer.append(str);
writer.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != writer)
writer.close();
}
}
}
复制代码
LogFactory(抽象工厂)
抽象的日志工厂,声明了一个创建日志的方法,返回类型为抽象的日志
package com.example.fxfactory.factory;
import com.example.fxfactory.model.Log;
public abstract class LogFactory {
public abstract Log createLog();
}
复制代码
ConsoleLogFactory(具体工厂)
控制台日志工厂,重写创建日志方法,返回一个控制台日志实例
package com.example.fxfactory.factory;
import com.example.fxfactory.model.ConsoleLog;
import com.example.fxfactory.model.Log;
public class ConsoleLogFactory extends LogFactory {
@Override
public Log createLog() {
return new ConsoleLog();
}
}
复制代码
FileLogFactory(具体工厂)
文件日志工厂,重写创建日志方法,返回一个文件日志实例
package com.example.fxfactory.factory;
import com.example.fxfactory.model.FileLog;
import com.example.fxfactory.model.Log;
public class FileLogFactory extends LogFactory {
@Override
public Log createLog() {
return new FileLog();
}
}
复制代码
测试
Main.java
package com.example.fxfactory;
import com.example.fxfactory.factory.ConsoleLogFactory;
import com.example.fxfactory.factory.FileLogFactory;
import com.example.fxfactory.factory.LogFactory;
import com.example.fxfactory.model.Log;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
LogFactory logFactory = new ConsoleLogFactory();
Log consoleLog = logFactory.createLog();
consoleLog.doLog();
logFactory = new FileLogFactory();
Log fileLog = logFactory.createLog();
fileLog.doLog();
}
}
复制代码
看起来,我们似乎并不需要LogFactory,直接创建2个不同的具体Factory不也行吗?那我们尝试换一种写法:
空工厂
抽象工厂换为一个空工厂,createLog方法返回null,新增一个切换到具体工厂的方法,接收具体工厂名,将自己变为指定的具体工厂
package com.example.fxfactory.factory;
import com.example.fxfactory.model.Log;
public class LogFactory {
public LogFactory siwtch(String logType){
switch (logType){
case "console":{
return new ConsoleLogFactory();
}
case "file":{
return new FileLogFactory();
}
default:{
return this;
}
}
}
public Log createLog(){
return null;
}
}
复制代码
测试
Main.java
LogFactory logFactory = new LogFactory();
logFactory = logFactory.siwtch("console");
Log consoleLog = logFactory.createLog();
consoleLog.doLog();
logFactory = logFactory.siwtch("file");
Log fileLog = logFactory.createLog();
fileLog.doLog();
复制代码
现在我们不需要知道具体工厂类了,只需要知道用于指定它们的名字就行。不过要拓展新的具体工厂,还需要维护空工厂的switch方法
总结
工厂方法的优点
★ 客户无须关心生成细节和具体产品的类名
★ 良好的
多态性
:创建细节完全封装在具体工厂内
★
易拓展性
:无须修改抽象工厂,新增基于抽象工厂的新具体工厂类即可
工厂方法的缺点
★ 新产品和新具体工厂成对,一定程度上增加了系统复杂性
★ 双重抽象(产品和工厂),一定程度上增加了系统的抽象性和理解难度
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
设计模式
工厂
方法
相关帖子
解析设计模式与设计原则:构建可维护性和可扩展性代码的重要性
C#扩展方法或.net扩展方法
【EF Core】FromExpression 方法有什么用?
关于2233看板娘的配置方法
VonaJS AOP编程:魔术方法
笔记:不同进制的转换方法
Go语言实现GoF设计模式:适配器模式
告别盲人摸象,数据分析的抽样方法总结
使用ai的方法给epub文件中的汉字加拼音
在java中实现c#的int.TryParse方法
回复
使用道具
举报
提升卡
置顶卡
沉默卡
喧嚣卡
变色卡
千斤顶
照妖镜
相关推荐
安全
解析设计模式与设计原则:构建可维护性和可扩展性代码的重要性
2
533
涂流如
2025-10-11
安全
C#扩展方法或.net扩展方法
2
113
邹语彤
2025-10-14
业界
【EF Core】FromExpression 方法有什么用?
1
304
瞪皱炕
2025-10-14
业界
关于2233看板娘的配置方法
3
581
吕梓美
2025-10-18
业界
VonaJS AOP编程:魔术方法
4
358
喝岖
2025-10-23
安全
笔记:不同进制的转换方法
1
297
甘子萱
2025-11-08
安全
Go语言实现GoF设计模式:适配器模式
0
478
柩通奉
2025-11-19
业界
告别盲人摸象,数据分析的抽样方法总结
0
279
曲愍糙
2025-11-29
业界
使用ai的方法给epub文件中的汉字加拼音
0
232
叶芷雁
2025-12-08
安全
在java中实现c#的int.TryParse方法
0
794
歇凛尾
2025-12-09
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
回复
本版积分规则
回帖并转播
回帖后跳转到最后一页
签约作者
程序园优秀签约作者
发帖
蒙飘
2025-6-6 09:47:47
关注
0
粉丝关注
19
主题发布
板块介绍填写区域,请于后台编辑
财富榜{圆}
anyue1937
9994893
kk14977
6845356
3934307807
991122
4
xiangqian
638210
5
宋子
9985
6
闰咄阅
9991
7
刎唇
9993
8
俞瑛瑶
9998
9
蓬森莉
9951
10
匝抽
9986
查看更多