百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程网 > 正文

深入浅出Java设计模式之适配器模式

yuyutoo 2024-10-20 13:08 7 浏览 0 评论

通常,客户类(clients of class)通过类的接口访问它提供的服务。有时,现有的类(existing class)可以提供客户类的功能需要,但是它所提供的接口不一定是客户类所期望的。这是由于现有的接口太详细或者缺乏详细或接口的名称与客户类所查找的不同等诸多不同原因导致的。

在这种情况下,现有的接口需要转化(convert)为客户类期望的接口,这样保证了对现有类的重用。如果不进行这样的转化,客户类就不能利用现有类所提供的功能。适配器模式(Adapter Pattern)可以完成这样的转化。适配器模式建议定义一个包装类,包装有不兼容接口的对象。这个包装类指的就是适配器(Adapter),它包装的对象就是适配者(Adaptee)。适配器提供客户类需要的接口,适配器接口的实现是把客户类的请求转化为对适配者的相应接口的调用。换句话说:当客户类调用适配器的方法时,在适配器类的内部调用适配者类的方法,这个过程对客户类是透明的,客户类并不直接访问适配者类。因此,适配器可以使由于借口不兼容而不能交互的类可以一起工作(work together)。

在上面讨论的接口

  • 不是指在JAVA编程语言中接口的概念,虽然类的接口可以通过JAVA借扩来定义。
  • 不是指由窗体和GUI控件所组成的GUI应用程序的用户接口。
  • 而是指类所报漏的,被其他类调用的编程接口,

类适配器(Class Adapter)VS对象适配器(Object Adapter)

适配器总体上可以分为两类:类适配器(Class Adapter)VS对象适配器(Object Adapter)

类适配器

类适配器是通过继承类适配者类(Adaptee Class)实现的,另外类适配器实现客户类所需要的接口。当客户对象调用适配器类方法的时候,适配器内部调用它所继承的适配者的方法。

对象适配器

对象适配器包含一个适配器者的引用(reference),与类适配器相同,对象适配器也实现了客户类需要的接口。当客户对象调用对象适配器的方法的时候,对象适配器调它所包含的适配器者实例的适当方法。

下表是类适配器(Class Adapter)和对象适配器(Object Adapter)的详细不同:

补充

类适配器(Class Adapter) 对象适配器(Object Adapter)

基于继承概念 利用对象合成

只能应用在适配者是接口,不能利用它子类的接口,当类适配器建立时,它就静态地与适配者关联 可以应用在适配者是接口和它的所有子类,因为适配器是作为适配者的子类,所以适配器可能会重载适配者的一些行为。

注意

在JAVA中,子类不能重载父类中声明为final的方法。 不能重载适配者的方法。

字面上,不能重栽只是因为没有继承。但是适配器提供包装方法可以按需要改变行为。

客户类对适配者中声明为public的接口是可见的, 客户类和适配者是完全不关联的,只有适配器才能感知适配者接口。

在JAVA应用程序中

适用于期待的接口是JAVA接口的形式,而不是抽象地或具体地类的形式。这是因为JAVA编程语言只允许单继承。因此,类适配器设计成适配者的子类。

在JAVA应用程序中

适用于当客户对象期望的接口是抽象类的形式,同时也可以应用于期望接口是Java接口的形式。

例子

让我们建立一个验证给定客户地址的应用。这个应用是作为大的客户数据管理应用的一部分。

让我们定义一个Customer类:

Customer

Figure 20.1: Customer Class

Listing 20.1: Customer Class

class Customer {
   public static final String US = "US";
   public static final String CANADA = "Canada";
   private String address;
   private String name;
   private String zip, state, type;
   public Boolean isValidAddress() {
   …
   …
   
 }
   public Customer(String inp_name, String inp_address,
   String inp_zip, String inp_state,
   String inp_type) {
   name = inp_name;
   address = inp_address;
   zip = inp_zip;
   state = inp_state;
   type = inp_type;
   
 }
   
}
//end of class

不同的客户对象创建Customer对象并调用(invoke)isValidAddress方法验证客户地址的有效性。为了验证客户地址的有效性,Customer类期望利用一个地址验证类(address validator class),这个验证类提供了在接口AddressValidator中声明的接口。

Listing 20.2: AddressValidator as an Interface

public interface AddressValidator {
   public Boolean isValidAddress(String inp_address,
   String inp_zip, String inp_state);
   
}
//end of class

让我们定义一个USAddress的验证类,来验证给定的U.S地址。

Listing 20.3: USAddress Class

class USAddress implements AddressValidator {
   public Boolean isValidAddress(String inp_address,
   String inp_zip, String inp_state) {
   if (inp_address.trim().length() < 10)
   return false;
   if (inp_zip.trim().length() < 5)
   return false;
   if (inp_zip.trim().length() > 10)
   return false;
   if (inp_state.trim().length() != 2)
   return false;
   return true;
   
 }
   
}
//end of class

USAddress类实现AddressValidator接口,因此Customer对象使用USAddress实例作为验证客户地址过程的一部分是没有任何问题的。

Listing 20.4: Customer Class Using the USAddress Class

class Customer {
   …
   …
   public Boolean isValidAddress() {
   //get an appropriate address validator
   AddressValidator validator = getValidator(type);
   //Polymorphic call to validate the address
   return validator.isValidAddress(address, zip, state);
   
 }
   private AddressValidator getValidator(String custType) {
   AddressValidator validator = null;
   if (custType.equals(Customer.US)) {
   validator = new USAddress();
   
 }
   return validator;
   
 }
   
}
//end of class

Figure 20.2: Customer/USAddress Validator Class Association

但是当验证来自加拿大的客户时,就要对应用进行改进。这需要一个验证加拿大客户地址的验证类。让我们假设已经存在一个用来验证加拿大客户地址的使用工具类CAAddress。

Java肖先生:专注于Java开发技术的研究与知识分享!

————END————

  • 点赞(感谢)
  • ...
  • 转发(感谢)
  • ...
  • 关注(感谢)
  • ...

相关推荐

Docker部署 chatgpt-web-midjourney-proxy:开启一站式AI与绘图

ChatGPT和Midjourney的结合无疑是创新性的突破。ChatGPT作为强大的语言模型,能够为用户提供智能的对话和文本生成服务。而Midjourney则以其出色的绘画能力,能够根据...

Cacti监控服务器配置教程(基于CentOS+Nginx+MySQL+PHP环境搭建)

具体案例:局域网内有两台主机,一台Linux、一台Windows,现在需要配置一台Cacti监控服务器对这两台主机进行监控...

那些少为人知却非常有意思好用的 Chrome 扩展

ChromeWebStoreSessionManager要睡觉了,还有网页没看完怎么办?等明天点开歷史记录重新加载?No!有这个保存当前打开的链接,下回直接打开一串网址,好顶赞有木有!!!chr...

分享一款轻量级 HTTP(S) 代理 TinyProxy

概述众所周知,我们常用的Web服务器Nginx/Apache都可以很方便的用来做为正向或反向代理服务器使用。但是它们都并不支持HTTPS的正向代理。Nginx做为正向代理不支持HT...

深入理解 WebSecurityConfigurerAdapter「源码篇」

我们继续来撸SpringSecurity源码,今天来撸一个非常重要的WebSecurityConfigurerAdapter。我们的自定义都是继承自WebSecurityConfigurer...

RPC、Web Service等几种远程监控通信方式对比

几种远程监控通信方式的介绍一.RPCRPC使用C/S方式,采用http协议,发送请求到服务器,等待服务器返回结果。这个请求包括一个参数集和一个文本集,通常形成“classname.meth...

老酒好喝,5G时代数据中心柴油发电机组以GPRS方式接入动环监控

背景:随着手机的普及,电信运营商基站越建越多,网络覆盖范围也越来越广,基本上随时随地都能通过运营商的网络上网冲浪,这给我们传统的通过有线方式实现的动环监控也提带来了新的启发:对于不具备有线传输条件的的...

为了春节红包大战,微信做了一次成功的预热!

经过上午的预告,微信在今天下午17:00正式推出了微信红包新玩法——红包照片。微信用户在朋友圈点击照片发送按钮,会看到“红包照片”选项,用户在选择发布照片之后,这张照片将被模糊处理后,再发送到朋友...

Proxy-Lite实战:3步部署+2个案例,轻松掌握轻量级网页自动化

大家好,我是何三,80后老猿,独立开发者一、Proxy-Lite模型概述...

会Python?那么你一定要试一试mitmproxy

mitmproxy是一款工具,也可以说是python的一个包,使用这个工具可以在命令行上进行抓包(现在也可以在web页面上查看上抓的数据包了),还可以对所抓到的包进行脚本处理,非常有用。和...

十大Web安全扫描工具,你知道哪些?

初入门时,喜欢将目标站点直接丢扫描器,慢慢等扫描结果,极度依赖Web扫描器;而有一些漏洞高手,善于运用运用各种工具但并不依赖工具,经常可以找到扫描工具发现不了的漏洞。一款好用的Web扫描器对于白帽子来...

鸿蒙5网页开发神器 ArkWeb:让 Web 和原生手拉手跳舞

你有没有想过,在鸿蒙应用里既能用原生代码写高性能界面,又能直接塞进一个网页?这听起来有点像把汉堡和披萨拼在一起,但ArkWeb(方舟Web)真的做到了!今天咱们就聊聊这个神奇的工具,看看它如何让...

MapReduce过程详解及其性能优化(详细)

从JVM的角度看Map和ReduceMap阶段包括:第一读数据:从HDFS读取数据1、问题:读取数据产生多少个Mapper??Mapper数据过大的话,会产生大量的小文件,由于Mapper是基于虚拟...

大数据平台建设需要掌握的14个知识

Q1、大数据分析中的实时推荐是如何实现的?@rein07某证券系统架构师:实时推荐需要使用实时处理框架结合推荐算法,从而做到对数据的实时处理和推荐。实时处理框架有Storm、Flink、Spark...

HDFS可视化管理系统设计与实现(hdfs的可靠性设计,主要依靠哪些机制来实现)

摘要:Hadoop工具核心模块包括分布式文件系统(HadoopDistributedFileSystem,HDFS)和分布式编程模型MapReduce,其中HDFS是Hadoop数据存储处理的...

取消回复欢迎 发表评论: