工厂方法源码解析(jdk+logback)
我们来看一下Collection,这个类大家都比较熟悉,public interface Collection extends Iterable {是集合类,例如在这个接口中定义的Iterator接口,Iterator iterator();这个方法就是一个工厂方法,Collection可以理解成一个抽象工厂,那在后面讲抽象工厂的时候呢,我们再重点关注抽象工厂,而现在我们只关注工厂方法,工厂方法这个词可以理解为作为工厂的一个方法,而Iterator这个方法呢,正是作为工厂的一个方法,这是一个接口,接口里面的一个方法,那他有很多实现类,例如ArrayList这里边,对于iterator()方法的一个实现public Iterator iterator() {return new Itr();
}这里面只用了一个内部类来实现,private class Itr implements Iterator 就是这个,这里面就是全交由子类来实现了,使用不同工厂类中的iterator方法能够得到不同的具体产品的实例,我们可以认为ArrayList在这里边是一个具体的实现工厂,他呢实现了这个工厂方法,而具体的抽象产品呢,又是Iterator这么一个接口,public interface Iterator 具体抽象产品已经找到,那实际生产出来的产品呢,那就是ArrayList里面的Itr对象,private class Itr implements Iterator这个就是具体的产品,他实现了Iterator接口,然后这里边写这么一个实现,同时在具体的工厂里面,返回了具体的产品,这个产品也就是说Iterator抽象产品的一个实例,我们可以类比来看,Collection相当于我们里面的VideoFactory,ArrayList就相当于具体的实现工厂,例如JavaVideoFactory,PathonVideoFactory,而抽象产品,就是Iterator这么一个产品,而在我们的课程当中,就是Video这么一个抽象类,它是一个抽象产品,然后实际的具体产品就是ArrayList里面的Itr这么一个类,他实现了抽象产品,那Itr对应我们工厂里面的,就是JavaVideo,PathonVideo,或者FEVideo,那我们看一下,Itr这么一个类图

抽象产品,具体的ArrayList Itr实际的产品,而这个类是和ArrayList是有依赖关系的,也就是说ArrayList依赖他,因为Itr作为iterator方法的一个返回值,也就是说这个Itr类型虽然是Iterator这个接口类型,但是它是一个具体的产品,public Iterator iterator() {return new Itr();
}private class Itr implements Iterator例如这里可以看出来,那我们来看一下ArrayList的一个类图

从这里面就可以看出来,ArrayList实现的一个接口,以及和其他抽象类的一个关系,那我们重点来关注一个方法,我们看一下ArrayList的方法,我们找到iterator这么一个方法,也就是说ArrayList中的iterator方法

我们可以人工的看一下他们之间的关系,通过里面的类实现,他们之间的关系,所以这个就是一个工厂方法,在JDK重要的体现,那我们现在看另外一个类,public interface URLStreamHandlerFactory 这样一个类,首先它是一个接口,这个类在JDK里面主要是解决URL协议扩展使用的,这里面的protocol也就决定了交互规范,例如HTTP FILE,https,这些呢都是协议,那我们现在来理解一下,很明显它是一个工厂,并且这个工厂里面只有一个方法public interface URLStreamHandlerFactory {/*** Creates a new {@code URLStreamHandler} instance with the specified* protocol.** @param protocol the protocol ("{@code ftp}",* "{@code http}", "{@code nntp}", etc.).* @return a {@code URLStreamHandler} for the specific protocol.* @see java.net.URLStreamHandler*/URLStreamHandler createURLStreamHandler(String protocol);
}之前也说了,无法具体描述的话,我们使用抽象类和抽象方法也可以,使用一个接口和一个方法命名,也是OK的,那么我们来看看他的具体实现,Launcher Factory createURLStreamHandlerprivate static class Factory implements URLStreamHandlerFactory {private static String PREFIX = "sun.net.www.protocol";private Factory() {}public URLStreamHandler createURLStreamHandler(String var1) {String var2 = PREFIX + "." + var1 + ".Handler";try {Class var3 = Class.forName(var2);return (URLStreamHandler)var3.newInstance();} catch (ReflectiveOperationException var4) {throw new InternalError("could not load " + var1 + "system protocol handler", var4);}}
}这个Factory是一个静态类,实现了URLStreamHandlerFactory,这里面定义了一个前缀,这个前缀就是给具体的类使用的,比如说这个是一个包名,然后点,再加上var1,然后.Handler,为什么点Handler呢,以后我们来看一下,Class.forName,newInstance,来找到具体的产品,那前面我们讲简单工厂的时候,通过Class.forName,对简单工厂进行了一个扩展,我们看一下他的返回值是URLStreamHandler,而这个类呢如果实现工厂的话,可以大胆猜测一下,他会不会是一个抽象类呢,或者说作为很多类的一个父类,我们点进来看一下,URLStreamHandler他是一个抽象类

然后下边有openConnection,是一个比较主要的方法

既然他返回的是一个抽象类public abstract class URLStreamHandler {/*** Opens a connection to the object referenced by the* {@code URL} argument.* This method should be overridden by a subclass.** If for the handler's protocol (such as HTTP or JAR), there* exists a public, specialized URLConnection subclass belonging* to one of the following packages or one of their subpackages:* java.lang, java.io, java.util, java.net, the connection* returned will be of that subclass. For example, for HTTP an* HttpURLConnection will be returned, and for JAR a* JarURLConnection will be returned.** @param u the URL that this connects to.* @return a {@code URLConnection} object for the {@code URL}.* @exception IOException if an I/O error occurs while opening the* connection.*/abstract protected URLConnection openConnection(URL u) throws IOException;他肯定是由子类来实现他的,这里面有N多Handler,有deploy发布包下面的

下面还有具体的协议,protocol.file协议,ftp协议,http,https,mial各种协议

我们先进入http的Handler

这个Handler直接继承了这个抽象类,那这个Handler里边啊,openConnection方法抽象方法,并且它是一个protected,所以子类必须会实现他,也就是说openConnection,这个是http包下面的Handler,那我们再看一下其他的实现类,例如有一个https的

它是间接继承,这个handler我们进来

继承下一个Handler,再进来

这样Handler继承了URLStreamHandler,这个factory里面继承了这个

public interface URLStreamHandlerFactory {/*** Creates a new {@code URLStreamHandler} instance with the specified* protocol.** @param protocol the protocol ("{@code ftp}",* "{@code http}", "{@code nntp}", etc.).* @return a {@code URLStreamHandler} for the specific protocol.* @see java.net.URLStreamHandler*/URLStreamHandler createURLStreamHandler(String protocol);
}里面提供了工厂方法,而createURLStreamHandler这个工厂方法的实现

里面通过Class.forName来获取对象,而具体对象就是URLStreamFactory很多实现的一个子类

那我们现在来对应一下,URLStreamHandler对应我们的Video,这个是抽象的产品,而这些都是具体的产品,URLStreamHandlerFactory,对应的就是VideoFactory,这里面提供了一个方法,而这个方法createURLStreamHandler具体的实现呢,交由他的子类,Launcher这个类来实现的

而具体这个方法的实现,也就是这个工厂的实现public interface URLStreamHandlerFactory {/*** Creates a new {@code URLStreamHandler} instance with the specified* protocol.** @param protocol the protocol ("{@code ftp}",* "{@code http}", "{@code nntp}", etc.).* @return a {@code URLStreamHandler} for the specific protocol.* @see java.net.URLStreamHandler*/URLStreamHandler createURLStreamHandler(String protocol);
}就是使用Factory这么一个类

他实现了URLStreamHandlerFactory,这个Factory就相当于我们的JavaVideoFactory,PythonVideFactory,所以工厂方法所在的类,还有具体的创建者,还有抽象的产品,和具体的产品,我们都找到了,那这一部分也是工厂方法,在JDK中的一个重要体现,我们再看logback中的一些应用public interface ILoggerFactory {/*** Return an appropriate {@link Logger} instance as specified by the* name parameter.* * If the name parameter is equal to {@link Logger#ROOT_LOGGER_NAME}, that is * the string value "ROOT" (case insensitive), then the root logger of the * underlying logging system is returned.* *
Null-valued name arguments are considered invalid.**
Certain extremely simple logging systems, e.g. NOP, may always* return the same logger instance regardless of the requested name.* * @param name the name of the Logger to return* @return a Logger instance */public Logger getLogger(String name);
}这个接口下边只有一个方法,我们看一下他的实现,在这三个类中

也就是把这个抽象方法教给子类来实现,我们来看一下类图

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
