专栏首页java程序员思维java设计模式之适配器模式,大丈夫能屈能伸

java设计模式之适配器模式,大丈夫能屈能伸

适配器模式

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。适配器模式有三种:类适配器、对象适配器、接口适配器

适配器解决的问题

主要解决在软件系统中,常常要将一些"现存的对象"放到新的环境中,而新环境要求的接口是现对象不能满足的。

命令模式模式角色

目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。

适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。

适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。

适配器模式和装饰着模式的区别

适配器模式的意义是要将一个接口转变成另一个接口,它的目的是通过改变接口来达到重复使用的目的。而装饰器模式不是要改变被装饰对象的接口,而是恰恰要保持原有的接口,但是增强原有对象的功能,或者改变原有对象的处理方式而提升性能。

代码实现:220v电压适配成5v电压

/**
 * 目标(Target)接口
 */
public interface Targetable {
 public int v5();
}
/**
 * 适配者(Adaptee)类
 */
public class Adaptee {
 public int v220(){
 return 220;
 }
}

基于对象的适配器,组合适配者对象

/**
 *
 * 采用对象聚合的方式进行适配
 *
 * 对象的适配器模式
 *
 */
public class ObjectAdapterMode implements Targetable {
 private Adaptee adaptee;
 public ObjectAdapterMode(Adaptee adaptee) {
 this.adaptee = adaptee;
 }
 public int v5() {
 return adaptee.v220()/44;
 }
}

基于类的适配器,继承适配者类

public class ClassAdapterMode extends Adaptee implements Targetable {
 public int v5() {
 return super.v220() / 44;
 }
}

基于接口的适配器,同时实现目标接口和适配者接口

public interface Adapteeable {
 public int v220();
}
public class InterfaceAdapterMode implements Targetable ,Adapteeable{
 public int v220() {
 return 220;
 }
 public int v5() {
 return v220()/44;
 }
}

JDK中的适配器模式

public class InputStreamReader extends Reader {
 private final StreamDecoder sd;
 /**
 * Creates an InputStreamReader that uses the default charset.
 *
 * @param in An InputStream
 */
 public InputStreamReader(InputStream in) {
 super(in);
 try {
 sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
 } catch (UnsupportedEncodingException e) {
 // The default encoding should always be available
 throw new Error(e);
 }
 }
 /**
 * Creates an InputStreamReader that uses the named charset.
 *
 * @param in
 * An InputStream
 *
 * @param charsetName
 * The name of a supported
 * {@link java.nio.charset.Charset charset}
 *
 * @exception UnsupportedEncodingException
 * If the named charset is not supported
 */
 public InputStreamReader(InputStream in, String charsetName)
 throws UnsupportedEncodingException
 {
 super(in);
 if (charsetName == null)
 throw new NullPointerException("charsetName");
 sd = StreamDecoder.forInputStreamReader(in, this, charsetName);
 }
 /**
 * Creates an InputStreamReader that uses the given charset.
 *
 * @param in An InputStream
 * @param cs A charset
 *
 * @since 1.4
 * @spec JSR-51
 */
 public InputStreamReader(InputStream in, Charset cs) {
 super(in);
 if (cs == null)
 throw new NullPointerException("charset");
 sd = StreamDecoder.forInputStreamReader(in, this, cs);
 }
 /**
 * Creates an InputStreamReader that uses the given charset decoder.
 *
 * @param in An InputStream
 * @param dec A charset decoder
 *
 * @since 1.4
 * @spec JSR-51
 */
 public InputStreamReader(InputStream in, CharsetDecoder dec) {
 super(in);
 if (dec == null)
 throw new NullPointerException("charset decoder");
 sd = StreamDecoder.forInputStreamReader(in, this, dec);
 }
 /**
 * Returns the name of the character encoding being used by this stream.
 *
 * <p> If the encoding has an historical name then that name is returned;
 * otherwise the encoding's canonical name is returned.
 *
 * <p> If this instance was created with the {@link
 * #InputStreamReader(InputStream, String)} constructor then the returned
 * name, being unique for the encoding, may differ from the name passed to
 * the constructor. This method will return <code>null</code> if the
 * stream has been closed.
 * </p>
 * @return The historical name of this encoding, or
 * <code>null</code> if the stream has been closed
 *
 * @see java.nio.charset.Charset
 *
 * @revised 1.4
 * @spec JSR-51
 */
 public String getEncoding() {
 return sd.getEncoding();
 }
 /**
 * Reads a single character.
 *
 * @return The character read, or -1 if the end of the stream has been
 * reached
 *
 * @exception IOException If an I/O error occurs
 */
 public int read() throws IOException {
 return sd.read();
 }
 /**
 * Reads characters into a portion of an array.
 *
 * @param cbuf Destination buffer
 * @param offset Offset at which to start storing characters
 * @param length Maximum number of characters to read
 *
 * @return The number of characters read, or -1 if the end of the
 * stream has been reached
 *
 * @exception IOException If an I/O error occurs
 */
 public int read(char cbuf[], int offset, int length) throws IOException {
 return sd.read(cbuf, offset, length);
 }
 /**
 * Tells whether this stream is ready to be read. An InputStreamReader is
 * ready if its input buffer is not empty, or if bytes are available to be
 * read from the underlying byte stream.
 *
 * @exception IOException If an I/O error occurs
 */
 public boolean ready() throws IOException {
 return sd.ready();
 }
 public void close() throws IOException {
 sd.close();
 }
}

InputStreamReader是通过对象适配的方式进行适配,Reader是目标,StreamDecoder是适配者。

优缺点

优点:可以让任何两个没有关联的类一起运行,提高了类的复用,增加了类的透明度,灵活性好。

缺点:过多地使用适配器,会让系统非常零乱,维护成本高。

生活中的命令模式

中国标准输出电压220v,手机充电器5v电压,无法改变标准输出,可以增加一个充电插头,它负责将220v的电压转化成5v电压,充当了一个适配器的作用。

手机内存读卡器,将内存卡转换成USB接口,方便笔记本电脑读取手机内存卡中的内容。手机圆孔耳机和方块耳机,可以通过转换器进行转换。

每个人都有不同的角色,在公司是员工,在学校是学生,在家里是家庭成员等等,进入不同的环境,我们要切换不同的角色,与之适配。

我的启发

适配器模式,大丈夫能屈能伸,在艰苦的环境下,坚韧不拔。在舒适的环境,居安思危。做人做事,外圆内方,精彩塑造自己的每一个角色。

设计模式系列历史文章

Head First 设计模式之命令模式,各司其职提高效率

Head First 设计模式之装饰器模式,因为参与,所以认同

Head First 设计模式之单例模式,每个人都是唯一

Head First 设计模式之观察者模式,你我都是发布者和订阅者

Head first 设计模式之策略模式,来源于生活,用之于生活

本文分享自微信公众号 - java程序员思维(java_python_go),作者:曾建路

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-05-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • java设计模式之适配器模式【设计模式】

    这一篇写的是适配器模式,适配器的出现目的是为了对不同的接口做出不同的功能,比如:生活中最常用就是充电头,有Type-C的,有苹果的,有安卓的... 适配器的作用...

    简单的程序员
  • Java设计模式之适配器模式

    今天讲适配器模式,这个模式也很简单,你笔记本上的那个拖在外面的黑盒子就是个适配器,一般你在中国能用,在日本也能用,虽然两个国家的的电源电压不同,中国是220V,...

    CoderJed
  • java设计模式之适配器模式

    秋白
  • 设计模式之适配器模式适配器模式

    当我们的手机接口Type-A时,但是数据线只有Type-C的时候,就需要用转接口做适配,这种情况下就要增加一个适配器

    tanoak
  • JAVA 设计模式 适配器模式

    用途 适配器模式 (Adapter) 将一个类的接口转换成客户希望的另外一个接口。 Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工...

    静默虚空
  • Java 设计模式 适配器模式

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://louluan.blog.c...

    亦山
  • 浅谈Java设计模式-之-适配器模式

    适配器模式是将一个类的接口变成客户端所期待的另一种接口,从而使原本接口不匹配而无法在一起工作的两个类能够在一起工作,适配器模式也称变压器模式。

    动力节点Java学院
  • 图解Java设计模式之适配器模式

    泰国插座用的是两孔的(欧标),可以买个多功能转换插头(适配器),这样就可以使用了。

    海仔
  • 设计模式之适配器模式

    适配器就是一种适配中间件,它存在于不匹配的二者之间,用于连接二者,将不匹配变得匹配,简单点理解就是平常所见的转接头,转换器之类的存在。

    二十三年蝉

扫码关注云+社区

领取腾讯云代金券