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 StringBuilder 实现原理全攻略

《JavaStringBuilder实现原理全攻略》StringBuilder是Java提供的可变字符序列类,位于java.lang包中,专门用于高效处理字符串的拼接和修改操作,本文给大家介绍Ja... 目录一、StringBuilder 基本概述核心特性二、StringBuilder 核心实现2.1 内部

SpringBoot AspectJ切面配合自定义注解实现权限校验的示例详解

《SpringBootAspectJ切面配合自定义注解实现权限校验的示例详解》本文章介绍了如何通过创建自定义的权限校验注解,配合AspectJ切面拦截注解实现权限校验,本文结合实例代码给大家介绍的非... 目录1. 创建权限校验注解2. 创建ASPectJ切面拦截注解校验权限3. 用法示例A. 参考文章本文

Java中字符编码问题的解决方法详解

《Java中字符编码问题的解决方法详解》在日常Java开发中,字符编码问题是一个非常常见却又特别容易踩坑的地方,这篇文章就带你一步一步看清楚字符编码的来龙去脉,并结合可运行的代码,看看如何在Java项... 目录前言背景:为什么会出现编码问题常见场景分析控制台输出乱码文件读写乱码数据库存取乱码解决方案统一使

Java Stream流与使用操作指南

《JavaStream流与使用操作指南》Stream不是数据结构,而是一种高级的数据处理工具,允许你以声明式的方式处理数据集合,类似于SQL语句操作数据库,本文给大家介绍JavaStream流与使用... 目录一、什么是stream流二、创建stream流1.单列集合创建stream流2.双列集合创建str

springboot集成easypoi导出word换行处理过程

《springboot集成easypoi导出word换行处理过程》SpringBoot集成Easypoi导出Word时,换行符n失效显示为空格,解决方法包括生成段落或替换模板中n为回车,同时需确... 目录项目场景问题描述解决方案第一种:生成段落的方式第二种:替换模板的情况,换行符替换成回车总结项目场景s

SpringBoot集成redisson实现延时队列教程

《SpringBoot集成redisson实现延时队列教程》文章介绍了使用Redisson实现延迟队列的完整步骤,包括依赖导入、Redis配置、工具类封装、业务枚举定义、执行器实现、Bean创建、消费... 目录1、先给项目导入Redisson依赖2、配置redis3、创建 RedissonConfig 配

SpringBoot中@Value注入静态变量方式

《SpringBoot中@Value注入静态变量方式》SpringBoot中静态变量无法直接用@Value注入,需通过setter方法,@Value(${})从属性文件获取值,@Value(#{})用... 目录项目场景解决方案注解说明1、@Value("${}")使用示例2、@Value("#{}"php

SpringBoot分段处理List集合多线程批量插入数据方式

《SpringBoot分段处理List集合多线程批量插入数据方式》文章介绍如何处理大数据量List批量插入数据库的优化方案:通过拆分List并分配独立线程处理,结合Spring线程池与异步方法提升效率... 目录项目场景解决方案1.实体类2.Mapper3.spring容器注入线程池bejsan对象4.创建

线上Java OOM问题定位与解决方案超详细解析

《线上JavaOOM问题定位与解决方案超详细解析》OOM是JVM抛出的错误,表示内存分配失败,:本文主要介绍线上JavaOOM问题定位与解决方案的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一、OOM问题核心认知1.1 OOM定义与技术定位1.2 OOM常见类型及技术特征二、OOM问题定位工具

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建