登录
/
注册
首页
论坛
其它
首页
科技
业界
安全
程序
广播
Follow
关于
每日签到
每天签到奖励2圆-6圆
发帖说明
VIP申请
登录
/
注册
账号
自动登录
找回密码
密码
登录
立即注册
搜索
搜索
关闭
CSDN热搜
程序园
精品问答
技术交流
资源下载
本版
帖子
用户
软件
问答
教程
代码
写记录
写博客
VIP申请
VIP网盘
网盘
联系我们
每日签到
道具
勋章
任务
设置
我的收藏
退出
腾讯QQ
微信登录
返回列表
首页
›
业界区
›
业界
›
设计模式-工厂方法
设计模式-工厂方法
[ 复制链接 ]
蒙飘
2025-6-6 09:47:47
工厂方法模式
简单工厂的不足
上节的简单工厂,需要拓展时比如修改工厂类,违背了设计模式的开闭原则
简单工厂类直接生成各个子类产品,而工厂方法则有一个抽象工厂类,声明了创建产品的工厂方法,而各个不同的子类产品交由各个不同的具体工厂去完成创建,拓展时,只需要新建一个具体工厂即可,具有更好的灵活性和拓展性
在工厂方法模式中,存在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方法
总结
工厂方法的优点
★ 客户无须关心生成细节和具体产品的类名
★ 良好的
多态性
:创建细节完全封装在具体工厂内
★
易拓展性
:无须修改抽象工厂,新增基于抽象工厂的新具体工厂类即可
工厂方法的缺点
★ 新产品和新具体工厂成对,一定程度上增加了系统复杂性
★ 双重抽象(产品和工厂),一定程度上增加了系统的抽象性和理解难度
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
设计模式
工厂
方法
相关帖子
性能优化之母:为什么说“方法内联”是编译器优化中最关键的一步棋?
性能优化之母:为什么说“方法内联”是编译器优化中最关键的一步棋?
Django 懒加载实现方法
burpsuite_pro_v1.5.01安装方法
向量索引的混合查询方法,你选对了吗?
static 静态方法的特点和作用
指数估值-A股主流指数的估值方法
Linux性能分析工具和方法
设计模式之单例模式
ORA-01720 错误及解决方法
vip免费申请,1年只需15美金$
回复
使用道具
举报
提升卡
置顶卡
沉默卡
喧嚣卡
变色卡
千斤顶
照妖镜
相关推荐
业界
性能优化之母:为什么说“方法内联”是编译器优化中最关键的一步棋?
0
657
悯拄等
2025-08-11
业界
性能优化之母:为什么说“方法内联”是编译器优化中最关键的一步棋?
0
597
蜴间囝
2025-08-11
安全
Django 懒加载实现方法
0
830
处匈跑
2025-08-18
软件
burpsuite_pro_v1.5.01安装方法
0
85
新程序
2025-08-18
科技
向量索引的混合查询方法,你选对了吗?
0
200
后彼
2025-08-19
业界
static 静态方法的特点和作用
0
853
拼匍弦
2025-08-20
安全
指数估值-A股主流指数的估值方法
0
1015
全叶农
2025-08-25
业界
Linux性能分析工具和方法
0
131
眸胝
2025-09-01
安全
设计模式之单例模式
0
77
颖顿庐
2025-09-03
安全
ORA-01720 错误及解决方法
0
789
万妙音
2025-09-04
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
回复
本版积分规则
回帖并转播
回帖后跳转到最后一页
签约作者
程序园优秀签约作者
发帖
蒙飘
2025-6-6 09:47:47
关注
0
粉丝关注
16
主题发布
板块介绍填写区域,请于后台编辑
财富榜{圆}
敖可
9984
杭环
9988
凶契帽
9988
4
氛疵
9988
5
黎瑞芝
9988
6
猷咎
9986
7
里豳朝
9986
8
肿圬后
9986
9
蝓俟佐
9984
10
虽裘侪
9984
查看更多