`

第九课 适配器模式

阅读更多

第九课 适配器模式

       今天我们来看一看适配器模式。这是一个常用的模式,作用也很简单,举例说明一下。现在我们有一个团队,在做一个大型项目。A同志负责写一些基类。它定义了一个读写操作类,由一个方法readbyte(),正如名字说说的,将文本读取,返回byte[]的方法。现在呢,B定义了一个接口,里面包含了2个方法,readByte(),和readString()。并且设计者基于这个接口做了很多应用。现在C同志犯愁了。A只给了他一个readByte(),而根据设计,他需要用B的接口。可是现在没有一个readString()的方法呀。那么怎么办呢。他就需要实现一个适配器。将A的类适配到B的接口上去。简单的说就是利用一下A的readbyte()方法,来实现一下readString()方法,这样不就满足了B的接口了吗,也能满足设计者的需求。这就是适配器模式了。就像美国的电源是110v,中国是220v。美国电器来到中国用,必须要通过一个 变压器(适配器) 来把电流改成110v才能正常使用。中间的适配器,就想C写的实现一样。

       转一段原话:在 GoF 的经典著作《设计模式》中指出: Adapter 模式的目的就是将类的接口转换成客户对象需要的接口, Adapter 模式使原本不相容的接口变的相容。也就是说我们有一个可以满足我们需要的对象,但是她的接口却不是象我们所期望的那样,而我们现在所需要的就是创建一个新的接口,让原本的接口能够满足我们的需要。

       这在拿过别人的类来做应用的时候很常用的。毕竟不能期待别人给你的接口完全符合你的需要,相信经常给不同设备写应用的同志很有感触吧。

 

       在实际应用中适配器基本有两种实现方法。

1.       基于类的实现

2.       基于对象的实现

 

下面分别来看1个例子

 

基于类的适配器模式实现:

首先看要适配到的接口(或基类,也就是上文例子B的接口)

1.        package com.javapatterns.adapter.classAdapter;
2.        

3.        public interface Target {
4.            byte[] readByte();
5.        

6.            string readString();
7.        }
8.        

9.        

Target接口期待这两个方法,readByte()和readString()。

 

接着看A实现的类对象:

1.        package com.javapatterns.adapter.classAdapter;
2.        

3.        public class Adaptee {
4.            public byte[] readByte(){...}
5.        }
6.        

Adaptee类只提供了readByte()一个方法,无法满足Target接口的期望。

 

再看C的处理方法:

1.        package com.javapatterns.adapter.classAdapter;
2.        

3.        public class Adapter extends Adaptee implements Target {
4.            public string readString(){
5.                byte[] bytes = readByte();
6.                return byte2String(bytes);
7.            }
8.        

9.            private string byte2String(byte[] bytes){...}
10.     }
11.     

 

他继承了Adaptee类,同时实现Target 接口。这样他自然就拥有了readByte()方法的实现。只需要实现Target接口期望的另一个方法readString()即可。这里用了集成Adaptee的方式,所以说他是基于类的实现。

      

       基于对象的适配器实现:

接口Target与Adaptee类不变,这里不再描述了。来关注下C的实现。

1.        package com.javapatterns.adapter.objectAdapter;
2.        

3.        public class Adapter implements Target {
4.        public Adapter(Adaptee adaptee){
5.                super();
6.                this.adaptee = adaptee;
7.            }
8.        

9.            public byte[] readByte(){
10.             return adaptee.readByte();
11.         }
12.     

13.         public string readString(){
14.             return byte2String(adaptee.readByte());
15.         }
16.     

17.         private Adaptee adaptee;
18.         private string byte2String(byte[] bytes){...}
19.     }
20.     

 

注意看这里C巧妙的利用了一个似有属性 adaptee 来实现Target 所期望的两个方法。这种方式就是基于对象的实现。

 

在实际应用中,很多情况下A提供的方法并不能直接作为B期望的方法的实现,所以基于对象的实现是颇为常用的手段。

 

先说个大家都知道的例子。Java的jdbc驱动。其实不同的数据库操作,都有这自己的接口。Jdbc就相当于一个适配器。将Oracle,sqlserver.mysql等操作接口适配成统一的jdbc的数据操作接口。进而方便客户调用。

 

再说一个我实际的例子。我在做发卡程序的时候,需要用到读写射频卡(可以理解为IC卡)的发卡器。不同厂家的发卡起都提供自己的接口。但是我要兼容多家厂商的发卡器啊,所以这里我采取了适配器模式。定义了一个统一的接口,里面包含基本方法(基本就是 init read write 这些基本操作。对于不同品牌发卡器来说,只是接口不同,基本用法都是相同的)然后通过适配器类来将不同品牌的接口适配到我统一的接口上。在通过一个反射工厂来获得具体的适配器类的接口引用。这样我用那个厂家的发卡器,只需要做下配置即可。如果采取了新厂家的发卡器,只需要新增一个适配器实现。很方便吧。

 

最后追加一个C#的例子,是大话设计模式的例子。我想例子多了终归是好的。、

1.        using System;
2.        using System.Collections.Generic;
3.        using System.Text;
4.        

5.        namespace 适配器模式
6.        {
7.            class Program
8.            {
9.                static void Main(string[] args)
10.             {
11.                 Player b = new Forwards("巴蒂尔");
12.                 b.Attack();
13.     

14.                 Player m = new Guards("麦克格雷迪");
15.                 m.Attack();
16.     

17.                 //Player ym = new Center("姚明");
18.                 Player ym = new Translator("姚明");
19.                 ym.Attack();
20.                 ym.Defense();
21.     

22.                 Console.Read();
23.             }
24.         }
25.     

26.         //篮球运动员
27.         abstract class Player
28.         {
29.             protected string name;
30.             public Player(string name)
31.             {
32.                 this.name = name;
33.             }
34.     

35.             public abstract void Attack();
36.             public abstract void Defense();
37.         }
38.     

39.         //前锋
40.         class Forwards : Player
41.         {
42.             public Forwards(string name)
43.                 : base(name)
44.             {
45.             }
46.     

47.             public override void Attack()
48.             {
49.                 Console.WriteLine("前锋 {0} 进攻", name);
50.             }
51.     

52.             public override void Defense()
53.             {
54.                 Console.WriteLine("前锋 {0} 防守", name);
55.             }
56.         }
57.     

58.         //中锋
59.         class Center : Player
60.         {
61.             public Center(string name)
62.                 : base(name)
63.             {
64.             }
65.     

66.             public override void Attack()
67.             {
68.                 Console.WriteLine("中锋 {0} 进攻", name);
69.             }
70.     

71.             public override void Defense()
72.             {
73.                 Console.WriteLine("中锋 {0} 防守", name);
74.             }
75.         }
76.     

77.         //后卫
78.         class Guards : Player
79.         {
80.             public Guards(string name)
81.                 : base(name)
82.             {
83.             }
84.     

85.             public override void Attack()
86.             {
87.                 Console.WriteLine("后卫 {0} 进攻", name);
88.             }
89.     

90.             public override void Defense()
91.             {
92.                 Console.WriteLine("后卫 {0} 防守", name);
93.             }
94.         }
95.     

96.         //外籍中锋
97.         class ForeignCenter
98.         {
99.             private string name;
100.          public string Name
101.          {
102.              get { return name; }
103.              set { name = value; }
104.          }
105.  

106.          public void 进攻()
107.          {
108.              Console.WriteLine("外籍中锋 {0} 进攻", name);
109.          }
110.  

111.          public void 防守()
112.          {
113.              Console.WriteLine("外籍中锋 {0} 防守", name);
114.          }
115.      }
116.  

117.      //翻译者
118.      class Translator : Player
119.      {
120.          private ForeignCenter wjzf = new ForeignCenter();
121.  

122.          public Translator(string name)
123.              : base(name)
124.          {
125.              wjzf.Name = name;
126.          }
127.  

128.          public override void Attack()
129.          {
130.              wjzf.进攻();
131.          }
132.  

133.          public override void Defense()
134.          {
135.              wjzf.防守();
136.          }
137.      }
138.  }
139.  

 

这里有一个基类Player,包含进攻和防守。不同位置都有不同的实现。但是最终大家都适配到了Player上。

 

       其实现在讲到这里了,大家应该对“开发模式”这个东西有一定了解了。这里重在思想,不重实现。(有点像依赖倒转原则哦)实际应用中很多情况下都是各种模式组合应用。而这个例子打眼一看好像根本都不算适配器模式。但他的思想是把各个位置的人员都适配到Player上面,体现了适配器的思想。所以他可以叫做适配器模式。

 

       其实到这里我实际用过的设计模式就讲得差不多了。再之后的我也是要先学习了。好了,不废话了,学习~

 

       作者:王文斌

       转载请注明出处


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lanwilliam/archive/2008/10/29/3173433.aspx

分享到:
评论

相关推荐

    JAVA设计模式(抽象类与适配器模式)

    同时,“[浪曦原创]JAVA设计模式 第1讲 抽象类与适配器模式(jzkangta).exe”应该是一个视频教程,可以帮助你更直观地学习。PPT文件“抽象类与适配器模式.ppt”则可能是教学幻灯片,列出了关键点和示例。最后,“demo...

    设计模式之适配器模式

    适配器模式是一种常用的设计模式,它在软件工程中扮演着重要的角色,特别是在解决系统间的兼容性和接口不匹配问题时。适配器模式的核心思想是将一个类的接口转换成客户希望的另一个接口,使原本由于接口不兼容而无法...

    设计模式之适配器模式Java实现和类设计图

    适配器模式是一种常用的设计模式,它在软件工程中扮演着重要的角色,允许不兼容的接口之间进行通信。在这个Java实现中,我们将深入探讨适配器模式的两大类型:类适配器模式和对象适配器模式,并通过具体的代码示例和...

    java设计模式之适配器模式

    在Java中,适配器模式扮演着重要的角色,尤其在处理遗留代码或者第三方库集成时,能够有效地解决接口不匹配的问题。本文将深入探讨适配器模式的概念、类型、优点和如何在Java中实现。 一、适配器模式概念 适配器...

    设计模式 - 适配器模式(C++实例)

    适配器模式的应用场景广泛,例如在集成第三方库、兼容旧版API或者在不同编程语言之间进行通信时。它提供了一种优雅的解决方案,使得系统可以灵活地扩展和适应不断变化的需求,同时也保持了原有组件的可复用性。 ...

    java 动态代理模式 适配器模式

    而适配器模式则广泛应用于各种集成场景,比如将第三方库的API转换为项目统一的接口,或者在不同的操作系统或硬件之间进行数据交换。 结合给定的文件名"文本",我们可以推测可能提供了关于这两种模式的示例代码或者...

    第9讲_适配器模式(Adapter)

    适配器模式是一种设计模式,它允许不兼容的类或接口之间进行通信和协作。这种模式的核心在于创建一个适配器类,该类将原始类(Adaptee)的接口转换为客户期望的目标接口(Target)。适配器模式分为基于类的适配器...

    java中适配器模式案例

    在Java中,适配器模式广泛应用于系统集成、旧代码复用以及第三方库的兼容性问题。 适配器模式主要有两种形式:类适配器模式和对象适配器模式。类适配器模式是通过继承目标接口(需要适配的接口)和被适配类(原始不...

    适配器模式案例代码

    适配器模式是一种软件设计模式,它允许两个不兼容的接口之间进行通信。在这个案例中,我们关注的是如何通过适配器模式解决实际编程问题。文章《适配器模式案例代码》提供了具体的实现示例,链接指向了CSDN博主...

    适配器模式demo源码

    适配器模式是一种常用的设计模式,它在软件开发中起到了桥梁的作用,允许两个不兼容的接口之间进行通信。在这个“适配器模式demo源码”中,我们可以深入理解这一模式的实现方式及其应用场景。 适配器模式的核心思想...

    适配器模式源代码

    适配器模式是一种常用的设计模式,它在软件工程中扮演着重要的角色,允许不兼容的接口之间进行通信。在这个源代码实例中,我们看到的是如何通过适配器模式来实现不同对象之间的协作,使得原本无法直接交互的系统组件...

    设计模式之--适配器模式

    例如,在软件开发中,当需要将一个第三方库的API与自己项目中的接口进行对接时,适配器模式可以帮助我们平滑过渡,减少对接带来的复杂性。 在实际应用中,适配器模式可能涉及的步骤包括: 1. 确定目标接口,这是...

    设计模式-适配器模式(讲解及其实现代码)

    适配器模式是一种常用的设计模式,它在软件工程中扮演着重要的角色,特别是在处理系统集成、遗留代码重用以及不同接口之间兼容性问题时。适配器模式的主要目的是将两个不兼容的接口融合在一起,使得原本无法直接协作...

    设计模式系列之适配器模式

    例如,当一个新的第三方库提供了更好的功能,但接口与现有系统不匹配时,就可以使用适配器模式将新库的接口转换为系统可接受的形式。 总的来说,适配器模式是软件设计中解决接口不兼容问题的重要工具,它使得不同...

    Java设计模式之适配器模式

    适配器模式是解决接口不兼容问题的有效手段,尤其在集成第三方库或模块时非常有用。通过使用适配器,我们可以避免对现有系统的大量修改,同时也提高了代码的复用性和可维护性。无论是类适配器还是对象适配器,选择...

    实验七:适配器模式.rar

    适配器模式是一种软件设计模式,它允许两个不兼容的接口之间进行通信。在本实验中,我们将深入探讨适配器模式的概念、应用场景以及如何在实际编程中实现它。适配器模式通常分为类适配器和对象适配器两种形式。 ...

Global site tag (gtag.js) - Google Analytics