本节举例说明Abstract Factory在Android源码中的体现。
abstract factory是对象的创建型模式。这种设计模式在Android中运用相当广泛。现仅仅以Android平台JVM的DatagramSocket的实现为例来介绍之。
DatagramSocket是一个实现了UDP socket的类。
相关代码:
//接口的定义
1). SocketOptions.java:
public interface SocketOptions { ...}
//抽象类的定义,必须实现接口SocketOptions
2). DatagramSocketImpl.java:
public abstract class DatagramSocketImpl implements SocketOptions { ...}
//抽象类的定义,必须实现接口SocketOptions
3). SocketImpl.java:
public abstract class SocketImpl implements SocketOptions { ...}
//抽象工厂接口的定义
4. DatagramSocketImplFactory.java:
public interface DatagramSocketImplFactory {
DatagramSocketImpl createDatagramSocketImpl();
}
//抽象工厂接口的定义
5). SocketImplFactory.java
public interface SocketImplFactory {
SocketImpl createSocketImpl();
}
//DatagramSocket类的定义
6). DatagramSocket.java
public class DatagramSocket implements Closeable {
DatagramSocketImpl impl;
InetAddress address;
int port = -1;
static DatagramSocketImplFactory factory;
......
//创建socket
synchronized void createSocket(int aPort, InetAddress addr) throws SocketException {
impl = factory != null ? factory.createDatagramSocketImpl()
: new PlainDatagramSocketImpl();
impl.create();
try {
impl.bind(aPort, addr);
isBound = true;
} catch (SocketException e) {
close();
throw e;
}
}
//构造函数
public DatagramSocket(int aPort) throws SocketException {
checkPort(aPort);
createSocket(aPort, Inet4Address.ANY);
}
////构造函数
public DatagramSocket(int aPort, InetAddress addr) throws SocketException {
checkPort(aPort);
createSocket(aPort, (addr == null) ? Inet4Address.ANY : addr);
}
......
}
简要说明:
从各个类名字的命名就可以看出来,这是典型的abstract factory模式。这里,DatagramSocket就是client。
应用程序通过new DatagramSocket来创建一个Socket。 在DatagramSocket的构造函数中,依次调用
createSocket ,而在这个函数中,会new PlainDatagramSocketImpl。
synchronized void createSocket(int aPort, InetAddress addr) throws SocketException {
impl = factory != null ? factory.createDatagramSocketImpl()
: new PlainDatagramSocketImpl();
impl.create();
try {
impl.bind(aPort, addr);
isBound = true;
} catch (SocketException e) {
close();
throw e;
}
}
PlainDatagramSocketImpl的源码如下:
public class PlainDatagramSocketImpl extends DatagramSocketImpl {
......
//构造函数
public PlainDatagramSocketImpl(FileDescriptor fd, int localPort) {
this.fd = fd;
this.localPort = localPort;
if (fd.valid()) {
guard.open("close");
}
}
//构造函数
public PlainDatagramSocketImpl() {
fd = new FileDescriptor();
}
//绑定
@Override public void bind(int port, InetAddress address) throws SocketException {
......
}
@Override
protected void onBind(InetAddress localAddress, int localPort) {
this.localPort = localPort;
}
//关闭Socket
@Override
public synchronized void close() {
guard.close();
try {
IoBridge.closeAndSignalBlockedThreads(fd);
} catch (IOException ignored) {
}
}
@Override
protected void onClose() {
guard.close();
}
//创建
@Override
public void create() throws SocketException {
this.fd = IoBridge.socket(false);
}
//接收
@Override
public void receive(DatagramPacket pack) throws IOException {
doRecv(pack, 0);
}
//发送
@Override
public void send(DatagramPacket packet) throws IOException {
int port = isNativeConnected ? 0 : packet.getPort();
InetAddress address = isNativeConnected ? null : packet.getAddress();
IoBridge.sendto(fd, packet.getData(), packet.getOffset(), packet.getLength(), 0, address,
port);
}
//连接
@Override
public void connect(InetAddress inetAddr, int port) throws SocketException {
......
}
@Override
protected void onConnect(InetAddress remoteAddress, int remotePort) {
isNativeConnected = true;
connectedAddress = remoteAddress;
connectedPort = remotePort;
}
//断开
@Override
public void disconnect() {
......
}
......
}
PlainDatagramSocketImpl是DatagramSocketImpl的具体类,一个典型的client。