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#中接口的实现(隐式,显示,多接口)

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

    public class Program{static void Main(string[] args){var fan = new DeskFan(new PowerSupply());Console.WriteLine(fan.Work());}}public class PowerSupply{public int GetPower(){return 100;}}public class DeskFan{private PowerSupply PowerSupply;public DeskFan(PowerSupply powerSupply){this.PowerSupply = powerSupply;}public string Work(){int power = PowerSupply.GetPower();if (power <= 0){return "won't work";}else if (power < 100)return "Slow";else if (power < 200)return "Work fine";elsereturn "Waring";}}

当前代码如果我们要测试的话会直接修改PowerSupply里面的方法内的数值,在当前是不能这样干的,可能有别的代码引用这个PowerSupply这个类,所以我们需要引入接口来解耦。

  public interface IPowerSulpply{int GetPower();}private IPowerSulpply PowerSupply;public DeskFan(IPowerSulpply powerSupply){this.PowerSupply = powerSupply;}

现在可以进行单元测试了。具体步骤如下:

点击VS顶级菜单Test->Window->Test Explore

右击解决方案,添加项目,添加对应的单元测试项目。

命名为要测试的项目名加“.Test”即可。

接着引用被测试项目。

编写代码方法等

  [Fact]public void PowerSupplyThanZeroTest(){var oldvalue = "won't work";var power_ = new DeskFan(new PowerSupplyThanZero());var newvalue = power_.Work();Assert.Equal(oldvalue, newvalue);}public class PowerSupplyThanZero : IPowerSulpply{public int GetPower(){return 0;}}

打开测试管理器界面,点击对应的方法运行,全部变绿证明测试通过了。

上面调用是构造类的实例然后更改调用的方法的值,使用Moq可以极大减轻我们的工作量。

  var oldvalue = "won't work";//var power_ = new DeskFan(new PowerSupplyThanZero());var mock = new Mock<IPowerSulpply>();mock.Setup(a => a.GetPower()).Returns(() => 0);var power = new DeskFan(mock.Object);var newvalue = power.Work();Assert.Equal(oldvalue, newvalue);

 

转载于:https://www.cnblogs.com/jingjingweixiao/p/11080404.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/247710.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot操作MongoDB实现增删改查

本篇博客主讲如何使用SpringBoot操作MongoDB。 SpringBoot操作MongoDB实现增删改查 &#xff08;1&#xff09;pom.xml引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifac…

java面向对象的特征三:多态性 —(15)

1.多态性的理解&#xff1a;可以理解为一个事物的多种形态。 2.何为多态性&#xff1a; 对象的多态性&#xff1a;父类的引用指向子类的对象&#xff08;或子类的对象赋给父类的引用&#xff09; 举例&#xff1a; Person p new Man(); Object obj new Date(); 3.多态性的…

vue 中$index $key 已移除

之前可以这样: 123456<ulid"example"><liv-for"item in items">{{$index}}{{$key}}</li></ul>现在已经移除,如果还用的话就会报错:Uncaught ReferenceError: $index is not defined; 现在这样写: 123456<ul id"example&qu…

vue-resource全攻略

Vue.js——vue-resource全攻略 概述 上一篇我们介绍了如何将$.ajax和Vue.js结合在一起使用&#xff0c;并实现了一个简单的跨域CURD示例。Vue.js是数据驱动的&#xff0c;这使得我们并不需要直接操作DOM&#xff0c;如果我们不需要使用jQuery的DOM选择器&#xff0c;就没有必要…

java面向对象:关键字 —(16)

static:静态的 1.可以用来修饰的结构&#xff1a;主要用来修饰类的内部结构 属性、方法、代码块、内部类 2.static修饰属性&#xff1a;静态变量&#xff08;或类变量&#xff09; 2.1 属性&#xff0c;是否使用static修饰&#xff0c;又分为&#xff1a;静态属性 vs 非静态…

《少年先疯队》第九次团队作业:Beta冲刺与团队项目验收

博文简要信息表&#xff1a; 项目内容软件工程https://www.cnblogs.com/nwnu-daizh/本次实验链接地址https://www.cnblogs.com/nwnu-daizh/p/11056511.html团队名称少年先疯队作业学习目标&#xff08;1&#xff09;掌握软件黑盒测试技术&#xff1b;&#xff08;2&#xff09;…

vue-resource jsonp跨域问题解决方法

最近在学习vue.js 碰到个ajax跨域请求的问题&#xff0c;之前知道可以用jsonp解决&#xff0c;但是一直没实践过&#xff0c;这次用发现里面好多问题&#xff0c;所以现在记录下来&#xff0c;希望可以给刚接触使用jsonp的同学一点帮助&#xff01; 关于什么是jsonp&#xff0c…

虚拟机无法连接至网络

问题&#xff1a; 虚拟机中的win XP系统无法连接至外部win10系统网络 尝试解决方法&#xff1a; 1&#xff09;换用桥接模式和NAT模式&#xff0c;无效 2&#xff09;恢复虚拟机网络属性至默认状态&#xff0c;无效 最终解决方法&#xff1a; 换用外部无线网络&#xff0c;即能…

java面向对象:关键字 —(17)

interface:接口 1.使用说明&#xff1a; 1.接口使用interface来定义 2.Java中&#xff0c;接口和类是并列的两个结构3.如何定义接口&#xff1a;定义接口中的成员 3.1 JDK7及以前&#xff1a;只能定义全局常量和抽象方法>全局常量&#xff1a;public static final的.但是…

原生js来实现对dom元素class的操作方法

jQuery操作class的方式非常强大 写了一个利用原生js来实现对dom元素class的操作方法 1.addClass:为指定的dom元素添加样式 2.removeClass:删除指定dom元素的样式 3.toggleClass:如果存在(不存在)&#xff0c;就删除(添加)一个样式 4.hasClass:判断样式是否存在 下面为一toggleC…

python+selenium配置Edge浏览器

Chrome, Firefox只需要修改conftest.py文件中的 pytest.fixture(scopesession)def browser(): return BzwUtil.read_yml(config.yml,WEB_INFO,BROWSER) add option in pytest command line def pytest_addoption(parser): parser.addoption("--browser", actio…

JSON.parse和JSON.stringify方法

JSON.parse() JSON.parse()方法将json字符串转化为Javascript值或对象。 语法 JSON.parse(text[,reviver]) 参数 text:要被解析成Javascript值的字符串 reviver:若是一个函数则规定了原始值(text)如何被解析改造&#xff0c;在被返回前。 示例 JSON.parse({}); //…

java面向对象:异常处理 —(18)

1. 异常的体系结构 java.lang.Throwable |-----java.lang.Error:一般不编写针对性的代码进行处理。|-----java.lang.Exception:可以进行异常的处理|------编译时异常(checked)|-----IOException|-----FileNotFoundException|-----ClassNotFoundException|------运行时异常(un…

vue请求简单配置

简单记录一下vue的http请求配置相关 测试环境请求接口设置:   1. config/dev.env.js添加&#xff1a;     module.exports merge(prodEnv, {       NODE_ENV: "development",       API_ROOT: "http://", //配置http请求头     })…

【vue报错】——listen EADDRINUSE :::8080 解决方案

问题原因&#xff1a; 此项错误表示 8080 端口被占用 解决方案一&#xff1a; 打开cmd 输入&#xff1a;netstat -ano 查看所有端口信息&#xff0c;如图&#xff0c;找到端口 8081&#xff0c;以及对应的 PID 输入&#xff1a;tskill PID 即可杀死进程 解决方案二&#xff1a…

记录_20190626

java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result异常的解决方法 原来JAVA中如果用BigDecimal做除法的时候一定要在divide方法中传递第二个参数&#xff0c;定义精确到小数点后几位&#xff0c;否则在不整除的情况下…

String与Array

public class Api {Testpublic void StringApi(){// equals() 判断内容是否相同区分大小写// equalsIgnoreCase() 判断内容是否相同不区分大小写// length() 获取长度// charAt(int index) 获取某个索引位置的字…

HTML与CSS布局技巧总结

很多人对CSS的布局有困惑&#xff0c;实际的应用场景中由于布局种类多难以选择。今天我花些时间总结下自己对CSS布局的理解&#xff0c;分析下了解各种布局的优劣&#xff0c;同时希望能分享给初入前端的朋友们一些在布局上的经验&#xff0c;如果有那些地方总结的不好&#xf…

当谈论迭代器时,我谈些什么?

花下猫语&#xff1a;之前说过&#xff0c;我对于编程语言跟其它学科的融合非常感兴趣&#xff0c;但我还说漏了一点&#xff0c;就是我对于 Python 跟其它编程语言的对比学习&#xff0c;也很感兴趣。所以&#xff0c;我一直希望能聚集一些有其它语言基础的同学&#xff0c;一…

在Vue-cli项目中使用echarts

该示例使用 vue-cli 脚手架搭建 安装echarts依赖 npm install echarts -S11 或者使用国内的淘宝镜像&#xff1a; 安装 npm install -g cnpm --registryhttps://registry.npm.taobao.org11 使用 cnpm install echarts -S11 创建图表 全局引入 main.js // 引入echarts im…