目录

适配器模式(Adapter)

类的适配器模式

对象的适配器模式

接口的适配器模式


适配器模式(Adapter)

1、Java 7 种结构型模式:适配器模式、装饰模式、代理模式、外观模式、桥接模式、组合模式、享元模式,其中对象的适配器模式是各种模式的起源,如下图:

2、适配器模式将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的类的兼容性问题。

3、适配器模式主要分为三类:类的适配器模式、对象的适配器模式、接口的适配器模式。

类的适配器模式

1、当希望将一个类(Source)转换成满足另一个新接口的类(Targetable)时,可以使用类的适配器模式,创建一个新类(Adapter),继承原有的类(Source),实现新的接口(Targetable)即可。

2、核心思想是:有一个Source类,拥有一个(些)方法,待适配,目标接口是 Targetable,通过 Adapter 类,将 Source 的功能扩展到 Targetable 里。

3、实现代码如下:

package com.lct.adapterModel;

import java.util.logging.Logger;
//待适配的旧类
public class Source {
    //加法
    public void addition(float a, float b) {
        Logger logger = Logger.getAnonymousLogger();
        logger.info(a + " + " + b + " = " + (a + b));
    }
}
package com.lct.adapterModel;
public interface Targetable {
    //加法,与旧类中的方法相同
    public void addition(float a, float b);

    //乘法,新类的方法
    public void multiplication(float a, float b);
}
package com.lct.adapterModel;

import java.util.logging.Logger;
public class Adapter extends Source implements Targetable {
    @Override
    public void multiplication(float a, float b) {
        Logger logger = Logger.getAnonymousLogger();
        logger.info(a + " * " + b + " = " + (a * b));
    }
}

Adapter 类继承 Source类,实现 Targetable 接口。这样 Targetable 接口的实现类就具有了Source类的功能

4、测试如下:

package com.lct.test;

import com.lct.adapterModel.Adapter;
import com.lct.adapterModel.Targetable;
public class Test {
    public static void main(String[] args) {
        Targetable targetable = new Adapter();
        targetable.addition(10.0F, 20F);
        targetable.multiplication(5.0F, 100F);
    }
}

对象的适配器模式

1、对象的适配器模式:当希望将一个对象转换成满足另一个新接口的对象时,可以创建一个 Wrapper 类,持有原类的一个实例,在 Wrapper 类的方法中,调用实例的方法就行。

2、基本思路和类的适配器模式相同,只是将 Adapter 类作修改,不继承 Source 类,而是持有 Source 类的实例,以达到解决兼容性的问题。

3、修改Adapter 类为 Wrapper 如下:

package com.lct.adapterModel;

import java.util.logging.Logger;
public class Wrapper implements Targetable {
    private Source source;//旧对象作为参数传入

    public Wrapper(Source source) {
        this.source = source;
    }

    @Override
    public void addition(float a, float b) {
        source.addition(a, b);//调用旧类中的方法
    }

    //新类的方法
    @Override
    public void multiplication(float a, float b) {
        Logger logger = Logger.getAnonymousLogger();
        logger.info(a + " * " + b + " = " + (a * b));
    }
}

4、测试类修改如下:

package com.lct.test;

import com.lct.adapterModel.Source;
import com.lct.adapterModel.Targetable;
import com.lct.adapterModel.Wrapper;
public class Test {
    public static void main(String[] args) {
        Targetable targetable = new Wrapper(new Source());
        targetable.addition(10.0F, 20F);
        targetable.multiplication(5.0F, 100F);
    }
}

输出与第一种一样,只是适配的方法不同而已。

接口的适配器模式

1、接口的适配器模式:当不希望实现一个接口中所有的方法时,可以创建一个抽象类 Wrapper,实现所有方法,再写别的类的时候,继承抽象类重写需要的方法即可。

2、当写接口的实现类时,必须实现该接口的所有方法,而有时只需要其中的某一些方法,为了解决这个问题,引入了接口的适配器模式,借助于一个抽象类,该抽象类实现了该接口,并实现了接口的所有方法,而我们不和原始的接口打交道,只和该抽象类取得联系,所以我们写一个类,继承该抽象类,重写我们需要的方法就行。

3、下面使用代码实现上图:

package com.lct.adapterModel;

//原始接口
public interface Sourceable {
    //加法
    public void addition(float a, float b);

    //乘法
    public void multiplication(float a, float b);

    //除法
    public void division(float a, float b);
}
package com.lct.adapterModel;

import java.util.logging.Logger;

//自定义抽象类实现接口中的所有方法
public abstract class AbstractWrapper implements Sourceable {
    @Override
    public void addition(float a, float b) {
    }

    @Override
    public void multiplication(float a, float b) {
    }

    @Override
    public void division(float a, float b) {
        Logger logger = Logger.getAnonymousLogger();
        logger.info(a + " / " + b + " = " + (a / b));
    }
}
package com.lct.adapterModel;

import java.util.logging.Logger;

//子类继承抽象类,重写自己需要的方法
public class SourceSub1 extends AbstractWrapper {
    @Override
    public void addition(float a, float b) {
        Logger logger = Logger.getAnonymousLogger();
        logger.info(a + " + " + b + " = " + (a + b));
    }
}
package com.lct.adapterModel;

import java.util.logging.Logger;

//子类继承抽象类,重写自己需要的方法
public class SourceSub2 extends AbstractWrapper {
    @Override
    public void multiplication(float a, float b) {
        Logger logger = Logger.getAnonymousLogger();
        logger.info(a + " * " + b + " = " + (a * b));
    }
}

4、测试如下:

package com.lct.test;

import com.lct.adapterModel.AbstractWrapper;
import com.lct.adapterModel.SourceSub1;
import com.lct.adapterModel.SourceSub2;

public class Test {
    public static void main(String[] args) {
        AbstractWrapper abstractWrapper = new SourceSub1();
        abstractWrapper.addition(20F, 10F);
        abstractWrapper.division(100F, 20F);

        AbstractWrapper abstractWrapper1 = new SourceSub2();
        abstractWrapper1.multiplication(20F,30F);
        abstractWrapper1.division(200F,4F);
    }
}

 

更多推荐