适配器模式(Adapter Pattern)

23种软件设计模式

介绍

将一个类的接口转换成客户希望的另外一个接口,适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作,属于结构型设计模式。

使用场景

已经存在的类,它的方法和需求不匹配(方法结果相同或相似)的情况。

适配器模式不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品、不 同厂家造成功能类似而接口不相同情况下的解决方案,有点亡羊补牢的感觉。

优点

能提高类的透明性和复用,现有的类复用但不需要改变。

目标类和适配器类解耦,提高程序的扩展性。

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

缺点

适配器编写过程需要全面考虑,可能会增加系统的复杂性。

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

使用建议

能够重构就优先考虑重构,尽量不要使用适配器模式,毕竟业务复杂时代码看起来会很恶心。

代码实现

(实例一)媒体播放器适配器实现:

类图:

代码:

package com.knowledge.system.software_design_pattern.adapter_pattern.myself_instance;

public interface MediaPlayer {
    public void play(String audioType,String fileName);
}
package com.knowledge.system.software_design_pattern.adapter_pattern.myself_instance;

public interface AdvancedMediaPlayer {
    public void playVlc(String fileName);
    public void playMp4(String fileName);
}
package com.knowledge.system.software_design_pattern.adapter_pattern.myself_instance;

public class Mp4Player implements AdvancedMediaPlayer {
    @Override
    public void playVlc(String fileName) {

    }

    @Override
    public void playMp4(String fileName) {
        System.out.println("Playing mp4 file. Name: "+ fileName);
    }
}
package com.knowledge.system.software_design_pattern.adapter_pattern.myself_instance;

public class VlcPlayer implements AdvancedMediaPlayer {
    @Override
    public void playVlc(String fileName) {
        System.out.println("Playing vlc file. Name: "+ fileName);
    }

    @Override
    public void playMp4(String fileName) {

    }
}
package com.knowledge.system.software_design_pattern.adapter_pattern.myself_instance;

public class MediaAdapter implements MediaPlayer {

    AdvancedMediaPlayer advancedMusicPlayer;

    public MediaAdapter(String audioType){
        if(audioType.equalsIgnoreCase("vlc") ){
            advancedMusicPlayer = new VlcPlayer();
        } else if (audioType.equalsIgnoreCase("mp4")){
            advancedMusicPlayer = new Mp4Player();
        }
    }

    @Override
    public void play(String audioType, String fileName) {
        if(audioType.equalsIgnoreCase("vlc")){
            advancedMusicPlayer.playVlc(fileName);
        }else if(audioType.equalsIgnoreCase("mp4")){
            advancedMusicPlayer.playMp4(fileName);
        }
    }
}
package com.knowledge.system.software_design_pattern.adapter_pattern.myself_instance;

public class AudioPlayer implements MediaPlayer {

    MediaAdapter mediaAdapter;

    @Override
    public void play(String audioType, String fileName) {
        //播放 mp3 音乐文件的内置支持
        if(audioType.equalsIgnoreCase("mp3")){
            System.out.println("Playing mp3 file. Name: "+ fileName);
        }
        //mediaAdapter 提供了播放其他文件格式的支持
        else if(audioType.equalsIgnoreCase("vlc")
                || audioType.equalsIgnoreCase("mp4")){
            mediaAdapter = new MediaAdapter(audioType);
            mediaAdapter.play(audioType, fileName);
        }
        else{
            System.out.println("Invalid media. "+
                    audioType + " format not supported");
        }
    }
}
package com.knowledge.system.software_design_pattern.adapter_pattern.myself_instance;

public class AdapterPatternDemo {
    public static void main(String[] args) {
        AudioPlayer audioPlayer=new AudioPlayer();

        audioPlayer.play("mp3", "beyond the horizon.mp3");
        audioPlayer.play("mp4", "alone.mp4");
        audioPlayer.play("vlc", "far far away.vlc");
        audioPlayer.play("avi", "mind me.avi");
    }
}

(实例二)扩展登录方式的适配器实现:

简单实现:

package com.knowledge.system.software_design_pattern.adapter_pattern.course_instance;

import lombok.Data;

@Data
public class Member {
    private String username;
    private String password;
    private String mid;
    private String info;
}
package com.knowledge.system.software_design_pattern.adapter_pattern.course_instance;

import lombok.Data;

@Data
public class ResultMsg {

    private int code;
    private String msg;
    private Object data;

    public ResultMsg() {}

    public ResultMsg(int code, String msg, Object data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

}
package com.knowledge.system.software_design_pattern.adapter_pattern.course_instance;

public class SignService {
    public ResultMsg regist(String username,String password){
        return new ResultMsg(200,"注册成功",new Member());
    }
    public ResultMsg login(String username,String password){
        return  null;
    }
}
package com.knowledge.system.software_design_pattern.adapter_pattern.course_instance;

public class SignForThreadService extends SignService{
    public ResultMsg loginForQQ(String openId){
        return loginForRegist(openId,null);
    }

    public ResultMsg loginForWechat(String openId){
        return null;
    }
    public ResultMsg loginForToken(String openId){
        return null;
    }
    public ResultMsg loginForTelphne(String openId){
        return null;
    }
    public ResultMsg loginForRegist(String username, String  passwore) {
        super.regist(username,null);
        return super.login(username,null);
    }
}
package com.knowledge.system.software_design_pattern.adapter_pattern.course_instance;

import com.alibaba.fastjson.JSON;

/**
 * 0.简介:将一个类的一个接口转换成客户期望的另一个接口
 *    0.1  已经存在的类,它的方法和需求不匹配(方法结果相同或相似)的情况。
 *    0.2  适配器模式不是软件设计阶段考虑的设计模式,是随着软件维护,由于不同产品、不 同厂家造成功能类似而接口不相同情况下的解决方案。有点亡羊补牢的感觉。
 * 1.源码实例:adapter结尾
 */
public class Test {
    public static void main(String[] args) {
        System.out.println("测试适配器模式");
        SignForThreadService signForThreadService=new SignForThreadService();
        ResultMsg msg=signForThreadService.loginForQQ("dafkjahgjkahd");
        System.out.println(JSON.toJSON(msg));
    }
}

引入适配器:

类图:

代码:

package com.knowledge.system.software_design_pattern.adapter_pattern.course_instance.adapter;

import com.knowledge.system.software_design_pattern.adapter_pattern.course_instance.ResultMsg;

public interface LoginAdapter {
    boolean support(Object adapter);
    ResultMsg login(String id,Object adapter);
}
package com.knowledge.system.software_design_pattern.adapter_pattern.course_instance.adapter;

import com.knowledge.system.software_design_pattern.adapter_pattern.course_instance.ResultMsg;

public interface IPassportForThird {
    ResultMsg loginForQQ(String id);
    ResultMsg loginForWechat(String id);
    ResultMsg loginForToken(String token);
    ResultMsg loginForTelphone(String telphone,String code);
    ResultMsg loginForRegist(String username,String passport);
}
package com.knowledge.system.software_design_pattern.adapter_pattern.course_instance.adapter;

import com.knowledge.system.software_design_pattern.adapter_pattern.course_instance.ResultMsg;

public class LoginForQQAdapter implements LoginAdapter {
    @Override
    public boolean support(Object adapter) {
        return adapter instanceof  LoginForQQAdapter;
    }

    @Override
    public ResultMsg login(String id, Object adapter) {
        return new ResultMsg(200,"登录成功","success");
    }
}
package com.knowledge.system.software_design_pattern.adapter_pattern.course_instance.adapter;

import com.knowledge.system.software_design_pattern.adapter_pattern.course_instance.ResultMsg;

public class LoginForTelAdapter implements LoginAdapter {
    @Override
    public boolean support(Object adapter) {
        return adapter  instanceof  LoginForTelAdapter;
    }

    @Override
    public ResultMsg login(String id, Object adapter) {
        return null;
    }

}
package com.knowledge.system.software_design_pattern.adapter_pattern.course_instance.adapter;

import com.knowledge.system.software_design_pattern.adapter_pattern.course_instance.ResultMsg;

public class LoginForTokenAdapter implements LoginAdapter {
    @Override
    public boolean support(Object adapter) {
        return adapter instanceof  LoginForTokenAdapter;
    }

    @Override
    public ResultMsg login(String id, Object adapter) {
        return null;
    }
}
package com.knowledge.system.software_design_pattern.adapter_pattern.course_instance.adapter;

import com.knowledge.system.software_design_pattern.adapter_pattern.course_instance.ResultMsg;

public class LoginForWechatAdapter implements LoginAdapter{
    @Override
    public boolean support(Object adapter) {
        return adapter instanceof LoginForWechatAdapter;
    }

    @Override
    public ResultMsg login(String id, Object adapter) {
        return null;
    }
}
package com.knowledge.system.software_design_pattern.adapter_pattern.course_instance.adapter;

import com.knowledge.system.software_design_pattern.adapter_pattern.course_instance.ResultMsg;

public class PassportForThirdAdapter extends SignService implements IPassportForThird{
    @Override
    public ResultMsg loginForQQ(String id) {
        return processLogin(id,LoginForQQAdapter.class);
    }

    @Override
    public ResultMsg loginForWechat(String id) {
        return processLogin(id,LoginForWechatAdapter.class);
    }

    @Override
    public ResultMsg loginForToken(String token) {
        return processLogin(token,LoginForTokenAdapter.class);
    }

    @Override
    public ResultMsg loginForTelphone(String telphone, String code) {
        return processLogin(telphone,LoginForTelAdapter.class);
    }

    @Override
    public ResultMsg loginForRegist(String username, String passport) {
        super.regist(username,null);
        return super.login(username,null);
    }

    private ResultMsg processLogin(String key,Class<? extends LoginAdapter> clazz){
        try {
            LoginAdapter adapter=clazz.newInstance();
            if(adapter.support(adapter)){
                return adapter.login(key,adapter);
            }else{
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


}
package com.knowledge.system.software_design_pattern.adapter_pattern.course_instance.adapter;

import com.knowledge.system.software_design_pattern.adapter_pattern.course_instance.Member;
import com.knowledge.system.software_design_pattern.adapter_pattern.course_instance.ResultMsg;

public class SignService {
    public ResultMsg regist(String username,String password){
        return new ResultMsg(200,"注册成功",new Member());
    }
    public ResultMsg login(String username,String password){
        return  null;
    }
}
package com.knowledge.system.software_design_pattern.adapter_pattern.course_instance.adapter;

import com.alibaba.fastjson.JSON;
import com.knowledge.system.software_design_pattern.adapter_pattern.course_instance.ResultMsg;

public class Test {
    public static void main(String[] args) {
        IPassportForThird passportForThird=new PassportForThirdAdapter();
        ResultMsg msg=passportForThird.loginForQQ("1");
        System.out.println(JSON.toJSONString(msg));
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值