C#入门详解(14)

接口,依赖反转,单元测试

接口是协约是规定,所以必须是公开的,只能是public;

        static void Main(string[] args)
        {
            int[] num1 = new int[] { 1, 2, 3, 4, 5 };
            Console.WriteLine(Sum(num1).ToString());
            Console.WriteLine("==================");
            Console.WriteLine(Avg(num1).ToString());
        }

        static int Sum(int[] arr)
        {
            int result = 0;
            foreach (var item in arr)result += item;
            return result;
        }

        static double Avg(int[] arr)
        {
            int result = 0;
            double count = 0;
            foreach (var item in arr) { result += item; count++; };
            return (result/count);
        }
    }

在上述代码中,如果我们的参数不是int[]类型,而是ArrayList类型(存放的是object类型)

方案一进行方法的重载,在方法内部进行强制类型转换:

 static void Main(string[] args)
        {
            int[] num1 = new int[] { 1, 2, 3, 4, 5 };
            ArrayList array = new ArrayList { 1, 2, 3, 4, 5 };
            Console.WriteLine(Sum(array).ToString());
            Console.WriteLine("==================");
            Console.WriteLine(Avg(array).ToString());
        }

        static int Sum(ArrayList arr)
        {
            int result = 0;
            foreach (var item in arr)result += (int)item;
            return result;
        }

        static double Avg(ArrayList arr)
        {
            int result = 0;
            double count = 0;
            foreach (var item in arr) { result += (int)item; count++; };
            return (result/count);
        }

在上述问题中,我们要调用的求和和求平均数,就是甲方,提供的方法为乙方,仔细观察不难发现我们的甲方只要求其方法参数为可迭代的集合就行了,查看int[]和ArrayList的基类,它们都是可迭代的,实现了IEnumerable接口

  static void Main(string[] args)
        {
            int[] num1 = new int[] { 1, 2, 3, 4, 5 };
            ArrayList array = new ArrayList { 1, 2, 3, 4, 5 };
            Console.WriteLine(Sum(num1).ToString());
            Console.WriteLine("==================");
            Console.WriteLine(Avg(array).ToString());
        }

        static int Sum(IEnumerable arr)
        {
            int result = 0;
            foreach (var item in arr)result += (int)item;
            return result;
        }

        static double Avg(IEnumerable arr)
        {
            int result = 0;
            double count = 0;
            foreach (var item in arr) { result += (int)item; count++; };
            return (result/count);
        }

通过这样的实现解决问题,把具体参数变抽象,用契约管理供需关系。

下一个实例继续:

    public class Program
    {
        static void Main(string[] args)
        {
            Engine engine = new Engine();
            Car car = new Car(engine);
            car.Run(3);
            Console.WriteLine(car.Speed.ToString());
        }
    }

    public class Engine
    {
        public int RPM { get;private set; }

        public void Work(int gas)
        {
            this.RPM = 1000 * gas;
        }
    }

    public class Car
    {
        public Engine engine { get;private set; }

        public int Speed { get;private set; }

        public Car(Engine engine)
        {
            this.engine = engine;
        }

        public void Run(int gas)
        {
            this.engine.Work(gas);
            this.Speed = this.engine.RPM / 100;
        }
    }

上面这段代码当Engine中的Work出现问题时,会导致Car调用出现问题,这是因为Car已经和Engine类紧耦合了

追求低耦合的原因:降低对提供方的需求,只需满足协约就满足要求,可替换。

接口与单元测试

接口的产生:自底而上(重构),自顶向下(设计)

C#中接口的实现(隐式,显示,多接口)

语言对面向对象设计的内建支持:依赖反转,接口隔离,开/闭原则

猜你喜欢

转载自www.cnblogs.com/jingjingweixiao/p/11080404.html