浅谈模式 - 适配器模式

适配器,属于一种补偿模式,用于补偿原有设计的不足之处。

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中运用的实际案例。Codec2Dubbo的编码和反编码模块。目前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;
}

DubboCodec2下面设置了一个适配器类CodecAdapterCodecAdapter会持有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;
    }
}

查看全部 浅谈模式 - 汇总篇

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值