【C#语言入门】22. 接口、依赖反转、单元测试

【C#语言入门】22. 接口、依赖反转、单元测试

一、接口与单元测试

  • 接口的产生:自底向上(重构),自顶向下(设计)
  • C#中接口的实现(隐式,显式,多接口)
  • 语言对面向对象设计的内建支持:依赖反转,接口隔离,开/闭原则......
csharp 复制代码
//不使用接口,会很麻烦
class Program
{
    static void Main(string[] args)
    {
        int[] nums1 = new int[] { 1, 2, 3, 4, 5 };
        ArrayList nums2 = new ArrayList() { 1, 2, 3, 4, 5};
        Console.WriteLine(Sum(num1));
        Console.WriteLine(Avg(num1));
        Console.WriteLine(Sum(num2));
        Console.WriteLine(Avg(num2));
    }

    static int Sum(int[] nums)
    {
        int sum = 0;
        foreach (int x in nums) {
        sum += x;}
        return sum;
    }

    static double Avg(int[] nums)
    {
        int sum = 0;
        double count = 0;
        foreach(int x in nums)
        {
            sum += x;
            count++;
        }
        return sum/count;
    }

    static int Sum(ArrayList nums)
    {
        int sum = 0;
        foreach(var x in nums)
        {
            sum += (int)x;
        }
        return sum;
    }

    static double Avg(ArrayList nums)
    {
        int sum = 0;
        double count = 0;
        foreach(var x in nums)
        {
            sum += (int)x;
            count++;
        }
        return sum/count;
    }
}
csharp 复制代码
//使用了IEnumerable接口
class Program
{
    static void Main(string[] args)
    {
        int[] nums1 = new int[] { 1, 2, 3, 4, 5 };
        ArrayList nums2 = new ArrayList() { 1, 2, 3, 4, 5};

        Console.WriteLine(Sum(nums1));
        Console.WriteLine(Avg(nums1));
        Console.WriteLine(Sum(nums2));
        Console.WriteLine(Avg(nums2));
    }

    static int Sum(IEnumerable nums)
    {
        int sum = 0;
        foreach (int x in nums) {
        sum += x;}
        return sum;
    }

    static double Avg(IEnumerable nums)
    {
        int sum = 0;
        double count = 0;
        foreach(int x in nums)
        {
            sum += x;
            count++;
        }
        return sum/count;
    }

}

二、依赖

在现实世界中,由于自身能力有限,合作是一个非常常见的行为,而面向对象是对现实世界的抽象,因此也存在着类与类、对象与对象的合作,即"依赖"。依赖的出现伴随着耦合,依赖越直接,耦合度越高。

csharp 复制代码
class Program
{
    static void Main(string[] args)
    {
        var user = new PhoneUser(new NokiaPhone());
        //var user = new PhoneUser(new EricssonPhone());超级无敌松耦合,只要改这里就能实现手机切换
        user.UsePhone();
    }

}

class PhoneUser
{
    private IPhone _phone;
    public PhoneUser(IPhone phone)
    {
        _phone = phone;
    }

    public void UsePhone()
    {
        _phone.Dail();
        _phone.PickUp();
        _phone.Send();
        _phone.Receive();
    }
}

interface IPhone
{
    void Dail();
    void PickUp();
    void Send();
    void Receive();
}

class NokiaPhone:IPhone
{
    public void Dail()
    {
        Console.WriteLine("Nokia calling...");
    }

    public void PickUp()
    {
        Console.WriteLine("Hello!This is Tom");
    }

    public void Receive()
    {
        Console.WriteLine("Nokia message ring...");
    }

    public void Send()
    {
        Console.WriteLine("Hello!");
    }
}

class EricssonPhone : IPhone
{
    public void Dail()
    {
        Console.WriteLine("Ericsson calling...");
    }

    public void PickUp()
    {
        Console.WriteLine("Hello!This is Tom");
    }

    public void Receive()
    {
        Console.WriteLine("Ericsson message ring...");
    }

    public void Send()
    {
        Console.WriteLine("Hello!");
    }
}

注意:在代码中如果有可以替换的地方,就一定有接口的存在,接口就是为了解耦/松耦合而生,他最大的好处就是可以让功能的提供方可以方便替换,减少紧耦合时提供方可能带来的风险。

  • 依赖反转原则
相关推荐
伐尘17 分钟前
【Qt】QTableWidget 自定义排序功能实现
开发语言·qt
Aevget29 分钟前
DevExpress WPF中文教程:Data Grid - 如何使用虚拟源?(一)
c#·wpf·界面控件·devexpress·ui开发
【杨(_> <_)】36 分钟前
SAR信号处理重要工具-傅里叶变换(二)
算法·信号处理·傅里叶分析·菲涅尔函数
怎么没有名字注册了啊41 分钟前
爬动的蠕虫
算法
取酒鱼食--【余九】42 分钟前
机器人学基础(一)【坐标系和位姿变换】
笔记·算法·机器人·开源·机器人运动学·机器人学基础
多多*1 小时前
上传文件相关业务,采用策略模式+模版方法模式进行动态解耦
java·开发语言
晨非辰1 小时前
【面试高频数据结构(四)】--《从单链到双链的进阶,读懂“双向奔赴”的算法之美与效率权衡》
java·数据结构·c++·人工智能·算法·机器学习·面试
im_AMBER1 小时前
数据结构 03 栈和队列
数据结构·学习·算法
凸头1 小时前
以AtomicInteger为例的Atomic 类的底层CAS细节理解
java·jvm·算法
赴前尘1 小时前
Go 通道非阻塞发送:优雅地处理“通道已满”的场景
开发语言·后端·golang