23种设计模式之适配器模式傻瓜式理解

在这里插入图片描述

适配器模式

前言

第一次写博客,主要是为了做笔记,如果在这个过程当中能够帮助别人,那将是我最大的荣幸啦。如果有错误的地方还请大家多多指教。

为了方便直观理解,我的代码中加入了很多中文,但我个人不主张这样做,但后来我发现,以前做的笔记,学习的时候什么都懂,什么都会,过了一段时间回去看就忘得一干二净,而且捡起来也特别的费劲,为了方便以后我看笔记的时候能快速捡起之前学习的内容,我决定用生活中具体实物去表示代码中的逻辑关系。

为了方便理解,本章以下表述等价:

变压器=适配器
制造=创建
方法=函数
电脑插头=具有适配器特殊方法的类

1.类的适配器模式

所谓类的适配器模式,就是适配器以类的形式存在,或者以类的方式实现功能。

先贴一个步骤图

在这里插入图片描述

在这里插入图片描述

贴下代码:

	package 类的适配器模式;
	
	//设计一个标准插头,一切制造商都必须根据这个标准设计,及必须实现电压输出
	interface 插头 {
		public void OutputVoltage();
	}
	
	class V12变压器 {
		public void output12V() {
			System.out.println("12V电压输出");
		}
	}
	
	// 制造一个空调插头,不添加任何适配器,根据插头标准,必须有电压输出定义220V输出
	class 空调插头 implements 插头 {
		public void OutputVoltage() {
			System.out.println("220V电压输出");
		}
	}
	
	//制造电脑插头,继承变压器,实现标准接口,具有12V电压输出
	class 电脑插头 extends V12变压器 implements 插头 {
		public void OutputVoltage() {
			super.output12V();
		}
	}
	
	public class 类适配器模式测试类 {
		public static void main(String[] args) {
			// 使用不带适配器的空调插头
			插头 plug01 = new 空调插头();
			plug01.OutputVoltage();
	
			// 使用带适配器的电脑插头
			插头 plug02 = new 电脑插头();
			plug02.OutputVoltage();
		}
	}

大部分问题及描述都在步骤图里,这里在啰嗦添加一下。
问题1:为什么要实现标准插头以及实现变压器,直接在电脑插头类里添加一个输出12V电压的方法不就好了么?
答:所以的接口都是为了实现标准,方便管理。有了接口定义的方法,后面只要继实现接口的类都要听接口指挥。比方说,现在有1万个电脑插头需要修改电压,变成24V的输出电压,那么这时,只需要修改变压器就可以了。因为这1万个电脑插头都继承变压器。
问题2:那既然继承变压器就可以实现管理,那干嘛还要实现标准插头接口呢?
答:从效果上看,确实实现标准插头接口的意义不大,但是还是需要实现。一方面是为了实现规范化,实现了接口,那就一定要实例化接口里的方法,且函数名字不能变、如果不实现接口。1万个插头就有1万个方法名,不利于管理。另外一方面,实现标准插头接口方便使用这些电脑插头时使用多态。且多态情况下,电脑插头不能自己给自己添加特有的方法。
问题3:类的适配器适用场景?
答:批量生产功能单一的产品。

2.对象的适配器模式

所谓对象的适配器模式就是适配器以对象的形式传入到实现类中把特殊功能带给实现类(电脑插头)

在这里插入图片描述
在这里插入图片描述

代码:

	package 对象适配器模式;
	
	//设计一个标准插头,一切制造商都必须根据这个标准设计,及必须实现电压输出
	interface 插头 {
		public void OutputVoltage();
	}
	
	class V12变压器 {
		public void output12V() {
			System.out.println("12V电压输出");
		}
	}
	
	class V24变压器 {
		public void output24V() {
			System.out.println("24V电压输出");
		}
	}
	
	//	制造一个空调插头,不添加任何适配器,根据插头标准,
	//必须有电压输出定义220V输出
	class 空调插头 implements 插头 {
		public void OutputVoltage() {
			System.out.println("220V电压输出");
		}
	}
	
	//根据客户需要制造一个电脑插头,同时具备12V/24V电压输出。
	class 电脑插头 implements 插头 {
		// 定义两个变量接受两种类型的变压器对象
		private V12变压器 adapter_output12V;
		private V24变压器 adapter_output24V;
	
		// 可以通过构造函数传入两个带有特殊输出电压的变压器。
		public 电脑插头(V12变压器 adapter_output12V, V24变压器 adapter_output24V) {
			this.adapter_output12V = adapter_output12V;
			this.adapter_output24V = adapter_output24V;
		}
	
		public void OutputVoltage() {
			// 通过两个变压器输出相应的电压。
			this.adapter_output12V.output12V();
			this.adapter_output24V.output24V();
		}
	}
	
	//测试类
	public class 对象适配器模式测试 {
		public static void main(String[] args) {
			// 使用不带适配器的空调插头
			插头 plug01 = new 空调插头();
			plug01.OutputVoltage();
	
			// 使用带适配器的电脑插头
			// 需要先创建两个“变压器”类的对象作为参数
			插头 plug02 = new 电脑插头(new V12变压器(), new V24变压器());
			plug02.OutputVoltage();
		}
	}

问题1:对象的适配器与类的适配器有啥区别?
答:类适配器的12V电压是通过继承到电脑插头上的。但类的继承是单继承,这就导致电脑插头只能输出12V电压。如果现在我需要一个插头能输出12V和24V两种电压。明显类的适配器就没法用了。所以就引入了对象适配器模式。对象适配器模式下,变压器是以对象的形式,通过电脑插头的构造函数传入的。构造函数可以传入多个参数。所以这样电脑插头具有多个电压输出,多穿几个变压器对象就可以了。
问题2:那为啥不继承一个变压器,在变压器里多设计几个电压方法不就得啦?
答:这样设计是没有大局意识的,方法是实现功能的最小单位(这句话也解释了为什么不能在函数里嵌套定义函数),对于面向对象的语音,设计类时,也尽量让类简单。这里虽然看上去解决了问题,但实际上呢,并没有真正的思想上理解对象适配器的作用,比方说如果把类也看成是一个单元。
问题3:对象适配器模式适用于什么场景?
答:批量生产功能多样化产品。

2.抽象的适配器模式
网上有些说的接口的适配器模式,但我更愿意称之为抽象适配器模式。因为这里的适配器是以抽象类存在,继承的方式实现了方法的。在这里插入图片描述
在这里插入图片描述
代码;
package 接口的适配器模式;
//设计一个标准插头,
//一切制造商都必须根据这个标准设计,及必须实现电压输出
interface 插头 {
public void OutputVoltage1();

		public void OutputVoltage2();
	}
	
	abstract class 变压器 implements 插头 {
		public void OutputVoltage1() {
	
		}
	
		public void OutputVoltage2() {
	
		}
	}
	
	//按照需求制造一个12V插头继承变压器
	class V12插头 extends 变压器 {
		public void OutputVoltage1() {
			System.out.println("12V电压输出");
		}
	}
	//按照需求制造一个24V插头继承变压器
	class V24插头 extends 变压器 {
		public void OutputVoltage2() {
			System.out.println("24V电压输出");
		}
		public void OutputVoltage3() {
			System.out.println("24V插头48V电压输出");
		}
	}
	
	public class 接口适配器模式测试 {
		public static void main(String[] args) {
			插头 plug01 = new V12插头();
			V24插头 plug02 = new V24插头();
			
			plug01.OutputVoltage1();
			plug02.OutputVoltage3();
			插头 plug03 = new V24插头();
	//		 plug03.OutputVoltage3();
	
		}
	}

问题1:抽象适配器存在意义?
答:我们了解到前面两种模式,一个是批量生产功能单一的产品,一个是生产功能多样化的产品。但都无法做到定制化生成。
也就是一旦变压器里规定了输出电压,那生成的插头的输出电压只能是变压器规定电压。如果要实现私人订制怎么办,这个时候的抽象适配器模式就可以解决问题。

问题2:电脑插头直接实现标准插头不就可以了么,干嘛多此一举中间加个变压器类?
答:标准插头类有多个方法(多个电压输出,具体输出多少,实现类自己确定)如果直接实现,那就意味着全部方法都要实例化。那并不能实现定制化。比方说,我标准插头有10个方法(10电压输出)但定制的电脑插头只需要两个电压输出口。但标准插头上面已经规定死了不能改。想要用有必须全部实例化,剩下的8个完全没用,又不能扔。但是引入变压器后,情况就不一样了。相对于引入一个管理员,它帮里管理这10个方法,你想用哪一个的时候,在从中拿取一个在定制。变压器类实现了接口。把所有方法实例化(抽象处理)因为变压器不能擅自修改方法,一旦修改,后面的继承者就无法做到定制了。

问题3:抽象适配器模式使用场景?
答:小批量生产个性化定制产品。

猜你喜欢

转载自blog.csdn.net/bolanlanlan/article/details/85880054