首页 > 其他分享 >设计模式详解:适配器模式

设计模式详解:适配器模式

时间:2024-04-01 15:32:14浏览次数:116  
标签:string 适配器 详解 void Print 设计模式 Banner public

什么是适配器模式?

在程序设计中,经常会存在一种情况:现有的程序无法直接使用,需要做适当的变换才能使用。

而用于填补“现有程序”和“所需程序”之间差异的设计模式就是适配器模式(Adapter)。 

不理解?没关系,跟你分享一个生活中的例子!

我们在使用笔记本电脑时通常会插上电源,难道我们直接让220v的交流电通到电脑上吗?显然不是。通常,我们会使用AC适配器将家用的220v的交流电转化为电脑所需的直流电。这个就是适配器的工作,位于实际情况与需求之间,填补两者的差异


为什么要使用适配器模式?

那为什么在程序设计中要使用适配器模式呢?答案很简单,为了提高代码的复用性,减少重复开发。


适配器模式如何实现?

适配器模式的实现有两种方式:

  • 类适配器模式(使用继承和接口实现的适配器)
  • 对象适配器模式(使用委托的适配器)

场景描述

下面用一个场景示例来介绍适配器模式的两种实现。

现有一个类Banner和一个接口Print。

Banner类:包含两个方法showWithParen()、showWithAster()。

showWithParen(): 为字符串添加一对括号(),如输入"hello",输出"(hello)"

showWithAster(): 为字符串添加一对**,如输入"hello",输出"*hello*"

Print接口:声明了两种方法printWeak()、printStrong()。

printWeak()方法需要实现功能:为字符串添加一对括号(),如输入"hello",输出"(hello)"
printStrong()方法需要实现功能:为字符串添加一对星号**,如输入"hello",输出"*hello*"

class Banner{
    private String string;

    public Banner(String string){
        this.string = string;
    }

    public void showWithParen(){
        System.out.println("(" + string + ")");
    }

    public void showWithAster(){
        System.out.println("*" + string + "*");
    }
}
interface Print{
    public abstract void printWeak();
    public abstract void printStrong();
}

现在我们需要实现Print接口里的方法,我们应该如何使用适配器模式?


方式一:类适配器模式

编写一个类PrintBanner继承Banner类实现Print接口,在重写printWeak()和printStrong()的时候分别调用Banner类中的showWithParen()和showWithAster()方法。

class PrintBanner extends Banner implements Print{
    public PrintBanner(String string) {
        super(string);
    }

    //我们只需要调用父类Banner中的方法即可
    @Override
    public void printWeak() {
        showWithParen();
    }

    @Override
    public void printStrong() {
        showWithAster();
    }
}

完整代码如下:

/**
 * Author: Jayden
 * Date: 2024/4/1 10:52
 * Version: 1.0
 * Description:
 *      Adapter(适配器)模式有以下两种:
 *          ①类适配器模式(使用继承的适配器)
 *          ②对象适配器模式(使用委托的适配器)
 *
 *
 *      现有:
 *          Banner类:包含两个方法showWithParen()、showWithAster()
 *              showWithParen(): 为字符串添加一对括号(),如输入"hello",输出"(hello)"
 *              showWithAster(): 为字符串添加一对**,如输入"hello",输出"*hello*"
 *
 *          Print接口:声明了两种方法printWeak()、printStrong()
 *
 *
 *      需求:
 *          printWeak()方法需要实现下述功能:
 *              为字符串添加一对括号(),如输入"hello",输出"(hello)"
 *          printStrong()方法需要实现下述功能:
 *              为字符串添加一对星号**,如输入"hello",输出"*hello*"
 *
 *
 *      具体实现:
 *          编写一个类实现Print接口,继承Banner类,在重写printWeak()和printStrong()的时候分别调用Banner类中的showWithParen()和
 *          showWithAster()方法。精髓所在!!避免了代码重复!
 */
public class Demo01 {
    public static void main(String[] args) {
        Print printBanner = new PrintBanner("hello");
        printBanner.printWeak();
        printBanner.printStrong();
    }
}

class Banner{
    private String string;

    public  Banner(String string){
        this.string = string;
    }

    public void showWithParen(){
        System.out.println("(" + string + ")");
    }

    public void showWithAster(){
        System.out.println("*" + string + "*");
    }
}

//我们要做的就是利用现有的代码实现这个接口里的方法,而不是重新写一遍写过的代码
interface Print{
    public abstract void printWeak();
    public abstract void printStrong();
}

class PrintBanner extends Banner implements Print{
    public PrintBanner(String string) {
        super(string);
    }

    //我们只需要调用父类Banner中的方法即可
    @Override
    public void printWeak() {
        showWithParen();
    }

    @Override
    public void printStrong() {
        showWithAster();
    }
}

方式二:对象适配器模式

Banner类不变,Print接口变成抽象类后,我们又该如何处理?

创建一个类PrintBanner继承Print,然后在PrintBanner内部维护一个Banner对象,调用Banner对象中已经实现的showWithPren()和showWithAster()方法即可,用这个对象去调用已实现的方法即为委托。

完整代码如下:

package adapterPattern.pattern02;

/**
 * Author: Jayden
 * Date: 2024/4/1 11:24
 * Version: 1.0
 * Description:
 *      该示例实现对象适配器模式(使用委托的适配器)
 */
public class Demo02 {
    public static void main(String[] args) {
        Print printBanner = new PrintBanner("hello");
        printBanner.printWeak();
        printBanner.printStrong();
    }
}

class Banner{
    private String string;

    public  Banner(String string){
        this.string = string;
    }

    public void showWithParen(){
        System.out.println("(" + string + ")");
    }

    public void showWithAster(){
        System.out.println("*" + string + "*");
    }
}

abstract class Print{
     abstract void printWeak();
     abstract void printStrong();
}


//采用对象适配器模式后,该类的内部会维护一个Banner对象,用这个对象去调用已实现的方法即为委托
class PrintBanner extends Print{
    private Banner banner;

    public PrintBanner(String s){
        this.banner = new Banner(s);
    }

    @Override
    void printWeak() {
        banner.showWithParen();
    }

    @Override
    void printStrong() {
        banner.showWithAster();
    }
}

有人可能会有疑问,为什么main函数中要使用  Print printBanner = new PrintBanner("hello);

而不使用  PrintBanner printBanner = new PrintBanner("hello);

因为示例程序主要想强调Print方法的实现,PrintBanner因为实现了Print接口,继承了Banner类,所以内部会有多种方法。而Print接口中只有printWeak()和printStrong()两种方法,可以更明确地表明程序的意图。

标签:string,适配器,详解,void,Print,设计模式,Banner,public
From: https://blog.csdn.net/m0_63352294/article/details/137232166

相关文章

  • 苹果开发者账号注册及证书生成方法详解
    转载:注册苹果开发者账号的方法在2020年以前,注册苹果开发者账号后,就可以生成证书。但2020年后,因为注册苹果开发者账号需要使用AppleDeveloperapp注册开发者账号,所以需要缴费才能创建ios证书了。所以新政策出来后,注册苹果开发者账号,并缴费成为苹果开发者,才能手工创建证书......
  • 设计模式之组合模式
    概念:将对象组合成树形结构以表示“部分——整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。组合模式有三个角色:抽象构件:定义公有属性和方法。叶子结点:树形结构的底层结点,没有子结点,实现抽象构件的所有操作。中间结点:叶子结点之前的结点,有子结点。组合模......
  • 微信支付商户自动续费功能申请开通详解,申请自动续费的意义!
    在这个快速发展的数字时代,微信支付已经成为我们日常生活中不可或缺的一部分。作为商户,我们总是在寻找提高效率和客户满意度的方法。现在,有了微信支付的自动续费功能,我们可以做到这一点。一、一键开通,轻松管理自动续费功能的开通非常简单,但是关键的关键你需要找对可以协助开......
  • C#中的设计模式
    设计模式在C#和WPF日常开发中扮演着重要角色,它们提供了一套通用的解决方案,用于解决软件设计中的常见问题。以下是关于设计模式的知识点,以及可能会在面试中被问到的一些问题和答案:设计模式的知识点:创建型模式:创建型模式用于处理对象的创建过程,包括单例模式、工厂模式、抽......
  • SCADA详解
     低代码、配置式web组态软件-BY组态:by组态[web组态插件]远程数据采集和监控为主要功能的SCADA系统和DCS、PLC一样,是工业过程自动化和信息化不可或缺的基本系统。SCADA系统SCADA是SupervisoryControIAndData AcquiSitionSystem(数据采集与监视控制系统)的缩写,SCADA系......
  • 什么是Docker引擎架构,Docker引擎架构详解及Vmware,CentOS7、Docker引擎的安装,CentOS7常
    Dockere引擎架构详解2.1Docker引擎发展历程2.1.1首发版本架构       Docker在首次发布时,其引擎有两个核心组件构成,LXC(LinuxContainer)与DockerDaemon构成。不过该架构依赖于LXC,使得Docker存在严重的问题:依赖于外部工具对Docker来说存在着巨大的生存风险。......
  • Django xadmin安装及使用详解
    Djangoxadmin安装及使用详解一.简介xadmin是一个开源项目。针对于djangoadmin,页面美化程度,功能不完善等问题,额外开发的一个模块。目前xadmin的最新版本已经是xadmin3.0,但是xadmin3.0已经变成了一个纯前端项目,有兴趣的同学可以自己研究下。目前作者已经不对x......
  • 大语言模型中常用的旋转位置编码RoPE详解:为什么它比绝对或相对位置编码更好?
    自2017年发表“ AttentionIsAllYouNeed ”论文以来,Transformer架构一直是自然语言处理(NLP)领域的基石。它的设计多年来基本没有变化,随着旋转位置编码(RoPE)的引入,2022年标志着该领域的重大发展。旋转位置嵌入是最先进的NLP位置嵌入技术。大多数流行的大型语言模......
  • 详解SSL证书系列(8)了解HTTPS及和HTTP的区别
    上一篇我们介绍了HTTP协议的三大缺点,那么怎么避免和解决HTTP的缺点呢,是时候请出我们的HTTPS了,那HTTPS和HTTP有什么区别呢? HTTP加上加密处理和认证以及完整性保护后即是HTTPS如果在HTTP协议通信过程中使用未经加密的明文,比如在Web页面中输入信用卡号,如果这条通信线路遭到窃听,......
  • 深入解析:Linux目录结构及其功能详解
    Linux目录结构是Linux操作系统中的核心组成部分,它承载着整个系统的文件和资源。本文将带领读者深入解析Linux的目录结构,详细介绍各个目录的功能与用途,帮助读者更好地理解和使用Linux系统。从根目录“/”开始,我们将逐一探讨各个子目录,如“/bin”、“/etc”、“/home”等,揭示......