设计模式(2) : 工厂方法模式

2019-01-15  本文已影响0人  a_salt_fish

定义:

定义一个创建对象的接口, 但让实现这个接口的类来决定实例化哪个类, 工厂方法让类的实例化推迟到子类中进行.

类型:

创建型(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() 接口, 这里就不一一贴出,如果有兴趣可以自行研究.


优点:

缺点:

github源码

上一篇 下一篇

猜你喜欢

热点阅读