实训日志(二)

实训即将走到终点,至此后端API服务器基本版的编码工作基本完工了,在这里总结一下。

作为项目组组长,我有关于软件项目管理的唯一知识来自于寒假里读过一遍的《人月神话》。经此一番实践,发现自己还是太嫩。但是仍然,我认为自己还是学到了一点东西。

设计

相比起两年前写C语言作业时候二话不说开VS写作业,今天的自己显然有了一些改变。

首先VS我已经很久没打开过了。

总之这两年我经历了在天真纯粹的学习python的那段时间的练习,还是机器人队编写机器人上位机时候的历练,又或者是编写教务处网站师生端爬虫的经历、参与橙汁项目时候写的文件管理工具这几个集中编写代码的历程。最开始当然还是莽上,但我估计前后矛盾的苦头吃多了就知道要提前设计了。入了设计的门,接下来就是程度的问题了——因此这次把控整个项目的经历算是一次非常有益的练习。

首先明确要做什么,这个问题对于一个有心想做产品的团队来说至关重要:定义自己的产品,是战略层面的;但是遗憾这次没有什么有趣的想法,而责任在肩,认真做一个靠谱的、简单的项目是自己对这次实训的期待。

简而言之就是一个以微信小程序为主打特性的传统Web应用——具体要做的是一个目标管理系统。

这个东西做的人实在是太多了,因此对所要面临的事务的建模能够找到很多成熟的方案:诸如面向项目的Worktile;面向个人生活管理的WonderList;面向学生的My Study Life;甚至还包括Apple的提醒事项以及其他一些我听过但没有用过的工具。综合这些工具的特点,总结出一个经典的、微信特色目标管理系统——这就成了我们要做的Seed

应该具备的特性

那么Seed应该能做一些什么呢?

  • 拥有一个简单的用户系统,方便同步,同时提高用户粘性。
  • 用户可以自由创建并管理目标,这个目标与worktile的项目类似。
  • 用户可以被邀请进入别人的目标。
  • 目标分为日常打卡类(循环)和项目攻坚类(一次性,可以引入里程碑)。
  • 主打的前端是微信小程序。
  • 也兼容其它的潜在的客户端。

由此看来,Seed应该是一个小而精简的实用性服务,这点和微信小程序的初衷不谋而合。

在这里必须要强调“小而精简”这个特点。为什么要小而简单呢?一是人手不够时间有限。二要避免来自《人月神话》中提到的第二次项目容易犯的错误:盲目自大,疯狂地给一个项目添加无穷无尽的冗余。这是一种出力不讨好的蠢事,尤其——我们不涉及广告收入。举个简单的例子:Mac OS版迅雷和Win 版迅雷,显然大家都会喜欢精简使用的Mac版。

同时也要对微信小程序有良好的兼容性,为了提供良好的用户使用的平滑性,应该在支持email作为用户登录名的同时支持微信openId作为登录凭证。

系统的结构

上文提到我们要做一个以微信小程序为主打特性的Web应用,这就是说Seed具有兼容其它前端的能力与野心。因此RESTful风格的API就成为了最佳选择:前后端完全解耦,结构清晰,消费方便。

因此Seed应该是一个由微信小程序和其他一些潜在的形式作为前端,通过HTTP协议消费后端提供的资源

后端通过API来提供安全可靠的服务。

为此也学习了一些,接触到HATEOAS(Hypermedia As The Engine Of Application State)(超媒体即应用状态引擎)的思想,虽然不成熟,但却是一种可能的未来。

实现

由于只参与了API服务器的编码工作中,因此这里只谈后端的实现。

我喜欢把设计划分到为战略层面(道),剩下的工作划分到战术层面(术)因此,选用什么技术、如何具体去实现一个系统可以算在这里。

技术

出于实训的要求,也出于对Java语言的合理使用的渴望,选用Spring Framework作为后端框架,顺带使用了Spring全家桶:

  • Spring Boot作为应用容器
  • Spring Framework实现业务逻辑
  • Spring Data作为DAO
  • Spring Session管理Session
  • Spring test测试

此外使用Git、TravisCi、Heroku等工具提升开发体验。

开发过程

之前也提到Spring的Controller编写体验与Python Flask Web框架体验十分类似,也许Flask从Spring中得到了一些灵感?面向资源的控制器类我认为比起针对每一项资源都要写一个Servlet的传统Java Web显得要紧凑很多。

Spring提倡测试驱动开发,真要这么做起来到不是一件容易的事情,毕竟测试不是一向讨喜的工作。真要分配一个专人去编写测试代码,一学习成本很高,其次还有一些人情方面的问题。所以在开发中我决定让让每个人负责测试自己编写的代码。最终由我去审阅代码。

总结

有关Seed本身的值得一讲部分已经讲完了,接下来谈谈别的。

对自己的总结

在实训中学到了很多,但仍有问题。

作为项目经理我算是菜得抠脚。对进度的把控、人员的分配以及其他一些细节的把握都有大把不足之处。

举例来讲:

  • 对前端技术知识的匮乏使得本次项目最终很可能只有API服务器可以工作。
  • 项目小组中只有半数人真正参与了进来。
  • 对参与工作的人的培训显得空洞且缺乏耐心。

显然我还是需要进一步锻炼的。但同时作为项目经理和开发人员引出了我对另一问题的思考。

关于SEer两种能力的讨论

对整个系统的架构与把控能力实现单一功能的算法选择、裁剪、使用能力

我校的软件学院的课堂教育似乎只专注于后者,这也不算是一件怪事,毕竟对算法的掌握很容易度量,可以说是能力优劣差异显著,就好比解数学题,严格的前提条件与限制下人们的创造力十分便于评测。但合理制定这个所谓的“严格前提条件与限制”的能力虽然重要,却难以衡量。

至于为什么说自我矛盾,举个简单易懂但可能不十分恰当的例子,大家都知道家长以怕耽误学习为由严禁孩子早恋,却又希望孩子在毕业后立马能构成家这样的想法是幼稚而不切实际的。而隐含地期待学生在仅仅拥有良好学习成绩的情况下毕业后成为一个全才也是一种略微扭曲的想法,这两种情况的区别在于后者的矛盾不如前者那般尖锐。

我认为这样的实训的确是针对课堂教育的不足而作出的补偿,是有机会避免作为培养手段的成绩与作为培养目标的能力这两种符号所代表的事物之间的矛盾的。