[设计模式] - 适配器模式

一 、 适配器模式的简介

1. 什么是适配器模式

**适配器模式(adapter patterns)**又叫做包装器模式,其存在是为了称为两个不兼容的接口之间的桥梁。其隶属于结构性设计模式,致力于解决现有对象放入新环境中不兼容的问题。

2. 适配器的业务场景

适配器模式最吻合的现实场景应该就是转换器了,转换器的种类有很多,我们可以随意在狗东上搜一下耳机转换器:
在这里插入图片描述
由于很多手机厂商为了能够做的更薄而取消了3.5mm格式的耳机接口(就是我们常见的圆头插口),他们根据采用将耳机插口和充电插口二合一的方式来解决耳机插头的问题。那么问题来了,很多耳机的发烧友可能之前花了很多钱买了款HiFi耳机,如果每次更换手机都要更换对应插头格式的耳机,这样的成本无疑是过高的,那么此时我们就需要设计一个插头格式的转换器。

二 、适配器模式的实现

适配器模式的实现方式有很多种,今天就主要讲一下比较常见的三种适配器模式:类适配器,对象适配器和接口适配器

1- 类适配器

1. 类适配器的实现

首先我们用类适配器模式简单的实现下。

(1) 创建耳机接口
public interface HeadSet {
	// 播放音乐
	void music();
	// 获取种类
	String type();
}

(2) 创建普通3.5mm耳机
public class SimpleHeadset implements HeadSet {

	protected String type = "3.5mm接口";

	public void music() {
		System.out.println("播放音乐");
	}

	@Override
	public String type() {
		return type;
	}

}
(3) 创建转换器接口
public interface TypecHeadSetAdapter {

	void transformation();
}

(4) 创建接口转换类
public class SimpleToTypecAdapter extends SimpleHeadset implements TypecHeadSetAdapter {
	@Override
	public void transformation() {
		super.type = "typeC";
	}
	public SimpleToTypecAdapter() {
		transformation();
	}
}
(5) 创建手机对象
public class Phone {

	private HeadSet headSet;

	public void check() {

		if ("typeC".equals(headSet.type())) {
			headSet.music();
		} else {
			System.out.println("接口格式不符,无法播放音乐");
		}
	}

	public Phone(HeadSet headSet) {
		super();
		this.headSet = headSet;
	}

}

(6) 创建测试类
public class Test {
	public static void main(String[] args) {

		Phone phone = new Phone(new SimpleToTypecAdapter());
		phone.check();
	}

}

测试结果:
在这里插入图片描述

2. 类适配器的设计思路

先看图:
在这里插入图片描述
类适配器主要是利用了继承的特性进行实现,其主要思路为:

  1. 创建产品接口
  2. 通过待适配类实现产品接口
  3. 由于新建业务无法使用已有的待适配类,需要对待适配类进行转换
  4. 创建适配器接口
  5. 创建适配器子类,继承与待适配类,实现适配器接口
  6. 业务调用方创建适配器子类即可

2 - 对象适配器

1. 对象适配器的实现

对象适配器我们只需要改适配器对象即可

public class SimpleToTypeCAdapter implements  HeadSet,TypecHeadSetAdapter {

	private SimpleHeadset simpleHeadset;

	@Override
	public void transformation() {
		simpleHeadset.type = "typeC";
	}

	public SimpleToTypeCAdapter(SimpleHeadset simpleHeadset) {
		super();
		this.simpleHeadset = simpleHeadset;
		transformation();
	}

	@Override
	public void music() {
		simpleHeadset.music();
	}

	@Override
	public String type() {
		return simpleHeadset.type();
	}

}

测试结果:

public class Test {

	public static void main(String[] args) {
		HeadSet simpleToTypeCAdapter = new SimpleToTypeCAdapter(new SimpleHeadset());
		Phone phone = new Phone(simpleToTypeCAdapter);
		phone.check();
	}
}

在这里插入图片描述

1. 对象适配器的设计思路

如图:
在这里插入图片描述
这里应该有聪明的小伙子发现了类适配器和对象适配器之间的不同就是类适配器是通过对象继承的方式进行适配,而对象适配器是通过聚合的方式进行适配。

2 - 接口适配器

接口适配器的应用场景和上面两种适配器略有不同,接口适配器通常用于我们想要使用某一个复杂接口中的一个或少数方法时。就比如我们创建一个拥有十个方法的接口:

public interface SourceInterface {

	void method01();

	void method02();

	void method03();

	void method04();

	void method05();

	void method06();

	void method07();

	void method08();

	void method09();

	void method10();
}

如果此时我们只想使用接口中的method01,我们该怎么办呢?很简单,先创建一个继承与目标接口的子类并默认将所有方法空实现

public class Adapter implements SourceInterface {

	@Override
	public void method01() {
		// TODO Auto-generated method stub

	}

	@Override
	public void method02() {
		// TODO Auto-generated method stub

	}

	@Override
	public void method03() {
		// TODO Auto-generated method stub

	}

	@Override
	public void method04() {
		// TODO Auto-generated method stub

	}

	@Override
	public void method05() {
		// TODO Auto-generated method stub

	}

	@Override
	public void method06() {
		// TODO Auto-generated method stub

	}

	@Override
	public void method07() {
		// TODO Auto-generated method stub

	}

	@Override
	public void method08() {
		// TODO Auto-generated method stub

	}

	@Override
	public void method09() {
		// TODO Auto-generated method stub

	}

	@Override
	public void method10() {
		// TODO Auto-generated method stub

	}

}

然后我们在创建业务调用方并通过内部类重写需要适配的方法

public class Test {

	public static void main(String[] args) {
		Adapter adapter = new Adapter() {

			@Override
			public void method01() {
				System.out.println("适配了方法01");
			}
		};
		
		adapter.method01();
	}

}

测试结果:
在这里插入图片描述

接口适配器的实现原理

在这里插入图片描述
接口适配器的实现就非常的简单了:

  1. 我们通过一个适配类继承目标接口
  2. 适配类默认将所有接口方法空实现
  3. 业务调用方创建适配类,并通过内部类的方式调用期望方法

三 、 适配器模式的特点

1. 适配器的使用场景

  1. 系统需要使用现有的类,但是现有的类的属性与期望存在差异
  2. 通过接口转换,将一个类插入另一个接口系中
  3. 想要为两个可能会一起工作的类建立联系

2. 适配器模式的特点

优点:

  1. 可以让任何两个没有关联的类一起运行
  2. 提高了类的复用性
  3. 增加了类的透明度
  4. 灵活度高

缺点:

  1. 过多的使用适配器会是系统碎片化,不易整理进行把握。
  2. java单继承限制了适配的灵活性。

3. 注意事项

由于适配模式会让使用者产生调用错觉,比如明明看到调用的是A接口,但是其内部被适配成了B接口的实现导致过多的应用适配模式无疑对系统的语义和抽象性是一种灾难。因此如果不是必要的情况下,并不建议使用适配器模式,而是推荐直接对现有系统进行重构,减少潜在问题的发生概率。

好了,今天的内容到此结束,如果还有疑问的同学可以私信我或在评论区留言,我会在第一时间为你解答。觉得有收获的小伙伴请记得一键三连,关注博主不要走丢,拒当白嫖党~

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晓龙oba

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值