软件工程第一次
Task1:注册个人博客账号
Task2:注册码云账号
-
参考教程:
- 娄老师:使用开源中国(码云)托管代码;使用码云和博客园学习简易教程(太复杂真心看不懂)
Task3:提出问题
问题一
我看了这一段文字,第一章13页
托尼本人反省,他在20世纪60年代设计Algol W语言的时候引入了Null Reference,对后来的编程语言影响很大,他自己估计给工业界造成的损失应该在10亿美元以上。
有一个问题:为何他只是引入了一种语言就会影响到工业界10亿美元的损失,难道是语言很复杂很难理解,或者是语言和机械语言之间并不能很好的同时运作?况且也只是引入一种语言,也可以用其他的语言编写代码,这个代码不好用就不用,干嘛还损失了这么多钱。我查了资料,有这些说法
我的目的是确保所有引用的使用都是绝对安全的,编译器会自动进行检查。但是我未能抵御住诱惑,加入了Null引用,仅仅是因为实现起来非常容易。它导致了数不清的错误、漏洞和系统崩溃,可能在之后 40 年中造成了十亿美元的损失。近年来,大家开始使用各种程序分析程序,比如微软的 PREfix 和 PREfast 来检查引用,如果存在为非 Null 的风险时就提出警告。更新的程序设计语言比如 Spec# 已经引入了非 Null 引用的声明。这正是我在1965年拒绝的解决方案
根据我的百度,我明白了null是恐怖的,要尽量避免null,解决方式是用Maybes/Options,但是我还是不太懂,Null在很多时候很容易出漏洞,为何老师教我们的时候都是用一个漏洞百出的方法解决,而且null字符串和空字符串完全不一样,老师也是混为一谈的解释。null的问题这么多,为何我们不用一种不用null的编程语言?
问题2
我看了这段文字:第二章,第24页,一个单月测试的代码清单2-5后的报错
定睛一看,原来复制/粘贴用了原来的Argumentnullexception,而不是argument-exception
有一个问题:这两个异常类型的区别是什么,为何会报错。我查了一下资料,发现百度居然没有这两个异常的区别,很困惑。
问题3
我看了这段文字:第二章,第31页
代码注入就是将检测的代码加入到每一个函数中,这样程序的一举一动都被记录在案,程序的各个效能数据都可以被精准地测量。这一方法的缺点是程序的运行时间会大大加长,还会产生很大的数据文件,数据分析的时间也相应增加。同时,注入的代码也影响了程序真实的运行情况(这有点像量子物理学中的“测试的光线干扰了测试物体本身”的现象)。
有一个问题:测试影响到了程序的真实运行情况我能理解意思,但是我就不懂为什么注入的代码会影响到真实的运行情况,难道注入代码他就不安原来的路线运行代码了么,他会跳来跳去的运行么,不听指挥?我查了代码注入,却只看到依赖注入和sql注入,这两种还都不一样,依赖注入倒是找到了缺点
依赖注入是指在创建一个对象时,自动地创建它依赖的对象,并注入。
大家都知道有三种途径来实现依赖注入,我这里总结一下这三种方式的优缺点:1.构造方法注入:
优点:
- 在构造方法中体现出对其他类的依赖,一眼就能看出这个类需要其他那些类才能工作。
- 脱离了IOC框架,这个类仍然可以工作,POJO的概念。
- 一旦对象初始化成功了,这个对象的状态肯定是正确的。
缺点:
- 构造函数会有很多参数(Bad smell)。
- 有些类是需要默认构造函数的,比如MVC框架的Controller类,一旦使用构造函数注入,就无法使用默认构造函数。
- 这个类里面的有些方法并不需要用到这些依赖(Bad smell)。
2.Set方法注入:
优点:
- 在对象的整个生命周期内,可以随时动态的改变依赖。
- 非常灵活。
缺点:
- 对象在创建后,被设置依赖对象之前这段时间状态是不对的。
- 不直观,无法清晰地表示哪些属性是必须的。
3.方法参数注入:
方法参数注入的意思是在创建对象后,通过自动调用某个方法来注入依赖。类似如下代码。
Java代码
- public class MovieRecommender {
- private MovieCatalog movieCatalog;
- private CustomerPreferenceDao customerPreferenceDao;
- @Autowired
- public void prepare(MovieCatalog movieCatalog,
- CustomerPreferenceDao customerPreferenceDao) {
- this.movieCatalog = movieCatalog;
- this.customerPreferenceDao = customerPreferenceDao;
- }
- // ...
- }
这种方式介于Set方法注入和构造方法注入之间。比如说我们通常会用一个Init方法来接受依赖的参数。
这种方法可能不太常用,一般是只有一个方法依赖到注入的对象时用到,如果有多个方法依赖到注入的对象,还是比较倾向于使用构造方法注入。
优点:
- 比较灵活。
缺点:
- 新加入依赖时会破坏原有的方法签名,如果这个方法已经被其他很多模块用到就很麻烦。
- 与构造方法注入一样,会有很多参数。
我个人很不倾向于在业务逻辑层中应用Autowired 或者是 Inject这样的annotation(Attribute)来实现注入,因为一旦脱离了IOC框架,代码就无法重用了。
我不明白的是,代码注入还有哪些分类,都各自有各自的缺点不适合运用么?
问题4
我看了这段文字:第二章,第38页
变化的轴线仅当变化实际发生时才具有真正的意义。如果没有征兆,那么去应用SRP,或者其他原则都是不明智的。
我的问题是,变化的轴线是什么意思?如果没有征兆,什么指代征兆,是什么的征兆,本来很实际的东西,被他这么一说,感觉是当上帝召唤我们的时候,才能去应用SRP。网上没有查询到这句话的解释。
问题5
我看了这段文字:第二章,第40页
如果软件已经在服务中(例如图书管理信息系统),如何升级部分模块,同时尽量减少系统下线的时间?
我的问题是:系统下线是什么意思?难道我设计的软件还会自动关闭么?查询了一下百度,只有《国家电网公司信息系统上下线管理方法》中规定系统上线试运行在具备下列条件()后,可以由系统建设开发单位负责向信息化管理部门申请系统上线试运行验收。的选择题。
Task4:Git基本操作练习
完成以下Git基本操作
1. 将https://gitee.com/happyfaye/SoftwareEngineering仓库fork到自己的账号下
2. 将远程仓库clone至本地仓库
3. 在本地仓库添加学号姓名.txt(例如:201621123000happy.txt),并提交至远程仓库