软件设计模式之适配器模式

什么是适配器模式?

在计算机编程中,适配器模式(有时候也称包装样式或者包装)将一个类的接口适配成用户所期待的。适配器能将因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。

实现适配器的方式?

①对象适配器模式

-- 在这种适配器模式中,适配器容纳一个它包裹的类的实例。在这种情况下,适配器调用被包裹对象的物理实体。

②类适配器模式

-- 这种适配器模式下,适配器继承自已实现的类(一般多重继承)。

理论性的东西看起来就是比较烦,下面来举个日常的小例子来更好的了解适配器吧

图1:三相插头                 图2:二孔插座            图3:三相插头转二相的转换器

            

看完上面三幅图,我想大家应该都一目了然了,想把三相插头插到二孔插座里,只能中间加个转换器,这里我们可以简单把它理解成我们今天要说的适配器

再回过头看看文章开始的这句话"适配器能将因为接口不兼容而不能在一起工作的类工作在一起",没错,在两个原本不能工作到一起的组件中间添加适配器,就可以把它们关联起来了。

适配器模式里面存在着3种角色:

1、目标角色(Target):也就是客户理想中想要的接口,比如三相插头,客户想找的插孔就是三孔插座(目标角色)。

2、源(Adatee):现有的接口,也就是不满足客户想要的接口,也就是这个二孔插座(源)。

3、适配器(Adapter):能将二孔插座转换成"三孔插座"的组件,也就是上图的三相插头转二相插头转化器(适配器)。

就以上面的例子,用代码来讲下适配器模式吧

首先先来说下对象适配器模式

以笔记本通电为例,大家都知道正常的笔记本电源是三相接口

ThreeSocket.java

这是一个需求接口,也就是客户期待的,也就是3种角色中的目标接口(Target)

1 package com.lcw.adapter.test;
2
3 public interface ThreeSocket {
4
5     //需要一个三孔插座,也就是客戶的需求
6     public void needThreeSocket();
7
8 }

TwoSocket.java

这是现有的组件,也就是那个二孔插座,也就是3种角色中的源(Adatee),虽然能通电,但接口是不满足客户的需要

1 package com.lcw.adapter.test;
2
3 public class TwoSocket {
4     // 现有的插座,只有二孔,已经有了供电功能,只是缺少了三孔接口
5     public void serverTwo() {
6         System.out.println("我是一个二孔插座,我有供电功能");
7     }
8
9 }

ThreeToTwoAdapter.java

这是适配器类,它需要2孔插座来提供电,并实现三孔插座,在构造方法中传入现有组件2孔插座的对象(带电)

 1 package com.lcw.adapter.test;
 2
 3 public class ThreeToTwoAdapter implements ThreeSocket{
 4     private TwoSocket socket;
 5     public ThreeToTwoAdapter(TwoSocket two) {
 6         this.socket=two;
 7     }
 8     //现在已经有2孔插座的对象(意味着有通电功能)
 9     @Override
10     public void needThreeSocket() {
11         socket.serverTwo();
12         System.out.println("二孔接口已转换成三孔接口,并注入电");
13     }
14
15 }

这样一来,适配器类这个中间类就有了源(二孔插座)的效果也就是"电"

然后再实现了目标接口方法,也就是开通了三相接口,把"电"注入,这样就可以把2个本无法一起工作的类聚集到一起,类似红娘在它们之间牵了一条关系线

Computer.java 笔记本类,它需要的是三孔接口

 1 package com.lcw.adapter.test;
 2
 3 public class Computer {
 4     //笔记本电脑的电源插头需求是3孔
 5     private ThreeSocket three;
 6     public Computer(ThreeSocket three){
 7         this.three=three;
 8     }
 9     public void server(){
10         System.out.println("笔记本通电成功!");
11     }
12
13 }

来写个测试类

 1 package com.lcw.adapter.test;
 2
 3 public class Test {
 4     public static void main(String[] args) {
 5         //现有插座两孔,已经有提供电的功能,只是缺少3孔接口
 6         TwoSocket two=new TwoSocket();
 7         //把具有通电功能的对象传递进去,目的是要开通3孔接口的通电功能
 8         ThreeSocket three=new ThreeToTwoAdapter(two);
 9         //得到一个满足笔记本电源接口且具有电的功能对象
10         Computer computer=new Computer(three);
11         three.needThreeSocket();
12         computer.server();
13     }
14 }

看下效果图:

好了,这样就把2个原本不能在一起工作的类链接到一起了。

接着来说下类适配器模式

类适配器顾名思义不同点在于适配器,既然突出了‘类",我们一般都会联想到继承

嗯,没错,类适配器的做法就是让适配器去继承已有功能(二孔插座)的类,然后再实现期望接口(三孔插座)

具体看代码吧,除了测试类和适配器类,其他的类与上面的保持一致,这里就不再贴出

ThreeToTwoExtendsAdapter.java(适配器类)

1 package com.lcw.adapter.test;
2
3 public class ThreeToTwoExtendsAdapter extends TwoSocket implements ThreeSocket{
4     public void needThreeSocket() {
5         this.serverTwo();
6         System.out.println("二孔接口已转换成三孔接口");
7     }
8
9 }

Test.java(测试类)

 1 package com.lcw.adapter.test;
 2
 3 public class Test {
 4     public static void main(String[] args) {
 5         //由于ThreeToTwoExtendsAdapter继承了源,所以具有源的功能(电),并实现了3孔接口
 6         ThreeSocket socket=new ThreeToTwoExtendsAdapter();
 7         //插入接口
 8         Computer computer=new Computer(socket);
 9         socket.needThreeSocket();
10         computer.server();
11
12     }
13 }

效果依旧:

总结下:

①对象适配模式:

把"被适配者"作为一个对象组合到适配器中,以修改目标接口包装被适配者。

(例如上面例子,二孔插座就是被适配者,把对象传入适配器并实现接口方法改造)

②类适配模式:

通过多重继承和实现接口的方式,单一的为某个类而实现适配。

适配器的作用?

1、透明:通过适配器客户端可以调用统一接口,对于客户端是透明的,这样做可以更加简洁, 直接,紧凑。

2、复用:复用了现存的类,解决因环境要求不一致的问题。

3、低耦合:将目标类与源类解耦,引入一个适配器重用源类(适配器类),遵守开放-关闭原则。

时间: 2024-08-24 22:07:43

软件设计模式之适配器模式的相关文章

作业06之《软件设计模式》

我们在上个学期的课上已经学过了设计模式,但是都是在系统学习的基础上去认识软件设计模式的.所以后来在网上查了很多资料增加了很多自己的认识. 模式的含义其实就是对前人经验的总结,设计模式初期也是起源于建筑领域,它的目的就是为后人设计与开发基于面向对象的软件提供指导方针和成熟的解决方案,可以被认为是对软件开发这一问题的解法的某种统一表示,是在一定条件下出现的问题以及解法. 设计模式有一个定义:设计模式是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结,使用设计模式是为了可重用代码.让代

简述23种软件设计模式

简述23种软件设计模式 一.设计模式分类 总体来说设计模式分为三大类: 五种创建型模式:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 七种结构型模式:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 十一种行为型模式:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模式. 二.设计模式概述 创建型模式 1.工厂方法模式 工厂方法模式的创建是因为简单工厂模式有一个问题,在简单工厂模式

设计模式之适配器模式(Adapter Pattern)

适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作. 1. 解决的问题 即Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作. 2. 模式中的角色 2.1 目标接口(Target):客户所期待的接口.目标可以是具体的或抽象的类,也可以是接口. 2.2 需要适配的类(Adaptee):需要适配的类或适配者类. 2.3 适配器(Adapter):通过包装一个需要适配的对象,把

软件设计模式

软件设计模式大致能够分为三类.共23种. 创建型模式:单例模式,抽象工厂模式.建造者模式,工厂模式.原型模式. 结构型模式:适配器模式,桥接模式,装饰模式.组合模式,外观模式,享元模式.代理模式. 行为型模式:模板方法模式,命令模式.迭代器模式,观察者模式,中介者模式,备忘录模式,解释器模式.状态模式,策略模式,责任链模式.訪问者模式. 经常使用的有:装饰模式.代理模式,适配器模式,观察者模式.策略模式.模板模式,工厂模式.

设计模式之适配器模式(Adapter)摘录

23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象.创建型模式有两个不断出现的主旋律.第一,它们都将关于该系统使用哪些具体的类的信息封装起来.第二,它们隐藏了这些类的实例是如何被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以

C#设计模式之六适配器模式(Adapter Pattern)【结构型】

原文:C#设计模式之六适配器模式(Adapter Pattern)[结构型] 一.引言 从今天开始我们开始讲[结构型]设计模式,[结构型]设计模式有如下几种:适配器模式.桥接模式.装饰模式.组合模式.外观模式.享元模式.代理模式.[创建型]的设计模式解决的是对象创建的问题,那[结构型]设计模式解决的是类和对象的组合关系的问题.今天我们就开始讲[结构型]设计模式里面的第一个设计模式,中文名称:适配器模式,英文名称:Adapter Pattern.说起这个模式其实很简单,在现实生活中也有很多实例,比

软件设计模式概述

每个模式都描述了在环境中反复出现的(某类)问题,并以一种适当的方式描述该问题的核心解决方案, 以使该方案可以千百遍地被重复使用.核心思想是进行设计复用. 软件设计模式是对软件设计经验的总结,是对软件设计中反复出现的设计问题的成功解决方案的描述. 软件设计模式通常包含四个基本要素: 模式名称,问题,解决方案以及结果. 面向对象设计模式主要分为三类: 创建型模式:如工厂方法模式,抽象工厂模式,生成器模式和单例模式 结构型模式:如组合模式,适配器模式,外观模式和桥接模式 行为型模式:如迭代器模式,访问

设计模式之适配器模式

适配器模式(Adapter Pattern)有时候也称包装样式或者包装.将一个类的接口转接成用户所期待的.一个适配使得因接口不兼容而不能在一起工作的类工作在一起,做法是将类别自己的接口包裹在一个已存在的类中. Adapter Pattern有两种: 类的Adapter Pattern(继承) 对象的Adapter Pattern(委托) 下面我们用第一种来实现适配器模式: 我们首先来看看类图: 具体实现如下: Banner类: public class Banner { private Stri

大话设计模式_适配器模式(Java代码)

适配器模式:将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 简单描述: 大话设计模式中的截图: 代码例子: AbstractPlayer类: 1 package com.longsheng.adapter; 2 3 public abstract class AbstractPlayer { 4 5 public abstract void attack(); 6 7 public abstract void defenc