1.关于上一篇的简单工厂模式
简单工厂模式最大的缺点是当有新产品需要加入到系统中时,必须修改工厂类,需要在其中加入必要的业务落逻辑,违背了开闭原则。且简单工厂模式中所有产品都由同一个工厂创建,工厂类职责较重,业务逻辑较为复杂。
2.工厂模式的定义
(1)工厂模式:定义一个用于创建对象的接口,让子类决定哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。是一种类创建型模式。
(2)工厂方法模式提供一个抽象工厂接口来声明抽象工厂方法,而有其子类来具体实现工厂方法,创建具体的产品对象。
(3)Product(抽象产品)、ConcreteProduct(具体产品)、Factory(抽象工厂)、ConcreteFactory(具体工厂)
3.日志记录器的实现完整解决方案
// 日志记录器接口:抽象产品
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.引入重载方法后,代码的修改如下:
// (1)LoggerFactory修改为
interface LoggerFactory {
public Logger createLogger();
public Logger createLogger(String args);
public Logger createLogger(Object obj);
}
// (2)具体工厂累修改如下
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;
}
5.工厂方法的隐藏
对客户端隐藏工厂方法,工厂类中直接调用产品类的业务方法,客户端无需调用工厂方法来创建产品,直接通过工厂即可使用所创建的对象中的业务方法。
此时,代码修改为:
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(); // 直接使用工厂对象来调用产品对象的业务方法
}
};
6.工厂方法的使用场景
(1)客户端不知道其所需要的对象的类
(2)抽象工厂类通过其子类来指定创建哪个对象