• 接口


    问题的提出
    定义:开发一个应用,使不同型号的打印机都能与电脑连接
    上下文(环境):为了满足需求,公司现在购置了两类打印机,即打印机A和打印机B,它将与公司1000名员工的电脑连接,实现通信。并且公司在以后可能还会购买第三类打印机。
    分析上述问题,可能有如下方案
    方案一:分别定义PrintA和PrintB两个类。实现各自的Receive和Print方法,这么一来总共需要写四个方法。这种方法应该是最直观,最容易让人想到的。
    方案二:定义抽象类Printer,在里面写虚方法 Receive和 Print,使得这两台打印机分别继承此抽象类,并重写 Receive和Print方法。Computer类中包含一个类型为 Printer的成员变量,并为其编写get/set器,这样 Computer中只需要两个方法: ReceiveData和 PrintData,并通过多态性实现不同移动设备的读写。这种方法应该是接着会被想到的方法。
    方案三:与方案二基本相同,只是不定义抽象类,而是定义接口I Printer,修改打印机类。Computer中通过依赖接口IPrinter实现多态性。
           现在我们来分析一下上面三种方法。首先第一种方法最为直白,实现起来最简单,但是它有一个致命的弱点:可扩展性差。当将来有了第三中类型的打印机时,必须对Computer进行修改。这就如在一个真实的计算机上,为每一种打印机设备实现一个不同的插口、并分别有各自的驱动程序。当有了一种新的打印机设备后,我们就要将计算机大卸八块,然后增加一个新的插口,在编写一套针对此新设备的驱动程序。这种设计显 然不可取。

      此方案的另一个缺点在于,冗余代码多。在题目所给的环境中,已经说明打印机将与1000台电脑连接,这么一来,总共就需要写四千中方法。代码的重复量是相当大的。我们再来看方案二和方案三,之所以将这两个方案放在一起讨论,是因为他们基本是一个方案(从思想层面上来说),只不过实现手段不同,一个是使用了抽象类,一个是使用了接口,而且最终达到的目的应该是一样的。

      我们先来评价这种方案:首先它解决了代码冗余的问题,因为可以动态替换打印机,并且都实现了共同的接口,所以不管有多少种移不同类型的打印机,只要一个 Receive方法和一个Print方法,多态性就帮我们解决问题了。而对第一个问题,由于可以运行时动态替换,而不必将打印类编码在Computer 中,所以有了新的第三方设备,完全可以替换进去运行。这就是所谓的“依赖接口,而不是依赖于具体类”。如此一来,Computer和打印机类的耦合度大大下降。

    我们先来看一段断码:

    1.定义一个接口

    namespace _1.InterfaceTest

    {

         /// <summary>

         /// 定义打印机接口,不同类型的打印机都有共同的属性

         /// 他们都会接受电脑的信息(Receive)并且执行打印命令(Print)。

         /// </summary>

         public interface IPrinter

         {

            void Receive();

            void Print();

         }

    }

    2. 实现打印机类

    namespace _1.InterfaceTest

    {

      /// <summary>
        /// 实现A类打印机
        /// </summary>
        public class PrinterA : IPrinter
        {
            /// <summary>
            /// 实现接口定义的Receive方法
            /// </summary>
            public void Receive()
            {
                Console.WriteLine("PrinterA  receive message from Computer……");
                Console.WriteLine("Receive finished!");
            }
            /// <summary>
            ///  实现接口定义的Print方法
            /// </summary>
            public void Print()
            {
                Console.WriteLine("PrinterA execute the Computer command ……");
                Console.WriteLine("Print finished!");
            }
        }
        /// <summary>
        /// 实现B类打印机
        /// </summary>
        public class PrinterB : IPrinter
        {
            /// <summary>
            /// 实现接口定义的Receive方法
            /// </summary>
            public void Receive()
            {
                Console.WriteLine("PrinterB  receive message from Computer……");
                Console.WriteLine("Receive finished!");
            }
            /// <summary>
            ///  实现接口定义的Print方法
            /// </summary>
            public void Print()
            {
                Console.WriteLine("PrinterB execute the Computer command ……");
                Console.WriteLine("Print finished!");
            }
        }
    }
    3. 实现computer类

    namespace _1.InterfaceTest

    {

      /// <summary>
        /// 电脑与打印机连接,不论是何种打印机,电脑都将调用这两个方法
        /// </summary>
        public class Computer
        {
            /// <summary>
            /// 定义接口类型的变量
            /// </summary>
            private IPrinter _print;
            public IPrinter Print
            {
                get
                {
                    return this._print;
                }
                set
                {
                    this._print = value;
                }
            }
            public Computer()
            {
            }
            public Computer(IPrinter print)
            {
                this.Print = print;
            }
            public void ReceiveData()
            {
                this._print.Receive();
            }
            public void PrintData()
            {
                this._print.Print();
            }
        }
     }
    }
    4.测试一下打印机是否能正常工作:
    namespace _1.InterfaceTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                Computer computer = new Computer();
                IPrinter printerA = new PrinterA();
                IPrinter printerB = new PrinterB();
                Console.WriteLine("I connected  PrinterA into computer and print something");
                computer.Print = printerA;
                computer.ReceiveData();
                computer.PrintData();
                Console.WriteLine("-------------------------------------------------------------“);
                Console.WriteLine("Now,PrinterA has some problem!I connected  PrinterB into computer and print something");
                computer.Print = printerB;
                computer.ReceiveData();
                computer.PrintData();
         
            }
        }
    }
    输出结果:
    测试成功!
    此时又有另外一个问题,公司又重新购置了一台不同类型的打印机,那又该如何实现呢?过程简单。代码如下:
    namespace _1.InterfaceTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                Computer computer = new Computer();
                IPrinter newPrinter = new NewPrinter();
                Console.WriteLine("I connected  newPrinter into computer and print something");
                computer.Print = newPrinter;
                computer.ReceiveData();
                computer.PrintData();
                Console.ReadLine();
         
            }
        }
    }
    运行截图:
    哈哈,是不是很神奇,Computer一点都不用改动,就可以使新的设备正常运行。这就是所谓“对扩展开放,对修改关闭”。 
  • 相关阅读:
    fiddler的详细分析
    在Linux中mysql的一些基本操作
    MySQL运行状态show status详解
    第1节-软件测试基本概念及分类
    HTML
    python 目录
    Web框架 Bottle 、Flask 、Tornado
    Query
    JavaScript基础篇
    DOM、BOM 操作
  • 原文地址:https://www.cnblogs.com/penglei-it/p/5220109.html
Copyright © 2020-2023  润新知