• C#学习笔记-适配器模式


    什么是适配器模式?

       适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口。

       Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

    什么时候运用适配器模式?

       在想使用一个已经存在的类时,如果它的接口,也就是它的方法与我们当前的要求不相同时,就需要考虑用到适配器模式了。

       一般而言,使用适配器模式是出于无奈之举,一般存在于软件开发后期或者维护期,在软件设计阶段,我们还是尽量避免该模式的使用。

    适配器模式的组成

        Target:目标接口,也就是客户所期待的接口。目标可以是具体的或者抽象的类,也可以是接口。

      Adpatee:需要适配的类。也就是我们需要与目标接口对接成功的类。

      Adapter:中间起到链接作用的类。通过在内部包装一个Adptee对象,将源接口转换成目标接口。

    适配器模式具体实现

    适配器模式的结构

       

    适配器模式的实现

    Target类:也就是目标类

    1 class Target
    2 {
    3     public virtual void Request()
    4     {
    5          Console.WriteLine("普通请求");
    6      }
    7 }

    Adaptee类:需要适配的类

    1 class Adaptee
    2 {
    3      public void SpecificRequest()
    4      {
    5          Console.WriteLine("特殊请求");
    6      }
    7 }

    Adapter类:

     1 class Aapter : Target
     2 { 
     3      private Adaptee adaptee = new Adaptee();
     4      /// <summary>
     5      /// 这样就可以把表面调用Request()方法变成实际调用SpecificRequest()
     6      /// </summary>
     7      public override void Request()
     8      {
     9           adaptee.SpecificRequest();
    10       }
    11 }

    主函数调用:

    1 static void Main(string[] args)
    2 {
    3        //对客户端来说,调用的是Target的Request()
    4        Target target = new Aapter();
    5        target.Request();
    6 
    7         Console.Read();
    8 }

    实例解析

       为了深化理解,我们准备一个具体的实例来分析。

       姚明作为一个外籍的球员在进入NBA初期,由于英文水平一般,常常听不懂教练的指挥与安排,需要翻译来全程跟随以实现沟通。请就此来写出具体的情况。

     分析:

       在这里,我们不难发现教练的指挥与安排就是Target,姚明就是Adaptee,而翻译就理所当然成了Adapter,那么我们就能分析出彼此的关系了。

      

    具体实现:

      1     class Program
      2     {
      3         static void Main(string[] args)
      4         {
      5             Player b = new Forwards("A");
      6             b.Attack();
      7 
      8             Player m = new Guards("B");
      9             m.Attack();
     10             
     11             //通过翻译,姚明知道了需要做的事情
     12             Player ym = new Translator("姚明");
     13             ym.Attack();
     14             ym.Defense();
     15 
     16             Console.Read();
     17         }
     18 
     19         abstract class Player
     20         {
     21             protected string name;
     22             public Player(string name)
     23             {
     24                 this.name = name;
     25             }
     26             public abstract void Attack();
     27             public abstract void Defense();
     28         }
     29         /// <summary>
     30         /// 前锋
     31         /// </summary>
     32         class Forwards : Player
     33         {
     34             public Forwards(string name) : base(name)
     35             {
     36             }
     37             public override void Attack()
     38             {
     39                 Console.WriteLine("前锋{0} 进攻", name);
     40             }
     41             public override void Defense()
     42             {
     43                 Console.WriteLine("前锋{0} 防守", name);
     44             }
     45         }
     46         /// <summary>
     47         /// 中锋
     48         /// </summary>
     49         class Center : Player
     50         {
     51             public Center(string name) : base(name)
     52             {
     53             }
     54             public override void Attack()
     55             {
     56                 Console.WriteLine("中锋{0} 进攻", name);
     57             }
     58             public override void Defense()
     59             {
     60                 Console.WriteLine("中锋{0} 防守", name);
     61             }
     62         }
     63         /// <summary>
     64         /// 后卫
     65         /// </summary>
     66         class Guards : Player
     67         {
     68             public Guards(string name) : base(name)
     69             {
     70             }
     71             public override void Attack()
     72             {
     73                 Console.WriteLine("后卫{0} 进攻", name);
     74             }
     75             public override void Defense()
     76             {
     77                 Console.WriteLine("后卫{0} 防守", name);
     78             }
     79         }
     80         /// <summary>
     81         /// 翻译是继承于运动员的,因为他需要直接理解教练的意思
     82         /// 但是他实际需要传达的是外籍球员,所以他调用的是外籍球员所理解的方法=>也就是翻译的作用
     83         /// </summary>
     84         class Translator : Player
     85         {
     86             private ForeignCenter fc = new ForeignCenter();
     87             public Translator(string name) : base(name)
     88             {
     89                 fc.Name = name;
     90             }
     91             public override void Attack()
     92             {
     93                 fc.进攻();
     94             }
     95             public override void Defense()
     96             {
     97                 fc.防守();
     98             }
     99         }
    100         /// <summary>
    101         /// 作为外籍球员,他有自己的姓名和进攻防守方式等
    102         /// 其他的事情交给翻译就好了
    103         /// </summary>
    104         class ForeignCenter
    105         {
    106             private string name;
    107             public string Name
    108             {
    109                 get { return name; }
    110                 set { name = value; }
    111             }
    112             public void 进攻()
    113             {
    114                 Console.WriteLine("外籍中锋{0} 进攻", name);
    115             }
    116             public void 防守()
    117             {
    118                 Console.WriteLine("外籍中锋{0} 防守", name);
    119             }
    120         }
    121     }

    适配器模式的优缺点

       像之前提到的适配器能在后期维护的时候起到很大的作用,能在开发新的功能的时候保护原来软件的稳定性,但是初期的时候还是能避免就尽量避免吧!

    备注:文中所有代码及知识点均来自于《大话设计模式》,本人属于边学边看边敲代码边总结的阶段。

  • 相关阅读:
    小星星短视频app
    多元思维模型整理--查理芒格---每本书的思维模型都要添加到这里
    张一鸣 南开大学演讲
    增长黑客特训营--入门
    深度学习 TensorFlow
    推荐算法之---FM算法;
    idea更改代码格式化快捷键
    centos7启动MySQL报 Job for mysqld.service failed because the control process exited with error code. See "systemctl status mysqld.service" and "journalctl -xe" for details.
    springboot启动报无法加载主类解决方法
    centos7搭建 mongodb 主从复制
  • 原文地址:https://www.cnblogs.com/Aries-rong/p/7837972.html
Copyright © 2020-2023  润新知