设计模式之适配器模式(代码片段)

fefi521 fefi521     2023-01-13     474

关键词:

适配器模式

什么是适配器模式

  • 适配器模式属于结构型模式,可以使得两个不匹配的接口可以协同工作。
  • 适配器模式允许两个不匹配的类通过将其中一个接口类型转换成另一个客户端期望的接口类型,从而达到二者协同工作。
  • 适配器模式也叫包装器。
    适配器模式在 Gang of Four 书中原始的定义如下:

    将一个类的接口类型转换成另一个客户端期望的接口类型。
    适配器可以让多个类协同工作即使他们本来是不匹配的接口类型。

适配器模式的应用场景

  • 考虑一个这样的场景,你在印度购买了一个轻便的笔记本,最近你刚搬到英国。但是英国的电子插座和印度的不一样。因此,你的笔记本不能直接工作了。
    你必须去购买一个适配器,可以为你的印度笔记本可以在英国的插座上充电。

  • 当你有一个需要与新系统集成的遗留接口时,新系统不能直接接收遗留库的工作方式。由于遗留库不再进行开发了,所以我们需要使用适配器促使两种不同的类型进行工作。

  • 你使用 Mac 时,经常需要转接头才能连接到会议室的投影仪,这个转接头,就是适配器,使得原本 Mac 、投影仪互不相容的两个物件可以协同工作。

适配器模式的特点

  • 客户端通过使用目标接口调用适配器的方法向适配器发起请求。
  • 适配器通过适配器接口将请求转换成适配者的一个或多个调用。
  • 客户端收到调用结果,并且不感知存在一个适配器在做这个转换工作。

何时使用适配器模式

  • 如果你想要将已经存在的类和他们的接口类型去匹配你最后需要的接口类型,就可以使用适配器模式。
  • 如果你想创建可重用类以帮助在不匹配的两个类之间进行接口式交互。

适配器模式示例

劳埃德银行是一家提供全球性服务的国际性银行。境外账户持有人的税率为 0.03%。
在印度,它提供2种类型的账户,普通和白金。税法不适用于印度账户。
现在离岸账户就匹配不了印度账户了。
所以需要设计出一个账户适配器 AccountAdapter 促使2种不同的账户类型还可以继续一块工作。

这个示例的交互图如下所示。
在这里,客户端仅仅需要调用适配器的 getBalance() 方法。
适配器调用适配者的 getOffshoreBalance() 方法并返回客户端期望的结果。
适配器内部的 getBalance() 方法将会通过扣除税金来计算账户余额。

技术分享图片

同时它持有适配者的一个实例。
这样使得客户端和适配者完全解耦。只有适配器知道它们两个(客户端、适配者)。

技术分享图片

OffshoreAccount.java

package org.byron4j.cookbook.designpattern.adapter;


/**
 * 离岸账户
 */
public class OffshoreAccount 

    private double balance;

    /**税率*/
    private static final double TAX_RATE = 0.04;

    public OffshoreAccount(final double balance) 
        this.balance = balance;
    

    public double getTaxRate() 
        return TAX_RATE;
    

    public double getOffshoreBalance() 
        return balance;
    

    public void debit(final double debit) 
        if (balance >= debit) 
            balance -= debit;
        
    

    public void credit(final double credit) 
        balance += balance;
    


Account.java

package org.byron4j.cookbook.designpattern.adapter;

/**
 * 账户接口类型
 */
public interface Account 
    /**
     * 获取账户余额
     * @return
     */
    public double getBalance();

    /**
     * 是否可以透支
     * @return
     */
    public boolean isOverdraftAvailable();

    /**
     * 贷款; 贷款后账户余额增多
     * @param credit
     */
    public void credit(final double credit);


AbstractAccount.java

package org.byron4j.cookbook.designpattern.adapter;

public class AbstractAccount implements Account 
    /**
     * 账户余额
     */
    private double balance;
    /**
     * 是否可以透支
     */
    private boolean isOverdraftAvailable;

    public AbstractAccount(final double size) 
        this.balance = size;
    

    @Override
    public double getBalance() 
        return balance;
    

    @Override
    public boolean isOverdraftAvailable() 
        return isOverdraftAvailable;
    

    public void setOverdraftAvailable(boolean isOverdraftAvailable) 
        this.isOverdraftAvailable = isOverdraftAvailable;
    

    @Override
    public String toString() 
        return getClass().getSimpleName() + " Balance=" + getBalance()
                + " Overdraft:" + isOverdraftAvailable();
    

    @Override
    public void credit(final double credit) 
        balance += credit;
    


PlatinumAccount.java

package org.byron4j.cookbook.designpattern.adapter;

/**
 * 白金帐户: 可以透支
 */
public class PlatinumAccount extends AbstractAccount 

    public PlatinumAccount(final double balance) 
        super(balance);
        // 可以透支
        setOverdraftAvailable(true);
    


StandardAccount.java

package org.byron4j.cookbook.designpattern.adapter;

/**
 * 普通账户: 不能透支
 */
public class StandardAccount extends AbstractAccount 

    public StandardAccount(final double balance) 
        super(balance);
        // 不能透支
        setOverdraftAvailable(false);
    



AccountAdapter.java

package org.byron4j.cookbook.designpattern.adapter;

/**
 * 账户适配器; 适配器继承于目标账户。
 * 适配器(转接头)的目标是将离岸账户(会议室中的Mac电脑)转为 AbstractAccount(可以连接投影仪)
 */
public class AccountAdapter extends AbstractAccount 

    /**需要被适应的账户--适配者*/
    private OffshoreAccount offshoreAccount;

    /**
     *
     * @param offshoreAccount  适配者--会议室中的 mac 电脑
     */
    public AccountAdapter(final OffshoreAccount offshoreAccount) 
        super(offshoreAccount.getOffshoreBalance());

        // 适配器持有适配者的引用
        this.offshoreAccount = offshoreAccount;
    

    /**
     * 计算扣除税款后的离岸账户余额
     * @return
     */
    @Override
    public double getBalance() 
        // 离岸税率
        final double taxRate = offshoreAccount.getTaxRate();

        // 离岸账户余额
        final double grossBalance = offshoreAccount.getOffshoreBalance();

        // 需要扣除的税款
        final double taxableBalance = grossBalance * taxRate;

        // 扣除离岸税款后的账户余额
        final double balanceAfterTax = grossBalance - taxableBalance;

        return balanceAfterTax;
    


AdapterTest.java


package org.byron4j.cookbook.designpattern;

import org.byron4j.cookbook.designpattern.adapter.AccountAdapter;
import org.byron4j.cookbook.designpattern.adapter.OffshoreAccount;
import org.byron4j.cookbook.designpattern.adapter.StandardAccount;
import org.junit.Test;

public class AdapterTest 
    @Test
    public void test()
        StandardAccount sa = new StandardAccount(2000);
        System.out.println("Account Balance= " + sa.getBalance());

        //Calling getBalance() on Adapter
        AccountAdapter adapter = new AccountAdapter(new OffshoreAccount(2000));
        System.out.println("Account Balance= " + adapter.getBalance());
    

设计模式之适配器模式(代码片段)

设计模式之适配器模式Intro适配器模式(Adapter),将一个类的接口适配成用户所期待的。一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。也被称为Wrapper模... 查看详情

设计模式之适配器模式(代码片段)

适配器模式什么是适配器模式适配器模式属于结构型模式,可以使得两个不匹配的接口可以协同工作。适配器模式允许两个不匹配的类通过将其中一个接口类型转换成另一个客户端期望的接口类型,从而达到二者协同工作。适配... 查看详情

设计模式之适配器模式(代码片段)

前言本节学习结构型中的适配器模式。适配器模式将一个类的接口,转换成客户期望的另一个接口。适配器类似我们生活中将安卓充电头转化为苹果充电头的转化器一样。适配另一方的功能,使得两方能亲密无间的合作。代码实... 查看详情

设计模式之适配器模式(代码片段)

适配器模式1.简要概述2.模式分类3.模式结构4.实现代码5.优点好处6.缺点弊端7.应用场景8.应用示例1.简要概述适配器模式就是将一个类的接口转换成客户需要的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的... 查看详情

设计模式之adapter模式(代码片段)

作用:使不同的类之间进行协调配合(220V的电压经过适配器给12V的电脑供电) Adapt模式有以下两种:1.类适配器模式(使用继承的适配器) UML类图:后补Banner类:publicclassBanner//220伏电压privateStringstring;publicBanner(Stringstring... 查看详情

设计模式之适配器模式(代码片段)

  适配器就是一种适配中间件,它存在于不匹配的二者之间,用于连接二者,将不匹配变得匹配,简单点理解就是平常所见的转接头,转换器之类的存在。  适配器模式有两种:类适配器、对象适配器、接口适配器  前二... 查看详情

设计模式之适配器模式(代码片段)

首先贴个网址https://blog.csdn.net/elegant_shadow/article/details/5006175感谢博主的分享,阐述的很清楚博主理解的很深刻,特别是这句:适配是为了实现某种目的而为一个源类暂时性的加上某种方法,但是不破坏原类的结构博主说的太好了,我... 查看详情

揭秘设计模式之适配器模式(代码片段)

适配器模式简介适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。属于结构性模式。适用场景:已经存在的类的接口不符合我们... 查看详情

复习23种设计模式之适配器模式(代码片段)

一,前言  刚才在复习适配器模式时搜到了一张图片很有意思简单明了解释了适配器模式的思想,即将两种或以上的不适合的接口对接起来。 二、实战   假设我们需要对接一个播放器接口A和一个MP4接口B  首先,... 查看详情

设计模式之设配器模式(代码片段)

 适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口。 作用(解决的问题):Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。 组成: 1、目标接口(Target):客户... 查看详情

设计模式之桥接模式(代码片段)

本文通过老王和小王买车,引出设计模式中的结构型设计之桥接模式,接着说明设计型模式的概念和代码实现,为了加深理解,会说明适配器设计模式在JDBC中的应用,最后谈谈桥接模式和适配器模式的总结。读者可以拉取完整... 查看详情

设计模式之代理模式适配器模式和外观模式(代码片段)

  编写基于另一组类的包装器接口是一项常见的API设计任务,例如,你的工作可能是维护一个大型的遗留代码库,相比重构所有代码,你更愿意审计一个新的,更简洁的API,以隐藏所有的底层遗留代码;或者你可能已经编写了... 查看详情

headfirst设计模式之适配器模式与外观模式(代码片段)

HeadFirst设计模式之适配器模式与外观模式前言:之前讲过装饰者模式,将对象包装起来并赋予新的职责,这一章我们也会将对象进行包装,只不过是让它们看起来不像自己而像是别的东西。这样就可以在设计中将... 查看详情

java设计模式之适配器模式(代码片段)

一、概述:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。二、解决的问题:即Adapter模式使得原本由于接口不兼容而不能一起工作的那些类... 查看详情

java设计模式之适配器模式(代码片段)

一、概述:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。二、解决的问题:即Adapter模式使得原本由于接口不兼容而不能一起工作的那些类... 查看详情

java设计模式之适配器学习与掌握(代码片段)

文章目录定义与特点优点缺点模式的结构与实现模式的结构类适配器模式实现对象适配器模式实现模式应用场景模式的扩展定义与特点将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工... 查看详情

设计模式学习笔记之适配器模式(代码片段)

什么是适配器模式?适配器模式(有时候也称包装样式或者包装)就是将一个类的接口适配成用户所期待的。一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一... 查看详情

gof23设计模式之适配器模式(代码片段)

GOF23设计模式之适配器模式结构型模式:核心作用:是从程序的结构上实现松耦合,从而可以扩大整体的类结构,用来解决更大的问题。分类:适配器模式、代理模式、桥接模式、装饰模式、组合模式、外观模式、享元模式什么... 查看详情