您的位置:首页 > 编程语言 > Java开发

深入浅出设计模式(五):7.适配器模式

2016-01-12 18:55 609 查看
前面讲完了创建型模式,这里开始,我将讲下7种结构型模式:适配器模式、装饰模式、代理模式、外观模式、桥接模式、组合模式、享元模式。其中对象的适配器模式是各种模式的起源,我们看下面的图:



7.适配器模式(Adapter)

当一个系统需要使用另一个系统提供的外部接口,而这个外部接口与目前系统使用的接口不兼容时,就需要使用适配器模式,适配器模式就是将一个系统的接口转换成另外一种形式,从而使原来不能直接使用的接口变得可以使用。

哪里会使用到适配器模式

比如:

财务系统要使用人事系统的接口,而人事系统来不及写,财务系统又不能停下来等,这时两种解决办法:一种是双方事先定好要提供的接口方法,包括方法名、参数、返回值等;另一种是双方各自开发自己的程序,等将来提供了接口再进行整合,此时就需要适配器模式进行开发

有时候需要使用外部购买的系统提供的接口,或者使用很久以前的接口(已经不再维护),或者系统对方不提供源代码,这时需适配器模式将购买的系统接口转成自己需要的接口

如java的接口定义了8个方法,而一个客户端使用2个,另一个客户端只是用1个,如果将这8个方法都在实现类里覆写一遍,将会非常麻烦,此时可用适配器模式

适配器的实现原理



在模块的接口间使用适配器模式

比如目前人事系统接口返回Map,此时财务系统客户端要求Map,而供应链系统要求用List,所以就需要一个适配器将Map转换为List:



代码比较简单,就不在此贴出,全部放在项目中。

适配器模式的实际应用,源码剖析

适配器模式在StringReader, StringWriter, CharArrayReader, CharArrayWriter的实际应用

StringReader

import java.io.IOException;
import java.io.Reader;

public class StringReader extends Reader {

private String str;
private int length;
private int next = 0;
private int mark = 0;

public StringReader(String s) {
this.str = s;
this.length = s.length();
}

//确认该流没有被关闭
private void ensureOpen() throws IOException {
if (str == null)
throw new IOException("Stream closed");
}

// 读取字符
public int read() throws IOException {
synchronized (lock) {
ensureOpen();
if (next >= length)
return -1;
return str.charAt(next++);
}
}

// 读取字符数组中的字符
public int read(char cbuf[], int off, int len) throws IOException {
synchronized (lock) {
ensureOpen();
if ((off < 0) || (off > cbuf.length) || (len < 0) ||
((off + len) > cbuf.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return 0;
}
if (next >= length)
return -1;
int n = Math.min(length - next, len);
str.getChars(next, next + n, cbuf, off);
next += n;
return n;
}
}

// 跳转
public long skip(long ns) throws IOException {
synchronized (lock) {
ensureOpen();
if (next >= length)
return 0;
// Bound skip by beginning and end of the source
long n = Math.min(length - next, ns);
n = Math.max(-next, n);
next += n;
return n;
}
}

// 确认该字符是否已被读取
public boolean ready() throws IOException {
synchronized (lock) {
ensureOpen();
return true;
}
}

// 是否支持mark操作
public boolean markSupported() {
return true;
}

//标识当前位置
public void mark(int readAheadLimit) throws IOException {
if (readAheadLimit < 0){
throw new IllegalArgumentException("Read-ahead limit < 0");
}
synchronized (lock) {
ensureOpen();
mark = next;
}
}

// 重置当前位置
public void reset() throws IOException {
synchronized (lock) {
ensureOpen();
next = mark;
}
}

// 关闭流
public void close() {
str = null;
}
}


StringWriter

import java.io.IOException;
import java.io.Writer;

public class StringWriter extends Writer {

private StringBuffer buf;

public StringWriter() {
buf = new StringBuffer();
lock = buf;
}

public StringWriter(int initialSize) {
if (initialSize < 0) {
throw new IllegalArgumentException("Negative buffer size");
}
buf = new StringBuffer(initialSize);
lock = buf;
}

// 写入字符
public void write(int c) {
buf.append((char) c);
}

// 写入数组中的字符
public void write(char cbuf[], int off, int len) {
if ((off < 0) || (off > cbuf.length) || (len < 0) ||
((off + len) > cbuf.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
buf.append(cbuf, off, len);
}

//写入字符串
public void write(String str) {
buf.append(str);
}

// 在指定位置写入字符串
public void write(String str, int off, int len)  {
buf.append(str.substring(off, off + len));
}

// 增加字符串序列
public StringWriter append(CharSequence csq) {
if (csq == null)
write("null");
else
write(csq.toString());
return this;
}

// 在指定位置增加字符串序列
public StringWriter append(CharSequence csq, int start, int end) {
CharSequence cs = (csq == null ? "null" : csq);
write(cs.subSequence(start, end).toString());
return this;
}

// 增加字符
public StringWriter append(char c) {
write(c);
return this;
}

public String toString() {
return buf.toString();
}

public StringBuffer getBuffer() {
return buf;
}

public void flush() {
}

public void close() throws IOException {
}
}


适配器模式在Spring的实际应用

在Spring中也有适配器的大量应用,在Spring的AOP中,由于Advisor需要的是MethodInterceptor对象,所有每一个Advisor中的Advice都要适配成对应的MethodInterceptor对象。



AdvisorAdapter

package org.springframework.aop.framework.adapter;

import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.Advisor;

public abstract interface AdvisorAdapter
{
public abstract boolean supportsAdvice(Advice paramAdvice);

public abstract MethodInterceptor getInterceptor(Advisor paramAdvisor);
}
}


MethodBeforeAdviceAdapter

package org.springframework.aop.framework.adapter;

import java.io.Serializable;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.Advisor;
import org.springframework.aop.MethodBeforeAdvice;

class MethodBeforeAdviceAdapter
implements AdvisorAdapter, Serializable
{
public boolean supportsAdvice(Advice advice)
{
return advice instanceof MethodBeforeAdvice;
}

public MethodInterceptor getInterceptor(Advisor advisor)
{
MethodBeforeAdvice advice = (MethodBeforeAdvice)advisor.getAdvice();
return new MethodBeforeAdviceInterceptor(advice);
}
}


在Spring的ORM包中,对于JPA的支持也是采用了适配器模式,首先定义了一个抽象类的JpaVendorAdapter,然后不同的持久层框架都继承了此类:

JpaVendorAdapter

package org.springframework.orm.jpa;

import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.spi.PersistenceProvider;

public abstract interface JpaVendorAdapter
{
// 返回一个具体的持久层提供者
public abstract PersistenceProvider getPersistenceProvider();

// 返回持久层提供者的包名
public abstract String getPersistenceProviderRootPackage();

// 返回持久层提供者的属性
public abstract Map<String, ?> getJpaPropertyMap();

// 返回JpaDialect
public abstract JpaDialect getJpaDialect();

// 返回持久层管理器工厂
public abstract Class<? extends EntityManagerFactory> getEntityManagerFactoryInterface();

// 返回持久层管理器
public abstract Class<? extends EntityManager> getEntityManagerInterface();

// 自定义回调方法
public abstract void postProcessEntityManagerFactory(EntityManagerFactory paramEntityManagerFactory);
}


AbstractJpaVendorAdapter

package org.springframework.orm.jpa.vendor;

import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import org.springframework.orm.jpa.JpaDialect;
import org.springframework.orm.jpa.JpaVendorAdapter;

public abstract class AbstractJpaVendorAdapter implements JpaVendorAdapter {
private Database database; //定义数据库
private String databasePlatform; //定义数据库的平台
private boolean generateDdl; //是否生成ddl
private boolean showSql; //是否显示sql

public AbstractJpaVendorAdapter() {
this.database = Database.DEFAULT;

this.generateDdl = false;

this.showSql = false;
}

/* 设定下列数据库
* DB2, DERBY, H2, HSQL, INFORMIX, MYSQL, ORACLE, POSTGRESQL, SQL_SERVER,SYBASE
*/
public void setDatabase(Database database) {
this.database = database;
}

// 返回要操作的数据库
protected Database getDatabase() {
return this.database;
}

public void setDatabasePlatform(String databasePlatform) {
this.databasePlatform = databasePlatform;
}

protected String getDatabasePlatform() {
return this.databasePlatform;
}

public void setGenerateDdl(boolean generateDdl) {
this.generateDdl = generateDdl;
}

protected boolean isGenerateDdl() {
return this.generateDdl;
}

public void setShowSql(boolean showSql) {
this.showSql = showSql;
}

protected boolean isShowSql() {
return this.showSql;
}

public String getPersistenceProviderRootPackage() {
return null;
}

public Map<String, ?> getJpaPropertyMap() {
return null;
}

public JpaDialect getJpaDialect() {
return null;
}

public Class<? extends
fe7a
EntityManagerFactory> getEntityManagerFactoryInterface() {
return EntityManagerFactory.class;
}

public Class<? extends EntityManager> getEntityManagerInterface() {
return EntityManager.class;
}

// 设定emf,基于Eclipse的模型框架。它是Eclipse MDA(Model Driven Architecture)的一个重要组成部分
public void postProcessEntityManagerFactory(EntityManagerFactory emf) {
}
}


EclipseLinkJpaVendorAdapter

package org.springframework.orm.jpa.vendor;

import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import javax.persistence.EntityManager;
import org.eclipse.persistence.jpa.JpaEntityManager;
import org.springframework.orm.jpa.JpaDialect;

public class EclipseLinkJpaVendorAdapter extends AbstractJpaVendorAdapter {
// 设定持久层提供者
private final javax.persistence.spi.PersistenceProvider persistenceProvider;
// 设定持久层方言
private final JpaDialect jpaDialect;

public EclipseLinkJpaVendorAdapter() {
this.persistenceProvider = new org.eclipse.persistence.jpa.PersistenceProvider();

this.jpaDialect = new EclipseLinkJpaDialect();
}

public javax.persistence.spi.PersistenceProvider getPersistenceProvider() {
return this.persistenceProvider;
}

// 返回JPA的属性
public Map<String, Object> getJpaPropertyMap() {
Map jpaProperties = new HashMap();
// 判断平台是否为空
if (getDatabasePlatform() != null) {
jpaProperties.put("eclipselink.target-database",
getDatabasePlatform());
} else if (getDatabase() != null) {
String targetDatabase = determineTargetDatabaseName(getDatabase());
if (targetDatabase != null) {
jpaProperties
.put("eclipselink.target-database", targetDatabase);
}
}
// 判断是否生成ddl
if (isGenerateDdl()) {
jpaProperties.put("eclipselink.ddl-generation", "create-tables");

jpaProperties.put("eclipselink.ddl-generation.output-mode",
"database");
}

if (isShowSql()) {
jpaProperties.put("eclipselink.logging.level",
Level.FINE.toString());
}

return jpaProperties;
}

//设定数据库
protected String determineTargetDatabaseName(Database database)
{
switch (1.$SwitchMap$org$springframework$orm$jpa$vendor$Database[database.ordinal()])
{
case 1:
return "DB2";
case 2:
return "Derby";
case 3:
return "HSQL";
case 4:
return "Informix";
case 5:
return "MySQL4";
case 6:
return "Oracle";
case 7:
return "PostgreSQL";
case 8:
return "SQLServer";
case 9:
return "Sybase";
}
return null;
}

public JpaDialect getJpaDialect() {
return this.jpaDialect;
}

public Class<? extends EntityManager> getEntityManagerInterface() {
return JpaEntityManager.class;
}
}


HibernateJpaVendorAdapter

package org.springframework.orm.jpa.vendor;

import java.util.HashMap;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.spi.PersistenceProvider;
import org.hibernate.dialect.DB2Dialect;
import org.hibernate.dialect.DerbyDialect;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.dialect.HSQLDialect;
import org.hibernate.dialect.InformixDialect;
import org.hibernate.dialect.MySQLDialect;
import org.hibernate.dialect.Oracle9iDialect;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.dialect.SybaseDialect;
import org.hibernate.ejb.HibernateEntityManager;
import org.hibernate.ejb.HibernateEntityManagerFactory;
import org.hibernate.ejb.HibernatePersistence;
import org.springframework.orm.jpa.JpaDialect;

public class HibernateJpaVendorAdapter extends AbstractJpaVendorAdapter {
//设定持久层提供者
private final PersistenceProvider persistenceProvider;
//设定持久层方言
private final JpaDialect jpaDialect;

public HibernateJpaVendorAdapter() {
this.persistenceProvider = new HibernatePersistence();
this.jpaDialect = new HibernateJpaDialect();
}

//返回持久层方言
public PersistenceProvider getPersistenceProvider() {
return this.persistenceProvider;
}

//返回持久层提供者
public String getPersistenceProviderRootPackage() {
return "org.hibernate";
}

//返回JPA的属性
public Map<String, Object> getJpaPropertyMap() {
Map jpaProperties = new HashMap();

if (getDatabasePlatform() != null) {
jpaProperties.put("hibernate.dialect", getDatabasePlatform());
} else if (getDatabase() != null) {
Class databaseDialectClass = determineDatabaseDialectClass(getDatabase());
if (databaseDialectClass != null) {
jpaProperties.put("hibernate.dialect",
databaseDialectClass.getName());
}
}

if (isGenerateDdl()) {
jpaProperties.put("hibernate.hbm2ddl.auto", "update");
}
if (isShowSql()) {
jpaProperties.put("hibernate.show_sql", "true");
}

return jpaProperties;
}

//设定数据库
protected Class determineDatabaseDialectClass(Database database)
{
switch (1.$SwitchMap$org$springframework$orm$jpa$vendor$Database[database.ordinal()])
{
case 1:
return DB2Dialect.class;
case 2:
return DerbyDialect.class;
case 3:
return H2Dialect.class;
case 4:
return HSQLDialect.class;
case 5:
return InformixDialect.class;
case 6:
return MySQLDialect.class;
case 7:
return Oracle9iDialect.class;
case 8:
return PostgreSQLDialect.class;
case 9:
return SQLServerDialect.class;
case 10:
return SybaseDialect.class; }
return null;
}

//返回JPA方言
public JpaDialect getJpaDialect() {
return this.jpaDialect;
}

//返回JPA实体管理器工厂
public Class<? extends EntityManagerFactory> getEntityManagerFactoryInterface() {
return HibernateEntityManagerFactory.class;
}

//返回JPA实体管理器
public Class<? extends EntityManager> getEntityManagerInterface() {
return HibernateEntityManager.class;
}
}


适配器模式在JUnit中的实际应用

通俗而言,就是要适配成TestCase类。这里重点看TestCase的runTest()方法:

protected void runTest() throws Throwable {
assertNotNull("TestCase.fName cannot be null", this.fName);
Method runMethod = null;
try {
//获取要测试的方法
runMethod = getClass().getMethod(this.fName, (Class[]) null);
}
catch (NoSuchMethodException e) {
fail("Method \"" + this.fName + "\" not found");
}
//判断要测试的方法是否为公用方法
if (!Modifier.isPublic(runMethod.getModifiers())) {
fail("Method \"" + this.fName + "\" should be public");
}
//java反射机制
try {
runMethod.invoke(this, new Object[0]);
}
catch (InvocationTargetException e) {
e.fillInStackTrace();
throw e.getTargetException();
}
catch (IllegalAccessException e) {
e.fillInStackTrace();
throw e;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息