工厂方法模式
工厂方法模式提供一个抽象工厂接口来声明抽象工厂方法,而由其子类来具体实现工厂方法,创建具体的产品对象。
开发人员决定使用工厂方法模式来设计日志记录器,其基本结构如图3所示:
图3 日志记录器结构图
在图3中,Logger接口充当抽象产品,其子类FileLogger和DatabaseLogger充当具体产品,LoggerFactory接口充当抽象工厂,其子类FileLoggerFactory和DatabaseLoggerFactory充当具体工厂。完整代码如下所示:
//日志记录器接口:抽象产品 interface Logger { public void writeLog(); } //数据库日志记录器:具体产品 class DatabaseLogger implements Logger { public void writeLog() { System.out.println("数据库日志记录。"); } } //文件日志记录器:具体产品 class FileLogger implements Logger { public void writeLog() { System.out.println("文件日志记录。"); } } //日志记录器工厂接口:抽象工厂 interface LoggerFactory { public Logger createLogger(); } //数据库日志记录器工厂类:具体工厂 class DatabaseLoggerFactory implements LoggerFactory { public Logger createLogger() { //连接数据库,代码省略 //创建数据库日志记录器对象 Logger logger = new DatabaseLogger(); //初始化数据库日志记录器,代码省略 return logger; } } //文件日志记录器工厂类:具体工厂 class FileLoggerFactory implements LoggerFactory { public Logger createLogger() { //创建文件日志记录器对象 Logger logger = new FileLogger(); //创建文件,代码省略 return logger; } }
编写如下客户端测试代码:
class Client { public static void main(String args[]) { LoggerFactory factory; Logger logger; factory = new FileLoggerFactory(); //可引入配置文件实现 logger = factory.createLogger(); logger.writeLog(); } }
编译并运行程序,输出结果如下:
文件日志记录。
重载的工厂方法
图4 重载的工厂方法结构图
引入重载方法后,抽象工厂LoggerFactory的代码修改如下:
interface LoggerFactory { public Logger createLogger(); public Logger createLogger(String args); public Logger createLogger(Object obj); }
具体工厂类DatabaseLoggerFactory代码修改如下:
class DatabaseLoggerFactory implements LoggerFactory { public Logger createLogger() { //使用默认方式连接数据库,代码省略 Logger logger = new DatabaseLogger(); //初始化数据库日志记录器,代码省略 return logger; } public Logger createLogger(String args) { //使用参数args作为连接字符串来连接数据库,代码省略 Logger logger = new DatabaseLogger(); //初始化数据库日志记录器,代码省略 return logger; } public Logger createLogger(Object obj) { //使用封装在参数obj中的连接字符串来连接数据库,代码省略 Logger logger = new DatabaseLogger(); //使用封装在参数obj中的数据来初始化数据库日志记录器,代码省略 return logger; } }
在抽象工厂中定义多个重载的工厂方法,在具体工厂中实现了这些工厂方法,这些方法可以包含不同的业务逻辑,以满足对不同产品对象的需求。
6 工厂方法的隐藏
如果对客户端隐藏工厂方法,日志记录器的结构图将修改为图5所示:
图5 隐藏工厂方法后的日志记录器结构图
在图5中,抽象工厂类LoggerFactory的代码修改如下:
//改为抽象类 abstract class LoggerFactory { //在工厂类中直接调用日志记录器类的业务方法writeLog() public void writeLog() { Logger logger = this.createLogger(); logger.writeLog(); } public abstract Logger createLogger(); }
客户端代码修改如下:
class Client { public static void main(String args[]) { LoggerFactory factory; factory = (LoggerFactory)XMLUtil.getBean(); factory.writeLog(); //直接使用工厂对象来调用产品对象的业务方法 } }
note:
1.抽象工厂类中添加writeLog();
2.在XML中配置所需具体工厂类