ServerSocketChannel 只能把OP_ACCEPT注册到某个Selector上,不能注册OP_CONNENCT,OP_READ,OP_WRITE事件;
而SocketChannel 恰恰相反,它能注册OP_CONNENCT,OP_READ,OP_WRITE事件,不能注册OP_ACCEPT。
但是,将某种Channel注册到某个Selector的操作绝大多数都是一样的,也就是说我们可以在超类中实现这些东西。
Bad smells in code中有提过“Duplicated code”,其中一种情况就是重复的代码出现在两个兄弟类中,我们应该把
共同的部分Pull up到超类中去,对于他们之间的不同部分,应该单独出来,细化成某个粒度更小的接口或抽象方法,以在
不同子类中不同实现。
SuperClass {
protected abstart void diffPart();
public void operation() {
//共同操作
diffPart();
//共同操作
}
}
SubClassOne {
public void diffPart() {
//subClassOne's part
}
}
SubClassTwo {
public void diffPart() {
//subClassTwo's part
}
}
public abstract int validOps();//超类中细粒度的抽象方法
public final SelectionKey register(Selector sel, int ops,
Object att)
throws ClosedChannelException
{
if (!isOpen())
throw new ClosedChannelException();
if ((ops & ~validOps()) != 0)//各个子类不同的部分
throw new IllegalArgumentException();
synchronized (regLock) {
if (blocking)
throw new IllegalBlockingModeException();
SelectionKey k = findKey(sel);
if (k != null) {
k.interestOps(ops);
k.attach(att);
}
if (k == null) {
// New registration
k = ((AbstractSelector)sel).register(this, ops, att);
addKey(k);
}
return k;
}
}
子类 SocketChannel的实现:
/**
* Returns an operation set identifying this channel's supported
* operations.
*
* <p> Socket channels support connecting, reading, and writing, so this
* method returns <tt>(</tt>{@link SelectionKey#OP_CONNECT}
* <tt>|</tt> {@link SelectionKey#OP_READ} <tt>|</tt> {@link
* SelectionKey#OP_WRITE}<tt>)</tt>. </p>
*
* @return The valid-operation set
*/
public final int validOps() {
return (SelectionKey.OP_READ
| SelectionKey.OP_WRITE
| SelectionKey.OP_CONNECT);
}
子类ServerSocketChannel的实现:
/**
* Returns an operation set identifying this channel's supported
* operations.
*
* <p> Server-socket channels only support the accepting of new
* connections, so this method returns {@link SelectionKey#OP_ACCEPT}.
* </p>
*
* @return The valid-operation set
*/
public final int validOps() {
return SelectionKey.OP_ACCEPT;
}