zoukankan      html  css  js  c++  java
  • 设计模式-结构型-适配器模式

    适配器模式(Adapter Pattern):

      将某个类的接口转换成客户端期望的另一个接口表示,主要的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作。如读卡器是作为内存卡和笔记本之间的适配器,需要将内存卡插入读卡器,再将读卡器插入笔记本,这样笔记本就可以读取内存卡了。

    适配器模式的主要角色:

      

      1、目标接口(Target):当前系统业务所期待的接口,它可以是抽象类或接口。

      2、适配者类(Adaptee):被访问和适配的现存组件库中的组件接口。

      3、适配器类(Adapter):转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。

    适配器模式主要分三类:类适配器模式、对象适配器模式、接口适配器模式(java中使用)。接下来我们来详细介绍下这三种形式。

      1、类适配器模式

        当前去外地出差,工作繁忙,回到宾馆也不得不工作。当你拿出电脑,准备接电源,卧槽...不支持!!!电源是两孔的,而插座是三孔的,怎么办呢?你会想到去楼下小商店买个转换插座,将三孔插座转成两孔的来用,简直太聪明了。 

        (以该图代替,原理类似)

     1 internal class Program
     2 {
     3     private static void Main(string[] args)
     4     {
     5         Computer computer = new Computer(new TwoHoleSocket());
     6         computer.Connect();
     7         // 类适配器的缺点
     8         TwoHoleSocket twoHoleSocket = new TwoHoleSocket();
     9         twoHoleSocket.Test();
    10     }
    11 }
    12 
    13 internal class Computer
    14 {
    15     private readonly Transformer transformer;
    16 
    17     public Computer(Transformer transformer)
    18     {
    19         this.transformer = transformer;
    20     }
    21 
    22     public void Connect()
    23     {
    24         transformer.Transfrom();
    25         Console.WriteLine("连接成功!!!");
    26     }
    27 }
    28 
    29 /// <summary>
    30 /// 三孔插座Adaptee
    31 /// </summary>
    32 internal class ThreeHoleSocket
    33 {
    34     public void Show()
    35     {
    36         Console.WriteLine("我是三孔插座");
    37     }
    38 
    39     public void Test()
    40     {
    41         Console.WriteLine("我是多余的");
    42     }
    43 }
    44 
    45 /// <summary>
    46 /// 转换器Target
    47 /// </summary>
    48 internal interface Transformer
    49 {
    50     void Transfrom();
    51 }
    52 
    53 /// <summary>
    54 ///  两孔插座Adapter
    55 /// </summary>
    56 internal class TwoHoleSocket : ThreeHoleSocket, Transformer
    57 {
    58     public void Transfrom()
    59     {
    60         base.Show();
    61         Console.WriteLine("转换中。。。。");
    62         Console.WriteLine("哈哈哈,我已经是两孔插座");
    63     }
    64 }
    view code

        分析:对于类适配器来说,Adapter与Adaptee过于耦合,增加了使用成本,且会暴露不必要的方法。

      2、对象适配器模式

        当手机没电需要充电,你不可能直接使用220V的电压,如果你真这么做了,请注意人身安全及购买一台新机。此时,充电器就起到了转换器的作用,将220V电压转换成手机可使用的5V电压。

        

     1 class Program
     2 {
     3     static void Main(string[] args)
     4     {
     5         Phone phone = new Phone();
     6         phone.charging(new VoltageAdapter(new Voltage220V()));
     7     }
     8 }
     9 
    10 class Phone
    11 {
    12     public void charging(Voltage5V voltage5V)
    13     {
    14         voltage5V.output5V();
    15     }
    16 }
    17 
    18 class Voltage220V
    19 {
    20     public void output220V()
    21     {
    22         Console.WriteLine("220V");
    23     }
    24 }
    25 
    26 interface Voltage5V
    27 {
    28     void output5V();
    29 }
    30 
    31 class VoltageAdapter : Voltage5V
    32 {
    33     private readonly Voltage220V voltage220V;
    34 
    35     public VoltageAdapter(Voltage220V voltage220V)
    36     {
    37         this.voltage220V = voltage220V;
    38     }
    39 
    40     public void output5V()
    41     {
    42         voltage220V.output220V();
    43         Console.WriteLine("5V");
    44     }
    45 }
    view code

        分析:以松耦合的方式实现适配器模式,推荐使用。   

      3、接口适配器模式(java中使用,c#中能够实现但意义不大)

         

     1 class Program
     2 {
     3     static void Main(string[] agrs)
     4     {
     5         Power5VAdapter power5VAdapter = new Power5VAdapter(new AC220());
     6         Console.WriteLine(power5VAdapter.output5V());
     7     }
     8 }
     9 
    10 class AC220
    11 {
    12     public int output220V()
    13     {
    14         int output = 220;
    15         return output;
    16     }
    17 }
    18 
    19 interface Voltage
    20 {
    21     int output5V();
    22     int output9V();
    23     int output12V();
    24     int output24V();
    25 }
    26 
    27 abstract class PowerAdapter : Voltage
    28 {
    29     private readonly AC220 ac220;
    30 
    31     public PowerAdapter(AC220 ac220)
    32     {
    33         this.ac220 = ac220;
    34     }
    35 
    36     public virtual int output12V()
    37     {
    38         return ac220.output220V();
    39     }
    40 
    41     public virtual int output24V()
    42     {
    43         return ac220.output220V();
    44     }
    45 
    46     public virtual int output5V()
    47     {
    48         return ac220.output220V();
    49     }
    50 
    51     public virtual int output9V()
    52     {
    53         return ac220.output220V();
    54     }
    55 }
    56 
    57 class Power5VAdapter : PowerAdapter
    58 {
    59     private AC220 ac220;
    60 
    61     public Power5VAdapter(AC220 ac220)
    62         : base(ac220)
    63     {
    64         this.ac220 = ac220;
    65     }
    66 
    67     public override int output5V()
    68     {
    69         int output = 0;
    70         if (this.ac220 != null)
    71         {
    72             output = this.ac220.output220V() / 44;
    73         }
    74         return output;
    75     }
    76 }
    view code

    优点:

      1、客户端通过适配器可以透明地调用目标接口。

      2、复用了现存的类,开发人员不需要修改原有代码而重用现有的适配者类。

      3、将目标类和适配者类解耦,解决了目标类和适配者类接口不一致的问题。

    缺点:

      1、对类适配器来说,更换适配器的实现过程比较复杂。

      2、过多的适配器,会让系统零乱,不易整体进行把握。

  • 相关阅读:
    nginx超时重发
    excel另存为csv
    数据清洗——python定位csv中的特定字符位置
    pandas.read_csv参数整理
    Python 如何在csv中定位非数字和字母的符号
    ORACLE SEQUENCE用法(转)
    Python安装distribute包
    ex41习题 41: 来自 Percal 25 号行星的哥顿人(Gothons)
    利用python去除红章
    UNDO表空间
  • 原文地址:https://www.cnblogs.com/az4215/p/11538446.html
Copyright © 2011-2022 走看看