美文网首页
设计模式(2) : 工厂方法模式

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

作者: a_salt_fish | 来源:发表于2019-01-15 22:14 被阅读0次

    定义:

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

    类型:

    创建型(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源码

    相关文章

      网友评论

          本文标题:设计模式(2) : 工厂方法模式

          本文链接:https://www.haomeiwen.com/subject/rcjudqtx.html