1、出现原因:

在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象”放在新的环境中应用,但是新环境要求的接口是这些现存对象不满足的。(所以可以在他们之间建立一个适配器的中间类

 

2、意图:

将一个类的接口转换成客户希望的另一个接口。Adapter模式使得原本由接口不兼容而不能一起工作的那些类可以一起工作。(就是在新环境的 接口 和 原来的 类之间 建立一个适配器,将他们联系起来

 

3、两种实现适配器模式的方式

1》对象适配器

推荐使用,因为相对于下面的类继承的方式耦合度更低 

结构图:

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

1对象适配器采用对象组合,通过引用一个类(原来的类)与另一个类接口(实现新的环境接口) 在对象适配器中通过组合获得Adaptee对象

 

2、通过调用Adaptee对象的方法,转换后返回Target结果

 

2》类的多继承方式

不推荐使用,因为使用继承实现的,对象之间的耦合度 过高

 结构图:

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

1、类适配器通过多继承对一个接口与另一个接口进行匹配。

 

2Target定义了Client使用的与特定领域相关的接口,Client通过调用Target实现某一个特定的操作。Adaptee是一个已经存在的类,需要与Target协同工作,这个接口需要适配。Adapter适配器适配AdapteeTarget接口。在类适配器中,通过继承获得Adaptee中的方法。

 

3、.NET不支持多重继承,因此当Target是一个类,而不是一个接口时无法实现类适配器,这时需要使用对象适配器。(如果,Target是抽象类的话,就不行了,因为 适配器在 c#里面是不支持多继承的),所以Target要是 接口,因为旧的系统已经继承了

 

4、代码演示

实现需求如下图:

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

实现代码:

  1     //新的环境(.Net不支持多继承,所以要使用接口),一个新的环境一个接口(然后 适配器 实现多个接口)
  2     public interface FootballPlayer
  3     {
  4         void Attact();
  5         void Defende();
  6     }
  7 
  8     public class FQianFeng : FootballPlayer
  9     {
 10         public void Attact()
 11         {
 12             Console.WriteLine("我是足球前锋,我要进攻了");
 13         }
 14 
 15         public void Defende()
 16         {
 17             Console.WriteLine("我是足球前锋,我要防守了");
 18         }
 19     }
 20 
 21 
 22     public class FZhongFeng : FootballPlayer
 23     {
 24         public void Attact()
 25         {
 26             Console.WriteLine("我是足球中锋,我要进攻了");
 27         }
 28 
 29         public void Defende()
 30         {
 31             Console.WriteLine("我是足球中锋,我要防守了");
 32         }
 33     }
 34 
 35     public class FHouWei : FootballPlayer
 36     {
 37         public void Attact()
 38         {
 39             Console.WriteLine("我是足球后卫,我要进攻了");
 40         }
 41 
 42         public void Defende()
 43         {
 44             Console.WriteLine("我是足球后卫,我要防守了");
 45         }
 46     }
 47 
 48 
 49     //另一个新的环境 接口
 50     public interface BasketBallPlayer
 51     {
 52         void JinGong();
 53         void FangShou();
 54     }
 55 
 56     public class BQianFeng : BasketBallPlayer
 57     {
 58         public void JinGong()
 59         {
 60             Console.WriteLine("我是篮球前锋,我要进攻了");
 61         }
 62 
 63         public void FangShou()
 64         {
 65             Console.WriteLine("我是篮球前锋,我要防守了");
 66         }
 67     }
 68 
 69 
 70 
 71     //要被适配的 类(Adaptee)
 72     //中国运动员:既会 打篮球,又会  踢足球
 73     public class ChinesePlayer
 74     {
 75         public void 足球进攻()
 76         {
 77             Console.WriteLine("我是中国运动员,我要进行足球进攻了");
 78         }
 79         public void 足球防守()
 80         {
 81             Console.WriteLine("我是中国运动员,我要进行足球防守了");
 82         }
 83         public void 篮球进攻()
 84         {
 85             Console.WriteLine("我是中国的运动员,我要进行篮球进攻了");
 86         }
 87         public void 篮球防守()
 88         {
 89             Console.WriteLine("我是中国的运动员,我要进行篮球防守了");
 90         }
 91     }
 92 
 93 
 94 
 95     //下面是一个 Adapter适配器的类
 96     public class Adapter : FootballPlayer, BasketBallPlayer  
 97     {
 98         //其实这里举的例子不适当,因为 是  先有  旧的系统(Adaptee被适配对象),才有新的环境。而且是 新的环境要使用旧的系统,才不得已使用适配器模式,,而且两个 新的环境 使用的 同一 旧的系统(也就是使用的同一 对象)
 99 
100         ChinesePlayer player = new ChinesePlayer();//这里使用的是  对象组合的方式  实现的 适配器模式
101         public void Attact()
102         {
103             player.足球进攻();
104         }
105 
106         public void Defende()
107         {
108             player.足球防守();
109         }
110 
111         public void JinGong()
112         {
113             player.篮球进攻();
114         }
115 
116         public void FangShou()
117         {
118             player.篮球防守();
119         }
120     }

Adapter模式