阅读后感

软件工程期中作业(阅读和提问)

本来打算每篇文献写一份读后感来着,读了”There is a Silver Bullet”,借鉴其中把模块的复用作为银弹的做法,决定把经历总结和读后感穿插成一篇去写。

part1 主要关于经验总结

在写这一篇之前,我已经经历了一次alpha阶段的开发(对联项目),beta阶段换了一个组(Julia-AI),此时,beta阶段也已经经历了一半。
在alpha阶段的开发中,主要做的是前端的一个demo界面,这里一方面是对前端的工作不熟悉,另一方面是在开发开始的时候就定下来这次的开发是以一个demo界面为主,不太需要考虑之后的发展(也就是笃定了之后要重构的)这样的念头,所以基本也没有做到对原型进行很好的设计

  • Simplicity-the design must be simple, both in implementation and interface. It is more important for the implementation to be simple than the interface. Simplicity is the most important consideration in a design.
  • Correctness-the design must be correct in all observable aspects. It is slightly better to be simple than correct.
  • Consistency-the design must not be overly inconsistent. Consistency can be sacrificed for simplicity in some cases, but it is better to drop those parts of the design that deal with less common circumstances than to introduce either implementational complexity or inconsistency.
  • Completeness-the design must cover as many important situations as is practical. All reasonably expected cases should be covered. Completeness can be sacrificed in favor of any other quality. In fact, completeness must sacrificed whenever implementation simplicity is jeopardized. Consistency can be sacrificed to achieve completeness if simplicity is retained; especially worthless is consistency of interface.
  • cited from"Worse is Better"

关于worse is better里面这样的设计理念,我是觉得很好的。一方面来说,尽量好的设计可以满足大部分常见情况下的需求,也就是说几乎可以满足市场,另一方面,这种做法可以合理的划分主次,把主要精力放在攻克主要的领域上,同时又足够的简单,可以说是在“多快省”这三个方面权衡下的最好设计方式了。但是这种方法会对编程人员的项目经验和架构能力与洞察力有比较高的要求。在这次10天的alpha冲刺,这个原型的设计确实是被我忽视了的,只做到了足够的简单,完成了一个算是完成各项功能模块的demo,但是正确性和持续性几乎是完全忽视了的。这也造成了最后的前后端逻辑是一个大泥球。

Therefore, focus first on features and functionality, then focus on architecture and performance
("Big Ball of Mud")

这篇文献相当于是给出了一个系统变成一个大泥球(一个杂乱无章的系统)和如何进行解决的方法。

反思,在冲刺的过程中做了什么事情让这个系统变成了泥球了呢?首先像上面引用的那样,只关注系统的功能,而对架构缺乏设计,这个可以说是最根本的原因了。其次的一些原因,

Therefore, produce, by any means available, simple, expedient, disposable code that adequately addresses just the problem at-hand. “Big Ball of Mud”

开发的时候确实抱着最后再进行整理的心态,但是到了后期整合各个部分的时候,发现由于缺乏前期的整体设计,最后将各个模块整理到一块(比如接口调整等)就花费掉了最后的冲刺时间。这就是在时间规划上出现的问题。做增量式改进的时候,也就是每次对需求作出改进的时候,过于急于看到效果,做的是最不经大脑的修改,没有考虑到各个模块之间的解耦和对可扩展性的支持。到了后期增加新的功能往往需要改动的函数就会变得很多。不过beta阶段整体架构和代码都在进行重构,也是符合“Big Ball of Mud”中的重新让项目有条理的做法的。

在冲刺的过程中,为了提升开发的效率,很多模块功能的实现并不是依靠自己去认真的翻库,而是通过寻找功能类似的代码去进行复用,也就是寄希望于银弹来提升开发的效率。确实,这样效率是提高了不少,但是,像这篇“有人负责,才有质量:写给在集市中迷失的一代”中阐述的那个样子,现在的开源部分的代码更多的像是一个大集市,很多代码的质量是没有办法保证的,特别是网上那些发布了代码但是作者仿佛忘记了自己的账号密码的博客中对应的代码,经常可以见到有人在下面评论在运行过程中遇到了什么问题但是并没有能够解决,但是往往过了一两年这样一条还是了无音信(当然,也和提问的人询问的方式有关)。然后这些代码彼此依赖,从一方面来说,给项目的代码中增加了许许多多没有必要的冗余代码,从另一方面,这些代码(尤其是作者失踪的)更多的是只是应付在某一种特定情况下的功能,并不会有任何的设计构造或者是异常处理可言,盲目的复用代码之后使得自己的代码更加像一个泥球。综上而言,在实现demo原型的阶段,复用是一个很好的提高效率的方式,但是做一个成熟的项目的时候,代码复用要考虑的事情应当会有很多。包括对于使用的库函数也应当有合理的挑选,比如之前的圣诞节图标狗啃事件。如果全部考虑(比如使用限制,应用大小,可扩展性等等),感觉代码复用并不能够非常显著的提高效率?
在利用已经成熟的模块时候,我遇到的两个问题:

  1. 虽然仅仅需要其中的一小部分功能,但是为了使用这个模块有的时候不得不将模块整体包含在项目文件内,导致项目整体体积偏大,运行效率可能比较慢,然而查不清楚具体原因
  2. 借助Web App实现部署的时候,需要将项目代码打包成规定的格式,所以导致部署的代码和github上的代码结构不同,同时由于运行环境不同等进行路径问题等的修改也花费了大量时间,对于Web App模块本身的运行逻辑不了解也增加了调试的困难,虽然部署方便了很多。

此外,

And for us who are concerned with the success of object-oriented programming, this is chilling—the future will be in the hands of the worst of our fruits. "Is worse really better"

简单的,考虑的情况比较少但是又相对足够全面的代码相对于设计实现复杂,为了一个很少用到的功能而大费周章去设计的代码来说应当是更容易被阅读和理解的,也就是更容易被入门的人去接受阅读的,也就是受众是更广的。(这里没有什么依据,只是看到之前资料收集的时候,看到大家对一个功能的实现,互相转载的博客中更多的是实现方法比较简单的做法而做出了的一个假设。)那么相对而言,加上软件工程的教育和练习在初学者中普及不充分这样一个情况,更多的项目容易陷入一个泥团的局面。

part2 如何学习软件工程

一点牢骚

这个方面,我想更多的聚焦于学校里的软件工程课。因为各种原因,我是自己上过一节软件工程课,同时通过听同学吐槽的方式旁观了第二学期的软件工程课。这门课里我听到最多的吐槽是哪几个呢?回想起来,是

  1. 这个作业ddl的时候马上就要考试了,哪有时间来应付这个
  2. 突然要求干XXX,这个东西根本没有接触过啊
  3. 团队里XXX是个大腿,只要他干活就行了
  4. 课程上得非常无聊,老师也不介绍编程技巧。。。
    为什么计算机系的老师教不好软件工程水平的编程这样一篇文章里,作者吐槽了软件工程这门课没啥锻炼的东西,老师教学仿佛是一种应付差事。这篇文章里,有这么一句话

就我们系来说,在学习软件工程这么课之前,好像一直都处于理论学习的阶段,平时的作业都只是一些简单的练习。甚至有些课程,现在都还不知道自己该在什么地方去应用它们,感觉真是白学了。

在某些程度上,这句话似乎可以解释一下大家会觉得软件工程这门课无聊的原因。因为课程上很多东西是从理论的角度出发的或者是方法论一样的东西,而这两个东西,理论的东西需要大量实践的验证,方法论的共鸣也是需要很多实践,经验一样的东西才可以有同感。在缺乏共鸣的时候就像是给原始人讲流水线生产是多么高效一样。在这篇博客中,团队成员对于如何学好programming摘出了几个意见:

  1. 请企业中的开发者参与programming的教学
  2. 学生自己应该有自我发现的能力,you develop software on your own,teacher give you time to develop your skills semi—autonomously
  3. programming更需要在实际的工作经验中学习

这三个方面的建议都是很有道理的,但是如果按照重要性排序的话可能我会选择2,3,1这样的顺序。经验丰富的开发者开设的programming课程,如果针对的还是第一篇博客中提到了“感觉自己白学了“这样的同学,可能纯理论的东西又会被抱怨无聊,做偏工程的项目又会被抱怨课程难度大。这是一个两难的局面。从自身出发来说,软件工程的困境一方面是来自于可能部分老师脱离工业环境,导致某些方面让人感觉说服力不强,另一方面(更大的方面)是来自于学生本身的矛盾性。这个矛盾性主要是体现在所有的课程要求的结题项目更多的是demo性质的而非一个真正的有要求的软件工程,而被突然施加了很多要求的软件工程无疑是走出舒适区;另一方面就是传统的浮躁,想要短期内提高软件能力而又缺乏足够的自觉动手能力。

软件工程教学最好的方式应该还是做中学,兼顾基础好和不好的两种情况(关于ddl重叠这种情况,按照道理来说并不应当成为一个顾虑,但是这个顾虑往往是真实存在的,尤其是在看重绩点的地方),以下的思考是建立在不存在ddl重叠并且大家真实想学不依赖大腿的情况下。

软件工程和计算机科学的gap在哪里?

CS != SE,这应该是一个公认的道理,相对而言,计算机科学更偏向于理论,而软件工程更偏向于更称,软件工程的东西相对而言更和人相关,没有一些很严谨的研究方式。在阅读这篇博客的过程中,作者对计算机科学和软件工程的区别有着更明确的定义,计算机科学严谨,并且各种理论相对比较固定,算法有着严格的分析,而软件工程中的各种不确定性大大增加,而且缺乏明确的定义。理论更新换代速度很快,需要人不断的根据实践去调整理论分析的方法,软件工程是一种将计算机科学的相关成果转换成为人类可以使用的软件的一种粘合剂,也就是说,软件工程是直接和人所打交道的。是一种和人类相关的,包括创意人文等多学科的综合系统,而非传统的软件工程。这篇文章解释了一个长久以来的疑惑,为什么大学里很多学习的材料都是一些比较老旧的东西,比如知乎经常吐槽的一个问题,为什么大学的C语言教学还在使用VC6.0这样一个过时的编译器。因为大学更多的偏向于一些理论知识的教学,大学内的教学包括实验部分,更多的是注重于促进对计算机科学的理解,比如可计算性,编译原理,计算算法的复杂度等等,所以,从工业的角度来看,大学里面的很多东西是非常过时落后的,而且学生受到的训练是可以忽略不计的,也就是“动手能力极差“。这些东西都是不涉及人的,甚至可能不涉及团队合作的有关内容(不过很多时候大学的团队合作更多的也都是一人带飞一对人),也就是和人打交道的部分形同虚设。哪怕是大作业,也就是开发一个软件项目,更多的也都是小打小闹性质,没有达到一定的规模,不需要软件工程相关的理论指导,不需要考虑软件的架构等等。那么,如何去准备软件工程的有关内容呢?计算机科学的内容,教学安排都是显然地显示在教学大纲上的,比如密码学图论等等。如果想成为一个软件开发者应该去培养学习啥技能嘞?

软件工程应该教什么?

"What Should We Teach New Software Developers? Why?"阐述了软件工程和正常教学之间存在的问题,分析了学术和工业之间存在的gap,指出学术界更关心一些计算机科学的核心理论知识点,工业界则更希望一些有经验的开发者,理论和实践之间如何取得一种平衡是教学过程中需要关注的重点。关于教学的方案,针对教授的四年本科时间仅仅只够教完计算机科学的理论知识点,目标是软件工程师的人应该需要一个master学位而有志于计算机科学研究的人则应该去学习一个PHD。但是计算机科学的最终目标是进行得到一个更好的系统,所以编程的技能是无论从事学术研究还是工业开发都不可或缺的。关于如何培养一个软件工程师,我觉得这篇参考文章的阐述更加的详细一些,也更有一些共鸣。也就是,用工作室的方式来进行学习,换成现在常见的做法,也就是实习这样一种方式来参与实践。在这篇文章里,作者指出软件工程是一种可以通过实践加反思来自我感悟自我提高的学科。通过工作室的方式参与实践,学习软件开发过程中架构设计,与团队成员沟通等多方面的技能,在经验丰富的工程师引导下对自己的软件开发流程进行反思,通过接触新的项目,考虑很多实际的问题,同时锤炼与人合作的技能等,在这样一个边学边反思的过程中,可以让人一步步的脱离舒适区,通过一种百炼自得地方式获取软件工程所需要地各项技能。软件工程应当是与建筑等学科无异的一样的实践方式。从个人地角度来说,在学校中所做地项目一方面更像是展示自己所学地demo,也就是所谓地三无产品,无用户,无反馈,无维护。做完就丢掉,也不需要管运行速度之类地东西。然而在实习地过程中,通过scrum等方式去听成熟地软件工程师对一个实际项目地见解,考虑的方方面面的要素,在自己工作的过程中去询问学习的方式,会更快的去领会该如何去真正的开发一个软件。做中学的方式,而不是开发一个玩具去自娱自乐的方式,更容易让人在这样一个偏工程的学科中获得成长。

posted @ 2019-01-01 20:45  Annbless  阅读(337)  评论(4编辑  收藏  举报