设计模式(二)------适配器模式

介绍

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。

这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。

分类

接口适配器

示例一

举一个现有的例子,比如你想把Enumeration适配成Iterator,此时必须要明白几个基础概念,或者说是明确你的适配后目标和被适配的对象。

  • 目标:Iterator;
  • 对象:Enumeration;

做法:定义一个适配器,实现你的目标,组合被适配的对象。

package com.silence.mode.struct.adapter;

import java.util.Enumeration;
import java.util.Iterator;

public class EnumerationIteratorAdapter implements Iterator {

    Enumeration enumeration;

    public EnumerationIteratorAdapter(Enumeration enumeration) {
        this.enumeration = enumeration;
    }

    public boolean hasNext() {
        return enumeration.hasMoreElements();
    }

    public Object next() {
        return enumeration.nextElement();
    }

    public void remove() {

    }

}

示例二

大家可能都遇到过一种困扰,比如实现一个接口,而在这个众多接口方法中我们只需要使用其中一两个,一般的做法就是只实现其中这一两个业务逻辑,其他默认实现。但是这样一来就会出现很多冗余的方法,看起来太不协调,在一些主流的框架里面都会出现一些AbstractXXX的默认实现某个或者某些接口,这些实现逻辑基本上符合我们这个示例二所讲的实现方法。

再举一个例子,比如一般Filter都会有如下几个方法:

package com.silence.mode.struct.adapter.inter_face;

public interface AnyFilter {

    void init();

    void doFilter();

    void destroy();

}

一般情况下我们可能只需要实现其中的doFilter(),那么我们就要在代码中冗余其它两个方法,但是如果此时我们创建一个AbstractXXX来默认实现一下其中的方法:

package com.silence.mode.struct.adapter.inter_face;

public class AbstractFilter implements AnyFilter {

    @Override
    public void init() {
        System.out.println("Default init!");
    }

    @Override
    public void doFilter() {
        System.out.println("Default doFilter!");
    }

    @Override
    public void destroy() {
        System.out.println("Default destroy!");
    }

}

这样一来,后续开发人员只需要实现AbstractFilter中的doFilter(),而不需要实现其它两个方法的业务逻辑即可完成我们的预期:

package com.silence.mode.struct.adapter.inter_face;

public class FilterImpl extends AbstractFilter {

    @Override
    public void doFilter() {
        System.out.println("FilterImpl doFilter!");
    }

}

对象适配器

不知道大家经历没有经历过这样一个时期,就是插头上面套个插头,或者是三相转两相或者两相转三相的时代。当然现如今我们已经不需要这么做了,我们拥有了插线板~,但是下面我举得这个例子就是那个时代的一个写照!

我有个冰箱,是三相插头的,但是我墙上的插板只有一个两相的插座,怎么办?

首先看看两相插头是如何工作的:

package com.silence.mode.struct.adapter.object;

public interface TwoPhasePlug {

    void workWithTwoPlug(int plugs);

}
package com.silence.mode.struct.adapter.object.impl;

import com.silence.mode.struct.adapter.object.TwoPhasePlug;

public class RoundHeadTwoPhasePlug implements TwoPhasePlug {

    @Override
    public void workWithTwoPlug(int plugs) {

        System.out.println("两相圆插头拥有" + plugs + "个插头!");

    }

}

然后我有个三相插头的电器:

package com.silence.mode.struct.adapter.object;

public class ThreePhasePlug {

    public void workWithThreePlug(int plugs) {

        System.out.println("三相圆插头拥有" + plugs + "个插头!");

    }

}

下面我就需要一个插头转换器:

package com.silence.mode.struct.adapter.object;

/**
 * Created by Silence on 2018/6/12.
 */
public class Three2TwoPlugAdapter implements TwoPhasePlug {

    private ThreePhasePlug threePhasePlug;

    public Three2TwoPlugAdapter(ThreePhasePlug threePhasePlug) {

        this.threePhasePlug = threePhasePlug;

    }

    @Override
    public void workWithTwoPlug(int plugs) {

        plugs = plugs - 1;
        System.out.println("三相->两相转换器!");

        threePhasePlug.workWithThreePlug(plugs);

    }

}

这个示例中使用了适配器拥有源的一个实例的方式,也就是组合的方式诠释了转换器的实现原理,还有一种就是继承的方式,由于设计模式一个很重要的思想就是多用组合少用继承,因此我摒弃了最后一种方式也就是继承的方式,也被称为类适配器。

猜你喜欢

转载自blog.csdn.net/keysilence1/article/details/80567533
今日推荐