Netty設計モード-ポリシーモード
ポリシー・モードの特徴は、次のとおりです.
1.一連の代替アルゴリズムファミリーをカプセル化する
2、ある戦略の動的選択をサポートする
一般的なポリシー・モードの実装方法
nettyのD e f a u l t E v e n t ExecutorChooserFactoryでは、このように戦略モデルを実現しています.
1.一連の代替アルゴリズムファミリーをカプセル化する
2、ある戦略の動的選択をサポートする
一般的なポリシー・モードの実装方法
/**
* @see DefaultEventExecutorChooserFactory#newChooser(EventExecutor[])
*/
public class Strategy {
private Cache cacheMemory = new CacheMemoryImpl();
private Cache cacheRedis = new CacheRedisImpl();
public interface Cache {
boolean add(String key, Object object);
}
public class CacheMemoryImpl implements Cache {
@Override
public boolean add(String key, Object object) {
// map
return false;
}
}
public class CacheRedisImpl implements Cache {
@Override
public boolean add(String key, Object object) {
// redis
return false;
}
}
public Cache getCache(String key) {
if (key.length() < 10) {
return cacheRedis;
}
return cacheMemory;
}
}
nettyのD e f a u l t E v e n t ExecutorChooserFactoryでは、このように戦略モデルを実現しています.
@UnstableApi
public final class DefaultEventExecutorChooserFactory implements EventExecutorChooserFactory {
public static final DefaultEventExecutorChooserFactory INSTANCE = new DefaultEventExecutorChooserFactory();
private DefaultEventExecutorChooserFactory() { }
@SuppressWarnings("unchecked")
@Override
public EventExecutorChooser newChooser(EventExecutor[] executors) {
if (isPowerOfTwo(executors.length)) {
return new PowerOfTowEventExecutorChooser(executors);
} else {
return new GenericEventExecutorChooser(executors);
}
}
private static boolean isPowerOfTwo(int val) {
return (val & -val) == val;
}
private static final class PowerOfTowEventExecutorChooser implements EventExecutorChooser {
private final AtomicInteger idx = new AtomicInteger();
private final EventExecutor[] executors;
PowerOfTowEventExecutorChooser(EventExecutor[] executors) {
this.executors = executors;
}
@Override
public EventExecutor next() {
return executors[idx.getAndIncrement() & executors.length - 1];
}
}
private static final class GenericEventExecutorChooser implements EventExecutorChooser {
private final AtomicInteger idx = new AtomicInteger();
private final EventExecutor[] executors;
GenericEventExecutorChooser(EventExecutor[] executors) {
this.executors = executors;
}
@Override
public EventExecutor next() {
return executors[Math.abs(idx.getAndIncrement() % executors.length)];
}
}
}