开发之路(设计模式七:适配器模式)

你眼中的适配器是什么样子的呢?在设计模式中也有模式叫适配器模式,一块儿来看看吧。

适配器是什么这不须要做者我多解释把,打个比方,在国内用的是220V的电器,但国外有些国家是110V甚至240V的也有等等,国内的充电线就不能直接插国外的插座了,这时候就须要一个适配器作电源转换,是的,在设计模式中也有这么一个模式与其相似,也是个颇有用的模式。编程

下面我作了几个配图来理解设计模式。设计模式

假设已有一个系统,此时它须要更新,你但愿它能和新的厂商类库搭配使用,可是这个新厂商设计出来的接口,与原系统的接口不同。因此二者不能直接匹配。
图片描述ide

若重构原来的代码可能会很是麻烦,并且又不能去改变厂商的代码,怎么办呢?这是你能够写一个类,将新厂商接口转换为你所期待的接口。
图片描述测试

那么这个适配器就比如一个中间人,它将客户所发送的请求转换成厂商类可以理解的请求。
图片描述this

直接放一个例子,假如一只火鸡想要“冒充”成鸭子怎么作呢?
代码以下:spa

这是鸭子接口设计

package duck_Interface;

/**
 * 适配器模式:就比如在中国的电器若要在美国的插座上使用,就必须使用适配器, 
 * 适配器就至关于一个中间层,将两个本来不能相互沟通的东西链接在一块儿
 * 
 * @author Joy
 * 
 */
public interface Duck {
    public void quack();

    public void fly();
}

绿头鸭是鸭子的子类code

package duck_Implements;

import duck_Interface.Duck;

public class MallardDuck implements Duck {
    /**
     * 绿头鸭
     */
    @Override
    public void quack() {
        System.out.println("绿头鸭叫:呱呱呱");

    }

    @Override
    public void fly() {
        System.out.println("我在飞");
    }
}

这是一只火鸡(接口)对象

package duck_Interface;

/**
 * 火鸡接口
 * 
 * @author Joy
 * 
 */
public interface Turkey {
    // 火鸡只会咯咯咯叫
    public void gobble();

    // 火鸡会飞,但飞不远
    public void fly();
}

这是火鸡的一个具体实现继承

package duck_Implements;

import duck_Interface.Turkey;

public class WildTurkey implements Turkey {
    /**
     * 火鸡类的实现
     */

    @Override
    public void gobble() {
        System.out.println("火鸡叫:咯咯咯");
    }

    @Override
    public void fly() {
        System.out.println("我会飞,但飞不高");
    }
}

很显然二者一开始不能直接匹配,这里写一个火鸡适配器

package Adapter;

import duck_Interface.Duck;
import duck_Interface.Turkey;

/**
 * 火鸡的适配器
 * 
 * @author Joy
 * 
 */
// 先要实现想要转换的类型接口,(火鸡但愿和绿头鸭交流)
// 火鸡:被适配者,鸭子:适配者
// 这里火鸡要实现鸭子接口
public class TurkeyAdapter implements Duck {
    Turkey turkey;

    // 须要取得适配的对象引用
    // 利用构造器取得这个引用
    public TurkeyAdapter(Turkey turkey) {
        this.turkey = turkey;
    }

    @Override
    public void quack() {
        // 如今咱们须要实现火鸡里的叫的方法
        // 很简单只需直接引用
        turkey.gobble();
    }

    /**
     * 这里因为火鸡的飞行距离短,鸭子飞行距离长, 为二者飞行可以对应, 这里得屡次调用火鸡飞行方法,至关于火鸡5次飞行的距离等于一次鸭子飞行的距离。。
     */
    @Override
    public void fly() {
        for (int i = 0; i < 5; i++) {
            turkey.fly();
        }
    }
}

测试类

package TestMain;

import Adapter.TurkeyAdapter;
import duck_Implements.MallardDuck;
import duck_Implements.WildTurkey;
import duck_Interface.Duck;

public class DuckTestDrive {
    // 取得一只鸭子
    public static void testDuck(Duck duck) {
        duck.quack();
        duck.fly();
    }

    public static void main(String[] args) {
        // 建立好一只鸭子和火鸡
        MallardDuck duck = new MallardDuck();
        WildTurkey turkey = new WildTurkey();
        // 而后将火鸡“包装”进火鸡适配器中,让它看上起像只鸭子
        Duck turkeyAdapter = new TurkeyAdapter(turkey);
        System.out.println("这只火鸡说~~~~~");
        turkey.gobble();
        turkey.fly();
        System.out.println("\n这只鸭子说a~~~~~");
        testDuck(duck);
        // 试着传入一个伪装是鸭子的火鸡对象
        System.out.println("\n火鸡适配器说~~~~~");
        /**
         * testDuck()方法不知道这是一只伪装鸭子的火鸡 turkey调用叫的方法是“咯咯咯”
         * 而fly方法调用了5次,就为了让火鸡伪装成鸭子同样飞的远
         */
        testDuck(turkeyAdapter);

    }
}

效果图
图片描述

TurkeyAdapter里的quack方法被调用,适配器咯咯咯的叫,而后fly方法被调用,适配器执行了5次飞行操做,而在testDuck(Duck duck)它还觉得参数duck真的是一鸭子,实际上是只伪装鸭子的火鸡(turkeyAdapter)。

让咱们再看看各部分之间的关系。
图片描述

客户使用适配器的过程以下:
一、客户经过目标接口调用适配器的方法对适配器发出请求。
二、适配器(鸭子)使用被适配器(火鸡)接口把请求转换成被适配器的一个或多个调用接口。
三、客户接收到调用的结果,但并未察觉这一切是适配器再起转换做用。

定义适配器模式:将一个类的接口,转换成客户期待的另外一个接口。适配器让本来接口不兼容的类能够合做无间。

注:细分适配器类型是有两种的,对象适配器和类适配器,前面的火鸡例子是对象适配器,而“类”适配器则须要多重继承才能实现,而Java中是不被容许的,这里就不讲述。

感谢你看到这里,适配器模式到这里就结束了,本人文笔随便,如有不足或错误之处望给予指点,90度弯腰~~~很快我会发布下一个设计模式的内容,生命不息,编程不止!

参考书籍:《Head First 设计模式》
相关文章
相关标签/搜索