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; }