设计模式之工厂方法模式(附实例代码下载)
工厂方法模式继承了简单工厂模式的优点,还弥补了简单工厂模式的缺陷
工厂方法模式的定义:定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化,工厂方法模式让一个类的实例化延迟到其子类
简而言之就是工厂方法模式有多个子工厂,每个子工厂负责一个产品的生产,这些子工厂都有一个父类:抽象工厂
工厂方法模式包括四个角色:
1)抽象产品
2)具体产品
3)抽象工厂
4)具体工厂
不同的具体工厂可以创建不同的具体产品,当然,在实际使用时,具体工厂类在实现工厂方法时除了创建具体产品对象之外,还可以负责产品对象的初始化工作以及一些资源和环境配置工作,例如连接数据库,创建文件等
可以通过配置文件来储存具体工厂类的类名,再通过反射机制创建具体的工厂对象,这样在更新的具体工厂时无需修改源码,系统扩展更加方便
实例如下:
实例说明:模拟建设一个日志记录器,包括数据库日志记录器,文件日志记录器
1.日志记录器接口 充当抽象产品角色
package 工厂方法模式; /** *@author YB *@version 2019年3月16日下午3:08:18 */ /* * 日志记录器接口 充当抽象产品角色 */ public interface Logger { public void writelog();//接口定义的方法 }
2.数据库日志记录器,充当具体产品角色
package 工厂方法模式; /** *@author YB *@version 2019年3月16日下午3:09:54 */ /* * 数据库日志记录器,充当具体产品角色 */ public class Databaselogger implements Logger { @Override public void writelog() { // TODO Auto-generated method stub System.out.println("数据库日志记录"); } }
3.文件日志记录器,充当具体产品角色
package 工厂方法模式; /** *@author YB *@version 2019年3月16日下午3:11:16 */ /* * 文件日志记录器,充当具体产品角色 */ public class FileLogger implements Logger{ @Override public void writelog() {//实现接口方法 // TODO Auto-generated method stub System.out.println("文件日志记录"); } }
4.日志记录器工厂接口,充当抽象工厂角色
package 工厂方法模式; /** *@author YB *@version 2019年3月16日下午3:13:05 */ /* * 日志记录器工厂接口,充当抽象工厂角色 */ public interface LoggerFactory { public Logger createLogger();//抽象工厂方法 }
5.数据库日志记录器工厂类 充当具体工厂角色
package 工厂方法模式; /** *@author YB *@version 2019年3月16日下午3:14:41 */ /* * 数据库日志记录器工厂类 充当具体工厂角色 */ public class DatabaseLoggerFactory implements LoggerFactory { @Override public Logger createLogger() { // TODO Auto-generated method stub //链接数据库 代码略 Logger logger=new Databaselogger();//创建数据库日志记录器对象 //初始化数据库日志记录器 代码略 return logger; } }
6.文件日志记录器工厂类 充当具体工厂角色
package 工厂方法模式; /** *@author YB *@version 2019年3月16日下午3:16:57 */ /* * 文件日志记录器工厂类 充当具体工厂角色 */ public class FileLoggerFactory implements LoggerFactory{ @Override public Logger createLogger() { // TODO Auto-generated method stub Logger logger=new FileLogger();//创建文件日志记录器对象 //创建文件 代码略 return logger; } }
7.客户端
package 工厂方法模式; /** *@author YB *@version 2019年3月16日下午3:20:06 */ public class Client { public static void main(String[] args) { // TODO Auto-generated method stub LoggerFactory loggerFactory; Logger logger; //loggerFactory=new FileLoggerFactory(); loggerFactory=(LoggerFactory)XMLUtil.getBean();//引入配置文件和反射机制 logger=loggerFactory.createLogger(); logger.writelog(); } }
8.XMLUtil工具类
package 工厂方法模式; import java.io.*; import javax.swing.text.Document; import javax.xml.parsers.*; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.soap.Node; import org.w3c.dom.*; import org.w3c.dom.NodeList; /** *@author YB *@version 2019年3月15日下午7:08:17 */ public class XMLUtil { //该方法用于从XML配置文件中提取图表类型,并返回类型名 public static Object getBean() { try { //创建文档对象 DocumentBuilderFactory dFactory=DocumentBuilderFactory.newInstance(); DocumentBuilder builder=dFactory.newDocumentBuilder(); org.w3c.dom.Document doc; doc=builder.parse(new File("src//工厂方法模式//config.xml")); //获取包含图表类型的文本节点 NodeList nlList= ((org.w3c.dom.Document) doc).getElementsByTagName("className"); org.w3c.dom.Node classNode=nlList.item(0).getFirstChild(); String cName=classNode.getNodeValue(); //通过类名生成实例对象并返回 Class<?> c=Class.forName(cName); Object obj=c.newInstance(); return obj; }catch (Exception e) { // TODO: handle exception e.printStackTrace(); return null; } } }
9.XML配置文件
<?xml version="1.0" encoding="UTF-8"?> <config> <className>工厂方法模式.DatabaseLoggerFactory</className> </config>
抽象工厂方法的重载:
当然,抽象工厂的方法也是可以重载的,在抽象工厂中声明多个重载的工厂方法,在具体工厂中实现了这些工厂方法,这些工厂方法可以包含不同的业务逻辑,以满足产品对象的多样化创建需求
抽象工厂方法的隐藏:
在具体工厂类中直接调用产品类的业务方法,这样在客户端就没有必要调用工厂方法来创建产品对象了,可以直接使用工厂对象即可调用所建产品对象中的业务方法
工厂方法模式是使用频率最该的设计模式之一!!!
优点:
1)工厂方法用来创建客户所需产品,同时还向客户隐藏了那种具体产品类将被实例化这一细节,用户只需关心所需产品对应的工厂,无需关心创建细节,甚至无需知道具体产品的类名
2)基于工厂角色和产品角色的多态性设计是工厂方法模式的关键,他能够让工厂自主确定创建何种产品对象,而如何创建这个对象的细节完全封装在具体工厂的内部,工厂方法模式之所以被称为多态工厂模式,正是因为所有的具体工厂都有同一抽象父类工厂
3)在系统中加入新产品时无需修改抽象工厂和抽象产品提供的接口,无需修改客户端,也无需修改其他具体过程和具体产品,而只要添加一个抽象工厂和抽象产品即可,这样系统的可扩展性将变得非常好,完全符合开闭原则
缺点:
1)添加新产品时需要编写新的具体产品类还有对应的具体工厂类,系统中类的个数会增加,一定程度上增加了系统复杂度或额外开销
2)引入了抽象层,增加了系统的抽象性和理解难度
代码下载:链接:https://share.weiyun.com/5YH0BLz 密码:n8psgd
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南