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

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)