设计模式-02 适配器模式

设计模式-02 适配器模式

目录

简介

当把手机或笔记本电脑插到插座上充电时,适配器就发挥了功效。适配器的作用是使产生 220 V 的插座和需要 4 V 的移动设备能够相互适应,完美地发挥二者的功效。类似地,通过在程序中使用适配器模式,可以做到不兼容的接口在一起正常工作,而填补现有程序和所需程序之间差异就是 Adapter 的工作:

设计模式-02 适配器模式


Adapter 模式有两种:

  • 类适配器模式(基于继承)。
  • 对象适配器模式(使用委托)。

例子

使用继承

类图

设计模式-02 适配器模式


代码

public interface Print {
	void printWeak();
	void printStrong();
}

public class Banner {
	private String str;

	public Banner(String str) {
		this.str = str;
	}

	public void showWithParen() {
		System.out.printf("(%s)\n", str);
	}

	public void showWithAster() {
		System.out.printf("*%s*\n", str);
	}
}

public class PrintBanner extends Banner implements Print {
	
	public PrintBanner(String str) {
		super(str);
	}

	@Override
	public void printWeak() {
		showWithParen();
	}

	@Override
	public void printStrong() {
		showWithAster();
	}
}

使用委托

类图

设计模式-02 适配器模式


代码

public abstract class Print {
	public abstract void printWeak();
	public abstract void printStrong();
}


public class Banner {
	private String str;

	public Banner(String str) {
		this.str = str;
	}

	public void showWithParen() {
		System.out.printf("(%s)\n", str);
	}

	public void showWithAster() {
		System.out.printf("*%s*\n", str);
	}
}

public class PrintBanner extends Print {

	private Banner banner;

	public PrintBanner(String str) {
		this.banner = new Banner(str);
	}

	@Override
	public void printWeak() {
		banner.showWithParen();
	}

	@Override
	public void printStrong() {
		banner.showWithAster();
	}
}

分析

对于第一种情况:

  • 我们的目标,就是 Print 接口规定的内容,也就是它含有的两个方法:printWeak()printStrong(),对应弱提示打印和强提示打印。
  • Banner 则是被适配的对象,它能够按照一定的规则打印字符串,但是这两个功能还不满足 Print 类汇总规定的类容。
  • PrintBanner 就是适配器,它实现了 Print 接口,也就是说它能完成目标工作;它又继承了 Banner,代表它能够使用被适配对象的功能(方法)。

对于第二种情况

  • 我们的目标,或者说是要适配成的样子,就是 Print 类的内容,也就是它含有的两个方法:printWeak()printStrong(),对应弱提示打印和强提示打印。
  • Banner 则是被适配的对象,它能够按照一定的规则打印字符串,但是这两个功能还不满足 Print 类汇总规定的类容。
  • PrintBanner 就是适配器,它继承自 Print,也就是说它适配目标,在其中它又将 Banner 组合成了自己的字段,为了完成 Print 定义的目标,它使用了 banner 字段的方法。

在两种情况下,我们都只需要调用 Print 接口中的方法,就可以使用老旧的被适配者来实现新的功能,注意,我们使用到了老旧的被适配者,并不是将它们剔除掉了。这也是 OCP 原则的体现,为了实现新的功能,我们只是增加,而不是修改原有的代码。

总结

通用结构

基于继承:

设计模式-02 适配器模式


基于委托:

设计模式-02 适配器模式


如何选择

在考虑灵活和拓展性的前提下,组合委托必然是优于继承的,后者是一种高耦合的行为。


何时使用

适配器模式适用于非常多的情境,比如你在网上找到了一段代码,并且想要在其中添加一些额外的功能,修改源代码似乎不是一种明治的行为,甚至有些时候会构成法律问题。适配器模式就能够帮助你,将这段代码以你规定的方式(Target)引入到项目中。


如何使用

直接引入这些工具类似乎是一个更加简单、愉悦的选择,何必大费周章地衍生出那么多接口或者抽象类,再通过进行复杂的继承和实现才引入它们。

在我看来,直接引入是一种极具侵略性的行为,是不符合预期的行为。系统或者某个模块的功能应该由接口来定义,如果直接引入工具类,无异于在自己的系统中增加了一个未曾预想过的接口,这是对工程原则的违反,是一种具有风险的行为。而通过适配器模式将它转换,隐匿到已定义的接口中则是一种归化,温驯而且符合预期,符合工程原则。

上一篇:springboot入门


下一篇:咖啡店banner