【Java设计模式】012-适配器模式

目录

八、适配器模式

1、概述

2、应用场景

3、优缺点

优点

缺点

4、主要角色

5、类适配器实现

目标接口

适配者

适配器

测试类

运行结果

6、对象适配器实现

目标接口

适配者

适配器

测试类

运行结果

7、接口适配器实现(缺省适配器)

接口

适配器

功能类

测试类

运行结果

8、双向适配器

Number接口

String接口

双向适配器

测试类

运行结果

9、感想


八、适配器模式

适配器大约跟转换器是一个意思了!也许是格式转换,也许是功能扩展……时间:2021年05月14日 10时08分35秒

1、概述

在现实生活中,经常出现两个对象因接口不兼容而不能在一起工作的实例,这时需要第三者进行适配。例如,讲中文的人同讲英文的人对话时需要一个翻译,用直流电的笔记本电脑接交流电源时需要一个电源适配器,用计算机访问照相机的 SD 内存卡时需要一个读卡器等。

在软件设计中也可能出现:需要开发的具有某种业务功能的组件在现有的组件库中已经存在,但它们与当前系统的接口规范不兼容,如果重新开发这些组件成本又很高,这时用适配器模式能很好地解决这些问题。

我在Android里面写过ListView的适配器!

为什么要适配?因为原来的东西还有可用性,不需要一个全新的东西,只需要对旧东西进行转换改造即可满足需求!因此适配的方式也是有很多的,比如调整顺序、调整格式、打乱重组、数据转换、重写部分内容等等;

适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。适配器模式分为类结构型模式和对象结构型模式两种,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。

 

2、应用场景

  • 以前开发的系统存在满足新系统功能需求的类,但其接口同新系统的接口不一致;

  • 使用第三方提供的组件,但组件接口定义和自己要求的接口定义不同;

 

3、优缺点

优点

  • 客户端通过适配器可以透明地调用目标接口;

  • 复用了现存的类,程序员不需要修改原有代码而重用现有的适配者类;

  • 将目标类和适配者类解耦,解决了目标类和适配者类接口不一致的问题;

  • 在很多业务场景中符合开闭原则;

 

缺点

  • 适配器编写过程需要结合业务场景全面考虑,可能会增加系统的复杂性;

  • 增加代码阅读难度,降低代码可读性,过多使用适配器会使系统代码变得凌乱;

 

4、主要角色

  • 目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口;

  • 适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口;

  • 适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者;

 

5、类适配器实现

目标接口

狗要会唱会跳

package com.zibo.design.six;

// 目标是能唱能跳
public interface Action {
    void song();
    void jump();
}

 

适配者

package com.zibo.design.six;

public class Dog {
    public void song(){
        System.out.println("狗在唱歌!");
    }
}

 

适配器

适配器模式好像干了和代理模式类似的活,适配器模式是对类和对象的增强

package com.zibo.design.six;

public class DogActionAdapter extends Dog implements Action{

    @Override
    public void jump() {
        System.out.println("狗狗在跳舞!");
    }
}

 

测试类

package com.zibo.design.six;

public class Test {
    public static void main(String[] args) {
        Action action = new DogActionAdapter();
        action.song();
        action.jump();
    }
}

 

运行结果

狗在唱歌!
狗狗在跳舞!

 

6、对象适配器实现

目标接口

目标是先站起来,然后说话,是一套走完

package com.zibo.design.five;

public interface Action {
    void standAndSay();
}

 

适配者

适配者不满足要求,所以要适配

package com.zibo.design.five;

public class Dog {

    public void stand(){
        System.out.println("狗站起来了!");
    }

    public void say(){
        System.out.println("狗说话了!");
    }

}

 

适配器

package com.zibo.design.five;

// 狗的行动适配器
public class DogActionAdapter implements Action {

    private final Dog dog;

    public DogActionAdapter(Dog dog) {
        this.dog = dog;
    }

    // 根据目标要求将两个动作组合成一个动作
    @Override
    public void standAndSay() {
        dog.stand();
        dog.say();
    }
}

 

测试类

package com.zibo.design.five;

public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        Action action = new DogActionAdapter(dog);
        action.standAndSay();
    }
}

 

运行结果

狗站起来了!
狗说话了!

 

7、接口适配器实现(缺省适配器)

当存在这样一个接口,其中定义了N多的方法,而我们现在却只想使用其中的一个到几个方法,如果我们直接实现接口,那么我们要对所有的方法进行实现,哪怕我们仅仅是对不需要的方法进行置空(只写一对大括号,不做具体方法实现)也会导致这个类变得臃肿,调用也不方便,这时我们可以使用一个抽象类作为中间件,即适配器,用这个抽象类实现接口,而在抽象类中所有的方法都进行置空,那么我们在创建抽象类的继承类,而且重写我们需要使用的那几个方法即可!妙啊!

接口

package com.zibo.design.seven;

public interface DoSth {
    void act01();
    void act02();
    void act03();
    void act04();
    void act05();
}

 

适配器

package com.zibo.design.seven;

// 接口适配器,定义为抽象类是为了使其不能new
public abstract class DoSthImpl implements DoSth{

    @Override
    public void act01() {

    }

    @Override
    public void act02() {

    }

    @Override
    public void act03() {

    }

    @Override
    public void act04() {

    }

    @Override
    public void act05() {

    }
}

 

功能类

package com.zibo.design.seven;

public class Person extends DoSthImpl{

    @Override
    public void act03() {
        System.out.println("做第三件事情!");
    }

    @Override
    public void act04() {
        System.out.println("做第四件事情!");
    }
}

 

测试类

package com.zibo.design.seven;

public class Test {
    public static void main(String[] args) {
        Person person = new Person();
        person.act03();
        person.act04();
    }
}

 

运行结果

做第三件事情!
做第四件事情!

 

8、双向适配器

实际工作中不常用!下面的例子也有点牵强,但说明了大致意思,可参考网上了猫狗双向适配器,写得倒是挺完善的,但我没看出来有啥用!地址:https://blog.csdn.net/xm393392625/article/details/79047859

Number接口

package com.zibo.design.eight;

public interface INumber {
    String toStr();
}

 

String接口

package com.zibo.design.eight;

public interface IString {
    Integer toNumber();
}

 

双向适配器

package com.zibo.design.eight;

public class NumberAndStringAdapter implements INumber,IString {

    private Integer num;
    private String str;

    public NumberAndStringAdapter(Integer num) {
        this.num = num;
    }

    public NumberAndStringAdapter(String str) {
        this.str = str;
    }

    @Override
    public Integer toNumber() {
        return num != null ? num : Integer.parseInt(str);
    }

    @Override
    public String toStr() {
        return str != null ? str : String.valueOf(num);
    }
}

 

测试类

package com.zibo.design.eight;

public class Test {
    public static void main(String[] args) {
        Integer integer = 100;
        NumberAndStringAdapter adapter = new NumberAndStringAdapter(integer);
        System.out.println(adapter.toStr());
        String str = "1999";
        NumberAndStringAdapter adapter1 = new NumberAndStringAdapter(str);
        System.out.println(adapter1.toNumber());
    }
}

 

运行结果

100
1999

 

9、感想

我发现这些设计模式的作用有很多相通的地方,也许在实际运用的时候可以灵活使吧!

在实际使用的时候,我们可以领会调配我们所使用的设计模式!我发现键盘垫腕限制了我的手腕的移动!导致我没办法灵活控制键盘,那么我打字的错误率提高了很多!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值