zoukankan      html  css  js  c++  java
  • 设计模式------适配器模式(二)

    使用场景和原则:

      当系统的数据和行为都正确,但接口不符合时,我们应该考虑用适配器。适配器主要应用于希望复用现存的类,但是接口又与复用环境要求的不一致。就是说,两个类所做的事相同或者相似,但是具有不同的接口,这也是一种迫于无奈,双发都不太容易修

    改的时候。一般情况下,尽可能的前期不考虑适配器,当然了,如果像对接类似第三方组件之类的,没必要为了它改变自己的接口,那就可以考虑。像我们的 ADO.net里面的 DataAdapter。

      

    案例分析:

       姚明去NBA打球,刚到NBA语言不通,这个时候姚明有没有必要迅速学外语呢,答案肯定是否定的。那姚明要怎么跟人沟通?答案是:请一个翻译。照着这个思路,我们画一下类图。

     

    首先,球员的基本动作是Attack和Defense,球员拥有名字。

      public abstract class 球员
        {
           protected string name;
            public 球员 (string name)
            {
                this.name = name;
            }
    
            public abstract void Attack();
            public abstract void Defense();
        }

    球员分为三种,前锋,中锋,后卫。

        public class 前锋 : 球员
        {
            public 前锋(string name)
                : base(name)
            {
            }
    
            public override void Attack()
            {
                Console.WriteLine("前锋{0}发起进攻啦", name);
            }
    
            public override void Defense()
            {
                Console.WriteLine("前锋{0}立刻防守~", name);
            }
        }
    
    
    
        public class 中锋 : 球员
        {
            public 中锋(string name)
                : base(name)
            {
            }
    
            public override void Attack()
            {
                Console.WriteLine("中锋{0}发起进攻啦", name);
            }
    
            public override void Defense()
            {
                Console.WriteLine("中锋{0}立刻防守~", name);
            }
        }
    
        public class 后卫 : 球员
        {
            public 后卫(string name)
                : base(name)
            {
            }
    
            public override void Attack()
            {
                Console.WriteLine("后卫{0}发起进攻啦", name);
            }
    
            public override void Defense()
            {
                Console.WriteLine("后卫{0}立刻防守~", name);
            }
        }

    这个时候来了一个外籍中锋,他拥有的属性和行为都球员基类不一样。

     public class 外籍中锋
        {
            string name;
    
            public 外籍中锋(string name)
            {
                this.name = name;
            }
    
            public void 进攻()
            {
                Console.WriteLine("外籍中锋{0}进攻", name);
    
            }
    
            public void 防守()
            {
                Console.WriteLine("外籍中锋{0}防守", name);
            }
    
        }

    这个时候,翻译官就可以出来工作了。

    public class 翻译官:球员
       {
           private 外籍中锋 w;
           public 翻译官(string name) : base(name)
           {
               w = new 外籍中锋(name);
           }
        
           public override void Attack()
           {
               //翻译进攻命令
              w.进攻();
           }
    
           public override void Defense()
           {
               //翻译防守命令
               w.防守();
           }
        }

    最后,如何调用

     球员 a=new 前锋("前锋_巴蒂尔");
                a.Attack();
                //教练直接给翻译官下命令
                球员 b = new 翻译官("中锋_姚明");
                b.Attack();
                b.Defense();
                Console.Read();

    案例总结:我觉得适配器是一种后期弥补的模式,不能盲目的用。姚明去NBA打球,不需要立刻学会外语,教练通过下命令给翻译官,翻译官转达给姚明,姚明执行命令。其实,这样的做法,必须依赖翻译官,最好方式就是姚明自己会外语,所以,适配器模式不能乱用,就像著名的扁鹊三兄弟的故事,如果前期设计好一点,事前能控制,而不是事后,经常改动。

    人生匆匆几十年,BeYourself...
  • 相关阅读:
    NTDLL未文档化函数RtlGetNtVersionNumbers获取操作系统版本
    FormatMessage与GetLastError配合使用,排查windows api调用过程中的错误
    [翻译]:怎样从C/C++代码中对C#进行回调
    解决libcurl7.50.3在windows XP SP3 VC++ 6.0下编译报错 unresolved external symbol __imp__IdnToAscii@20 unresolved external symbol __imp__IdnToUnicode@20
    Windows XP SP3 VC6环境下成功编译openssl-0.9.8zh
    Windows XP SP3下编译安装openssl-1.1.0b
    Ubuntu关闭自动更新
    IDEA中分析JVM堆导出文件heapdump-1591244153347.hprof文件
    Linux环境下非root用户通过防火墙nat将端口转发到8080端口
    Linux自定义java程序运行脚本的命令
  • 原文地址:https://www.cnblogs.com/huagege/p/7562859.html
Copyright © 2011-2022 走看看