这几天学到java.net包中的一些类,这三个的关系感觉和设计模式不太清楚。在此写写自己的看法,顺便整理下自己的思路。
其中,可以肯定的是:SocketImpl是其中的核心,抽象出了对socket操作所需要的所有方法和字段,例如:connect(),accept(),getInputStream()等。它的子类是真正操作运输层数据的对象。先看下它的类结构图:
AbstractPlainSocketImpl定义了默认的Socket实现,也是抽象类。这就有个问题了:这两个都是抽象类,而且SocketImpl的直接子类只有AbstractPlainSocketImpl一个,那么为什么不合并在一起呢?
其次,Socket是把SocketImpl包装起来,如同ServerSocket,DatagramSocket,***Socket一样。——这可能是一个适配器设计模式,不同的Socket可以用的是同一个SocketImpl,但通过自己的***Socket类构建出适合自己的类。他们都包含一个SocketImpl的子类对象,而且他们的方法都是调用SocketImpl中的方法。这点,可以从源码看出,构造时就是实例化一个SocketImpl:
1 public Socket() {2 setImpl();3 }
关闭就是在关闭SocketImpl:
public synchronized void close() throws IOException { synchronized(closeLock) { if (isClosed()) return; if (created) impl.close(); closed = true; } }
最后,从setImpl()中能看出,SocketImplFactory的作用:
1 void setImpl() { 2 if (factory != null) { 3 impl = factory.createSocketImpl(); 4 checkOldImpl(); 5 } else { 6 // No need to do a checkOldImpl() here, we know it's an up to date 7 // SocketImpl! 8 impl = new SocksSocketImpl(); 9 }10 if (impl != null)11 impl.setSocket(this);12 }
SocketImplFactory就是创建SocketImpl的。但一般都用默认的SocketImpl,所以就用不到SocketImplFactory。且他是使用了工厂方法设计模式,通过实现createSocketImpl()方法来返回一个SocketImpl,这样就封装了创建部分的变化。
总结一下,就是SocketImpl是实现运输层操作的抽象类。Socket、ServerSocket等封装了SocketImpl,以适应不同的操作。SocketImplFactory就是使用了工厂方法来创建SocketImpl。
PS:InetAddress类也用的是工厂方法设计模式,把创建这块的变化给封装起来的确实很好!