定义:
定义一个创建对象的接口, 但让实现这个接口的类来决定实例化哪个类, 工厂方法让类的实例化推迟到子类中进行.
类型:
创建型(creational)
场景:
- 创建对象需要大量重复的代码
- 应用层不关系产品类实例化的细节
- 一个类通过其子类来指定创建哪个对象
coding
对上一篇简单工厂模式的代码进行重构,改用工厂方法实现
DBConnection 接口保持不变, 实现类MysqlConnection不变
public interface DBConnection {
String getConnection();
}
public class MysqlConnection implements DBConnection{
@Override
public String getConnection() {
return "Mysql Connection";
}
}
改造简单工厂类DBConnectionFactory
public interface DBConnectionFactory {
DBConnection getConnection();
}
改成一个接口
创建MysqlDBConnection的工厂, 实现工厂接口
public class MysqlConnectionFactory implements DBConnectionFactory{
@Override
public DBConnection getConnection() {
return new MysqlConnection();
}
}
只生产Mysql连接
测试
public class Test {
public static void main(String[] args) {
DBConnectionFactory factory = new MysqlConnectionFactory();
DBConnection connection = factory.getConnection();
System.out.println(connection.getConnection());
// TODO sth
}
}
这时如果需要增加新的数据源Oracle, 只需要新增OracleDBConnetion和它的工厂类,并修改客户端中工厂类的实例类型即可,无需像简单工厂模式那样去修改工厂类中的代码.
public class OracleConnection implements DBConnection{
@Override
public String getConnection() {
return "Oracle Connection";
}
}
public class OracleConnectionFactory implements DBConnectionFactory{
@Override
public DBConnection getConnection() {
return new OracleConnection();
}
}
修改客户端代码
DBConnectionFactory factory = new OracleConnectionFactory();
在实际的应用中, 工厂类一般都是注册成bean由Spring注入的,所以实际上客户端只需修改Spring配置文件或配置类即可, 对业务代码不产生任何影响.
JDK源码中的应用
JDK中的Collection 与其实现类中的Iterator的实现就应用了这种模式
Iterator 接口 是实际要生产的产品, 承担着上述例子中DBConnection的角色
Collection 在这个模式中承担着上述例子中DBConnectionFactory的角色, 它提供了一个获取迭代器的接口.
Iterator<E> iterator();
Collection 有很多实现类,他们各自实现了iterator()接口, 如常用的ArrayList (相当于 MysqlConnetionFactory)
其中
public Iterator<E> iterator() {
return new Itr();
}
ArrayList.Itr 是一个内部类,实现了Iterator接口, 相当于MysqlConnection.
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
public boolean hasNext() {
return cursor != size;
}
......
}
其他Collection 的实现类也各自实现了 Iterator<E> iterator() 接口, 这里就不一一贴出,如果有兴趣可以自行研究.
优点:
- 应用层不关心产品类实例化的细节(与简单工厂模式优点相似,但避免了简单工厂模式需扩展时需要修改工厂类的问题)
缺点:
- 增加了系统的抽象性和类的个数.
网友评论