23种设计模式----适配器模式----结构模式

版权声明:本文为博主原创文章,转载请注明作者。 https://blog.csdn.net/a18792721831/article/details/82702551

适配器模式

1.适配器模式介绍

引入:显示生活中,有许许多多的的电器在被使用,但是我们普通家用电线的电压是220V(一般)。但是家里的电器却又很多种:
手机充电:5V
手电筒:12V、5V
电视机:220V
笔记本:12V
(电器电压不一定正确)
。。。。。。。。
那么,为什么只提供一种电压却满足了这么不同电压需求的电器。
原因就是每一种电器都有各自的电压转换器(变压器),笔记本是充电适配器(外)电视机(内)手机充电头(电源适配器)
所以,生活中处处可见各种各样的适配器。

在程序世界中,经常会存在有的程序无法直接使用,需要做适当的变换之后才能使用的情形(源自《图解设计模式》)。适配器模式就是连接“现有程序”和“目标程序”的中间程序。

2.适配器模式角色

通俗的理解:
需求-Target
适配器-Adapter
现有-Adaptee
使用-Client
专业的解释:
Target-对象
Client-请求者
Adaptee-被适配
Adapter-适配

3.适配器模式的实现

适配模式的实现主要分为2种:继承的方式和组合的方式。

需求

一个接口:玩和吃

public interface PeopleAction {

    void playNeed();

    void eatNeed();

}

现有

一个类:名字和年龄,玩和吃方法

import com.startime.adapter.utils.PeopleEatUtil;
import com.startime.adapter.utils.PeoplePlyUtil;


public class People{

    protected String name;

    protected int age;

    protected String string;

    public void setString(String string){
        this.string = string;
    }

    public People(String name,int age){
        this.name = name;
        this.age = age;
    }

    public void playHave(){
        PeoplePlyUtil.p(string, name, age);
    }

    public void eatHave(){
        PeopleEatUtil.e(string, name, age);
    }
}

工具类

public class PeopleEatUtil {

    public static void showTime(){
        PeoplePlyUtil.showTime();
    }

    public static void eat(String string){
        System.out.println(string);
    }

    public static void eat(String name,int age){
        System.out.println("我叫"+name+",今年"+age+"岁!");
    }

    public static void e(String string,String name,int age){
        showTime();
        eat(name, age);
        eat(string);
    }
}
import java.text.SimpleDateFormat;
import java.util.Date;

public class PeoplePlyUtil {

    public static void play(String string){
        System.out.println(string);
    }
    public static void play(String name,int age){
        System.out.println("我叫"+name+",今年"+age+"岁!");
    }
    public static void showTime(){
        System.out.print(new SimpleDateFormat("HH:mm:ss").format(new Date())+"\t");
    }
    public static void p(String string,String name,int age){
        showTime();
        play(name, age);
        play(string);
    }
}

3.1继承方式实现适配器

定义适配器:

import com.startime.adapter.domain.PeopleAction;
import com.startime.adapter.domain.People;


public class ChildrenExtend extends People implements PeopleAction{

    public ChildrenExtend(String name, int age) {
        super(name, age);
    }

    @Override
    public void playNeed() {
        super.setString("我玩王者荣耀");
        super.playHave();
    }

    @Override
    public void eatNeed() {
        super.setString("我吃冰淇淋");
        super.eatHave();
    }

}
import com.startime.adapter.domain.PeopleAction;
import com.startime.adapter.domain.People;


public class TeenagerExtend extends People implements PeopleAction{

    public TeenagerExtend(String name, int age) {
        super(name, age);
    }

    @Override
    public void playNeed() {
        super.setString("我玩足球");
        super.playHave();
    }

    @Override
    public void eatNeed() {
        super.setString("我吃麻辣烫");
        super.eatHave();
    }

}
import com.startime.adapter.domain.PeopleAction;
import com.startime.adapter.domain.People;


public class WrinklyExtend extends People implements PeopleAction{

    public WrinklyExtend(String name, int age) {
        super(name, age);
    }

    @Override
    public void playNeed() {
        super.setString("我玩高尔夫球");
        super.playHave();
    }

    @Override
    public void eatNeed() {
        super.setString("我吃绿豆羹");
        super.eatHave();
    }


}
import com.startime.adapter.domain.PeopleAction;
import com.startime.adapter.domain.People;


public class OlderExtend extends People implements PeopleAction{

    public OlderExtend(String name, int age) {
        super(name, age);
    }

    @Override
    public void playNeed() {
        super.setString("我玩中国象棋");
        super.playHave();
    }

    @Override
    public void eatNeed() {
        super.setString("我吃流食");
        super.eatHave();
    }

}

使用:

public class MainExtend {

    public static void main(String[] args) {
        ChildrenExtend c = new ChildrenExtend("小胖", 9);
        c.playNeed();
        c.eatNeed();
        TeenagerExtend t = new TeenagerExtend("张峰", 19);
        t.playNeed();
        t.playNeed();
        WrinklyExtend w = new WrinklyExtend("中山", 35);
        w.playNeed();
        w.eatNeed();
        OlderExtend o = new OlderExtend("X老", 88);
        o.playNeed();
        o.eatNeed();
    }

}

3.2组合的方式

实现适配器:

import com.startime.adapter.domain.People;
import com.startime.adapter.domain.PeopleAction;

public class ChildrenGroup implements PeopleAction{

    private People children = null;

    public ChildrenGroup(String name,int age){
        children = new People(name, age);
    }

    @Override
    public void playNeed() {
        children.setString("我玩手机游戏");
        children.playHave();
    }

    @Override
    public void eatNeed() {
        children.setString("我吃冰淇淋");
        children.eatHave();
    }

}
import com.startime.adapter.domain.People;
import com.startime.adapter.domain.PeopleAction;

public class TeenagerGroup implements PeopleAction{

    private People teenager = null;

    public TeenagerGroup(String name,int age){
        teenager = new People(name, age);
    }

    @Override
    public void playNeed() {
        teenager.setString("我玩足球");
        teenager.playHave();
    }

    @Override
    public void eatNeed() {
        teenager.setString("我吃辣条");
        teenager.eatHave();
    }

}
import com.startime.adapter.domain.People;
import com.startime.adapter.domain.PeopleAction;

public class WrinklyGroup implements PeopleAction{

    private People wrinkly = null;

    public WrinklyGroup(String name,int age){
        wrinkly = new People(name, age);
    }

    @Override
    public void playNeed() {
        wrinkly.setString("我玩攀岩");
        wrinkly.playHave();
    }

    @Override
    public void eatNeed() {
        wrinkly.setString("我吃肉");
        wrinkly.eatHave();
    }

}
import com.startime.adapter.domain.People;
import com.startime.adapter.domain.PeopleAction;

public class OlderGroup implements PeopleAction{

    private People older = null;

    public OlderGroup(String name,int age){
        older = new People(name, age);
    }

    @Override
    public void playNeed() {
        older.setString("我玩象棋");
        older.playHave();
    }

    @Override
    public void eatNeed() {
        older.setString("我吃流食");
        older.eatHave();
    }

}

使用:

public class MainGroup {
    public static void main(String[] args) {
        ChildrenGroup c = new ChildrenGroup("小胖", 9);
        c.playNeed();
        c.eatNeed();
        TeenagerGroup t = new TeenagerGroup("张峰", 19);
        t.playNeed();
        t.playNeed();
        WrinklyGroup w = new WrinklyGroup("中山", 35);
        w.playNeed();
        w.eatNeed();
        OlderGroup o = new OlderGroup("X老", 88);
        o.playNeed();
        o.eatNeed();
    }
}

3.3适配器模式实现扩展

问题:需求中的接口如果比较多,在实现适配器中,适配器可能用到很少的接口,会造成许多接口无用的实现。
原理:使用一个中间类,中间类实现接口(空语句实现),然后适配器继承中间类,利用子类覆盖父类的方法实现需求的接口,其他接口不用实现。
缺陷:
现有类的属性与方法需要被孙子类访问到(可以是方法访问或者属性权限控制)。
比如使用protected修饰类的属性或者增加protected方法访问类的属性。
接口:

public interface PersonEatInterface {

    void eatIceCream();

    void eatHotpot();

    void eatMungBeanSoup();

    void eatFluids();
}
public interface PersonPlayInterface {

    void playGame();

    void playSoccer();

    void playGolf();

    void playChess();
}

中间类:

import com.startime.adapter.domain.People;


public class PeopleBasic extends People implements PersonEatInterface,PersonPlayInterface{

    public PeopleBasic(String name, int age) {
        super(name, age);
    }

    @Override
    public void playGame() {
        super.playHave();
    }

    @Override
    public void playSoccer() {
        super.playHave();
    }

    @Override
    public void playGolf() {
        super.playHave();
    }

    @Override
    public void playChess() {
        super.playHave();
    }

    @Override
    public void eatIceCream() {
        super.eatHave();
    }

    @Override
    public void eatHotpot() {
        super.eatHave();
    }

    @Override
    public void eatMungBeanSoup() {
        super.eatHave();
    }

    @Override
    public void eatFluids() {
        super.eatHave();
    }
    public void setString(String string){
        super.setString(string);
    }

}

适配器:

public class ChildrenExtendsAndInterface extends PeopleBasic{

    public ChildrenExtendsAndInterface(String name, int age) {
        super(name, age);
    }

    @Override
    public void playGame() {
        super.setString("我玩吃鸡");
        super.playGame();
    }

    @Override
    public void eatIceCream() {
        super.setString("我吃冰淇淋");
        super.eatIceCream();
    }

}
public class TeenagerExtendsAndInterface extends PeopleBasic{

    public TeenagerExtendsAndInterface(String name, int age) {
        super(name, age);
    }

    @Override
    public void playSoccer() {
        super.setString("我玩足球");
        super.playSoccer();
    }

    @Override
    public void eatHotpot() {
        super.setString("我吃麻辣烫");
        super.eatHotpot();
    }


}

public class WrinklyExtendsAndInterface extends PeopleBasic{

    public WrinklyExtendsAndInterface(String name, int age) {
        super(name, age);
    }

    @Override
    public void playGolf() {
        super.setString("我玩高尔夫球");
        super.playGolf();
    }

    @Override
    public void eatMungBeanSoup() {
        super.setString("我吃绿豆羹");
        super.eatMungBeanSoup();
    }

}
public class OlderExtendsAndInterface extends PeopleBasic{

    public OlderExtendsAndInterface(String name, int age) {
        super(name, age);
    }

    @Override
    public void playChess() {
        super.setString("我玩象棋");
        super.playChess();
    }

    @Override
    public void eatFluids() {
        super.setString("我吃流食");
        super.eatFluids();
    }

}

使用:

import java.util.ArrayList;
import java.util.List;

public class MainExtendsAndInterface {

    public static void main(String[] args) {
        List<PeopleBasic> list = new ArrayList<PeopleBasic>();
        list.add(new ChildrenExtendsAndInterface("小胖", 9));
        list.add(new TeenagerExtendsAndInterface("张峰", 19));
        list.add(new WrinklyExtendsAndInterface("中山", 35));
        list.add(new OlderExtendsAndInterface("X老", 88));
        for (PeopleBasic object : list) {
            object.playChess();
            object.playGame();
            object.playGolf();
            object.playSoccer();
            object.eatFluids();
            object.eatHotpot();
            object.eatIceCream();
            object.eatMungBeanSoup();
        }
    }
}

3.4文档结构及名称

这里写图片描述

3.5总结

适配器解决连接旧类与新类的问题,主要有继承和组合两种方式;继承方式就是适配器继承旧类实现新类需求的接口,在新类的需求接口中合理的调用旧类现有的方法,实现新类的需求;组合方式是在适配器中增加旧类的属性,在实现新类的接口中,合理的通过旧类对象来调用旧类的方法,实现新类的需求;当接口中的方法较多时,可以使用中间类空语句或者转发(不改变任何东西,只是转发请求)实现接口,在中间类的子类中具体实现需要实现的接口;使用中间类要求旧类的方法在新类中能够实现调用,要么是权限限定关键词限定作用域,或者提供专门的访问方法,才能实现中间类的转发,进而实现适配器;使用适配器需要旧类方法和新类方法有一定的联系,如果完全没有任何显示或者隐含的联系,强行使用适配器只会增加工作的难度和工作量。

4.适配器模式的使用

4.1使用适配器可以在不更改原有类的基础上增加新类,这样出现bug也是在新类中,比在原有类的基础上修改好的多。

4.2修改原有类需要对原有类进行测试,如果只是改动比较小,但是测试比较麻烦的类,使用适配器的代价小的多。

4.3版本升级,新版本兼容旧版本。

猜你喜欢

转载自blog.csdn.net/a18792721831/article/details/82702551
今日推荐