Java设计模式——Adapter(适配器)模式

2024-06-16 11:18

本文主要是介绍Java设计模式——Adapter(适配器)模式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

适配器模式保留现有类所提供的服务,向客户提供接口,以满足客户的期望。适配器模式可分为类适配器模式、对象适配器模式和标识适配器模式三种。

类适配器模式
拓展一个现有的类,并实现一个目标接口,将把客户的调用转变为调用现有类的方法。
这里写图片描述
对象适配器模式
拓展一个目标类,并把它委派给一个现有的类,将客户调用转发给现有类的实例。
这里写图片描述

  • 如果希望适配的方法没有在接口中指定时,就应该使用委托方式,而不是创建子类方式。即对象适配器模式。
  • 只要我们所适配的接口可以得到抽象类的支持,也必须使用对象适配器模式。
  • 如果适配器类需要从多个对象中提取信息,也应当使用对象适配器。

Swing中的JTable组件是应用对象适配器模式的很好例子。JTable组件通过调用TableModel接口中定义的方法获取表格
的相关信息,这样就可以很容易地写出一个适配器类,从域对象中获取用于填充表格的数据。
这里写图片描述

import javax.swing.table.*;
/*** Adapt a collection of rockets for display in a JTable.* * @author Steven J. Metsker*/
public class RocketTableModel extends AbstractTableModel {protected Rocket[] rockets;protected String[] columnNames = new String[] { "Name", "Price", "Apogee" };/*** Construct a rocket table from an array of rockets.* * @param rockets*            an array of rockets*/public RocketTableModel(Rocket[] rockets) {this.rockets = rockets;}/*** @return the number of columns in this table.*/public int getColumnCount() {return columnNames.length;}/*** @param index*            which column is interesting* @return the name of the indicated column*/public String getColumnName(int i) {return columnNames[i];}/*** @return the number of rows in this table.*/public int getRowCount() {return rockets.length;}/*** @param row*            which row is interesting* @param col*            which column is interesting* @return the value at the indicated row and column.*/public Object getValueAt(int row, int col) {switch (col) {case 0:return rockets[row].getName();case 1:return rockets[row].getPrice();case 2:return new Double(rockets[row].getApogee());default:return null;}}
}
import java.awt.Component;
import java.awt.Font;import javax.swing.*;
public class ShowRocketTable { public static void main(String[] args) {setFonts();JTable table = new JTable(getRocketTable());table.setRowHeight(36);JScrollPane pane = new JScrollPane(table);pane.setPreferredSize(new java.awt.Dimension(300, 100));display(pane, " Rockets");}public static void display(Component c, String title) {JFrame frame = new JFrame(title);frame.getContentPane().add(c);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  frame.pack();frame.setVisible(true);}private static RocketTableModel getRocketTable() {Rocket r1 = new Rocket("Shooter", 1.0, new Dollars(3.95), 50.0, 4.5);Rocket r2 = new Rocket("Orbit", 2.0, new Dollars(29.03), 5000, 3.2);return new RocketTableModel(new Rocket[] { r1, r2 });}private static void setFonts() {Font font = new Font("Dialog", Font.PLAIN, 18);UIManager.put("Table.font", font);UIManager.put("TableHeader.font", font);}
}
public class Dollars {public static final Dollars cent = new Dollars(0.01);static final int CENTS_PER_DOLLAR = 100;long cents;public Dollars(double value) {this.cents = Math.round(value * CENTS_PER_DOLLAR);}public boolean isZero() {return cents == 0;}public Dollars plus(Dollars that) {return new Dollars(1.0 * (this.cents + that.cents) / CENTS_PER_DOLLAR);}public Dollars times(int multiplier) {return new Dollars((this.cents * multiplier) / CENTS_PER_DOLLAR);}public Dollars dividedBy(int divisor) {double newCents = (1.0 * cents / divisor) / CENTS_PER_DOLLAR;return new Dollars(newCents);}public double dividedBy(Dollars that) {return (1.0 * this.cents) / that.cents;}public boolean isLessThan(Dollars that) {return this.cents < that.cents;}public String toString() {StringBuffer result = new StringBuffer("$");long dollars = cents / CENTS_PER_DOLLAR;result.append(dollars);result.append('.');long pennies = cents % CENTS_PER_DOLLAR;if (pennies < 10) result.append('0');result.append(pennies);return result.toString();}public boolean equals(Object obj) {if (!obj.getClass().equals(this.getClass()))return false;Dollars that = (Dollars) obj;return this.cents == that.cents;}public int hashCode() {return (int) cents;}public long asCents() {return cents;}
}
public class Rocket extends Firework {private double apogee;private double thrust;/*** Allow creation of empty objects to support reconstruction from persistent* store.*/public Rocket() {}/*** Create a rocket with all its expected properties. See the superclass for* descriptions of other parameters* * @param apogee*            The height (in meters) that the rocket is expected to reach* @param thrust*            The rated thrust (or force, in newtons) of this rocket*/public Rocket(String name, double mass, Dollars price, double apogee,double thrust) {super(name, mass, price);setApogee(apogee);setThrust(thrust);}/*** The height (in meters) that the rocket is expected to reach.*/public double getApogee() {return apogee;}public void setApogee(double value) {apogee = value;}/*** The rated thrust (or force, in newtons) of this rocket.*/public double getThrust() {return thrust;}public void setThrust(double value) {thrust = value;}
}
public class Firework {/*** @return a firework of the given name. This method supports a "Strategy"*         example, but it isn't really implemented.* @param name*            a name to lookup*/public static Firework lookup(String name) {return new Firework(name, 9.0, new Dollars(3));}/*** @return a random firework from our shelves. This method is not actually*         implemented -- it's here as part of a "Strategy" example.*/public static Firework getRandom() {return new Firework("Random firework", 10.0, new Dollars(15));}private String name;private double mass;private Dollars price;/*** Allow creation of empty objects to support reconstruction from persistent* store.*/public Firework() {}public Firework(String name, double mass, Dollars price) {setName(name);setMass(mass);setPrice(price);}/*** The unique name of this type of firework*/public String getName() {return name;}public void setName(String value) {name = value;}/*** The mass, in kilograms, of one instance of this type*/public double getMass() {return mass;}public void setMass(double value) {mass = value;}/*** The price (in dollars) of one instance of this type*/public Dollars getPrice() {return price;}public void setPrice(Dollars value) {price = value;}/*** @return a textual representation of this firework.*/public String toString() {return getName();}
}

这里写图片描述
JTable类有两个原因不能使用类适配器:

  1. 表适配器必须拓展现AbstractTableModel类,应此它不能再拓展现有的类;
  2. JTable类需要收集多个对象的数据,只有对象适配器才可以对多个对象进行适配。

今天培训的时候讲的一个例子感觉更易于理解适配器模式:

package test.lindl.t2;public interface China {void onChina();
}
package test.lindl.t2;public class ChinaPC implements China{@Overridepublic void onChina() {// TODO Auto-generated method stubSystem.out.println("This is a adapter for America!!");}}
package test.lindl.t2;public interface Usa {void onAmerica();
}
package test.lindl.t2;public class UsaPC implements Usa {@Overridepublic void onAmerica() {// TODO Auto-generated method stubSystem.out.println("This is a adapter for China!!");}}
package test.lindl.t2;public class Adapter implements Usa, China {private Usa usa;private China china;public Adapter(Usa usa) {this.usa = usa;}public Adapter(China china) {this.china = china;}@Overridepublic void onChina() {// TODO Auto-generated method stubusa.onAmerica();}@Overridepublic void onAmerica() {// TODO Auto-generated method stubchina.onChina();}}
package test.lindl.t2;public class Runner {public static void main(String[] args) {Usa usaPC = new UsaPC();China china = new ChinaPC();Usa adapter1 = new Adapter(china);adapter1.onAmerica();China adapter2 = new Adapter(usaPC);adapter2.onChina();}
}

这里写图片描述
话说学设计模式看head first系列还真不错
标识适配器模式
创建存根类MouseAdapter以后,在实现鼠标监听器类的时候,就不用实现MouseAdapter接口的所有方法
这里写图片描述

这篇关于Java设计模式——Adapter(适配器)模式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1066318

相关文章

Java 实用工具类Spring 的 AnnotationUtils详解

《Java实用工具类Spring的AnnotationUtils详解》Spring框架提供了一个强大的注解工具类org.springframework.core.annotation.Annot... 目录前言一、AnnotationUtils 的常用方法二、常见应用场景三、与 JDK 原生注解 API 的

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

Java中的StringBuilder之如何高效构建字符串

《Java中的StringBuilder之如何高效构建字符串》本文将深入浅出地介绍StringBuilder的使用方法、性能优势以及相关字符串处理技术,结合代码示例帮助读者更好地理解和应用,希望对大家... 目录关键点什么是 StringBuilder?为什么需要 StringBuilder?如何使用 St

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

如何在 Spring Boot 中实现 FreeMarker 模板

《如何在SpringBoot中实现FreeMarker模板》FreeMarker是一种功能强大、轻量级的模板引擎,用于在Java应用中生成动态文本输出(如HTML、XML、邮件内容等),本文... 目录什么是 FreeMarker 模板?在 Spring Boot 中实现 FreeMarker 模板1. 环

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll