适配器,属于一种补偿模式,用于补偿原有设计的不足之处。
adapter
持有adaptee
目标对象的委托,对其调用。或者继承关系。
继承的方式
public class Adaptee {
public void method1() {
System.out.println("目标方法");
}
}
public class Adapter extends Adaptee implements ITarget {
@Override
public void doMethod1() {
super.method1();
}
}
public class Client {
public static void main(String[] args) {
ITarget target = new Adapter();
target.doMethod1();
}
}
组合的方式
public class Adaptee {
public void method1() {
System.out.println("目标方法");
}
}
public class Adapter2 implements ITarget {
private Adaptee adaptee;
public Adapter2(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void doMethod1() {
adaptee.method1();
}
}
public class Client {
public static void main(String[] args) {
ITarget target = new Adapter2(new Adaptee());
target.doMethod1();
}
}
说一个Dubbo
中运用的实际案例。Codec2
是Dubbo
的编码和反编码模块。目前Codec2
模块已经升级到Codec2
,而原来老的Codec
还有些用处。那么所有的上层模块都依赖Codec2
新编码模块之后,怎么兼容Codec
老模块呢?看看他们代码是怎么写的就知道了。
// 新模块
public interface Codec2 {
@Adaptive({Constants.CODEC_KEY})
void encode(Channel channel, ChannelBuffer buffer, Object message) throws IOException;
@Adaptive({Constants.CODEC_KEY})
Object decode(Channel channel, ChannelBuffer buffer) throws IOException;
enum DecodeResult {
NEED_MORE_INPUT, SKIP_SOME_INPUT
}
}
// 老模块
public interface Codec {
Object NEED_MORE_INPUT = new Object();
@Adaptive({Constants.CODEC_KEY})
void encode(Channel channel, OutputStream output, Object message) throws IOException;
@Adaptive({Constants.CODEC_KEY})
Object decode(Channel channel, InputStream input) throws IOException;
}
Dubbo
在Codec2
下面设置了一个适配器类CodecAdapter
。CodecAdapter
会持有Codec
的委托。
// CodecAdapter实现了Codec2
public class CodecAdapter implements Codec2 {
// CodecAdapter这个适配器中持有Codec的委托
private Codec codec;
public CodecAdapter(Codec codec) {
Assert.notNull(codec, "codec == null");
this.codec = codec;
}
@Override
public void encode(Channel channel, ChannelBuffer buffer, Object message)
throws IOException {
UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(1024);
codec.encode(channel, os, message);
buffer.writeBytes(os.toByteArray());
}
@Override
public Object decode(Channel channel, ChannelBuffer buffer) throws IOException {
byte[] bytes = new byte[buffer.readableBytes()];
int savedReaderIndex = buffer.readerIndex();
buffer.readBytes(bytes);
UnsafeByteArrayInputStream is = new UnsafeByteArrayInputStream(bytes);
Object result = codec.decode(channel, is);
buffer.readerIndex(savedReaderIndex + is.position());
return result == Codec.NEED_MORE_INPUT ? DecodeResult.NEED_MORE_INPUT : result;
}
public Codec getCodec() {
return codec;
}
}
查看全部 浅谈模式 - 汇总篇