近期的一个项目反思与总结

      近期手头接了一个智能硬件相关的项目,本来是想等自己更新完设计模式系列,然后好好总结一番的。但是正好碰到今天下大雨,正好碰到今天这个时候没有什么事情,然后正好碰到自己这个时候对于这个项目有一些吐槽的地方。

      这个项目的背景是这样的:因为之前已经有成型的android版本,并且已经迭代N多次。可是基于android目前没有找到比较合理的体感设备,于是公司就决定采用微软的kinect来实现人脸、动作、骨骼等相关很酷的功能。那么问题就来了,要使用微软的kinect就意味着必须将现有的android版本重新迁移一份到wpf/uwp。说实话这可不是小工作量,除了有一定的技术瓶颈,可能还会出现迁移过程中的功能性bug。于是,开始领导让我做这个项目的时候,自己心里也掂量过。大问题应该不会有,但是对于微软的那套东西,个人觉得还是非常的恶心。曾经在做上一个uwp项目的时候,自己暗下决心如果允许的话,以后自己肯定不会再碰.net平台。可是,有的时候在项目里面,还得服从组织安排。

      在刚刚迁移的时候,笔者先将android那套框架大概回顾了一下,然后按照自己的思路将那套框架画出了类图,最后对照android版本填充一些自己漏掉的东西。说实话,笔者觉得android那套框架设计的还是挺牛的。利用软件将整台硬件给模拟出来,在代码里面既考虑到了硬件的多样性,同时又考虑到了用户操作过程中可能的状态变化。那套框架很好的解释了“设计源于现实对象”的精髓,可能看到这里你会觉得笔者有点夸大,但是必须得承认牛人就是牛的道理。于是,抱着学习框架设计的目的,自己开始了框架迁移的工作。首先,针对不同的硬件机型定义出不同的软件层面的模型类。然后又根据每台不同的机型所具有的相同硬件层组件抽象出3-4种模型类,这样的话笔者就可以在工厂模式下,针对不同差异的机型组装出完整的机器。如果这块做好的话,那么后面就只需要往硬件模型类里面塞不同的变量、方法就可以了。接下来,还有一个大块就是用户操作的时候、机器启动的时候不同的状态变更,机器所要执行的动作肯定也是不一样的。其实如果对于这块没有什么概念的话,还真是没有什么设计思路,就像笔者刚刚看到android代码一样,也是一头雾水。后面笔者告诉自己:静下来,一定要静下来慢慢研究就可以了。于是,笔者花了很大一部分时间在这两块的迁移,想想如果这两块框架迁移好的话,那么整个迁移工作后面就可以省事很多。这个阶段,笔者想要重点吐槽的地方就是C#和Java语言的差异性。也许同时接触过这两种语言的朋友,肯定会认为C#和Java语言不是大同小异吗?基本就是一个模子刻出来的吗?

      C#和Java语言最直观的差异就是属性和方法命名的不同,其次就是一些API的差异。比如在Java里面,我们想要获取当前时间的毫秒值直接调用System.currentTimeMillis()就可以了,但是在C#里面呢?笔者是没有找到对应的API,这个时候开始就找一些替代方案了。结果吓一跳,原来C#和Java求当前时间的时候,竟然会相差8个小时。如果没有注意到这个细节的话,那么时间不管怎么求都不会相同。还有一个最大的差异就是我们当初选择迁移项目类型的时候,我们考虑到最大的适配性,所以我们选择了微软的UWP项目。要采用UWP就意味着应该要采用MVVM模式,采用MVVM模式就意味着最好采用依赖属性,采用绑定的方式。其实这个特性本来也是UWP的一个优势所在,但是微软的UWP的API相对于android的API,不管是完整性、全面性、稳定性、优雅性都远远不足。比如android里面的广播机制,比如android里面的消息机制,比如android里面多线程操作等。由于这些原因,导致笔者在迁移过程中,出现种种困难,而且最怕的就是莫名其妙的出现问题。

     好了,框架迁移完成之后。笔者接下来要做的事情就是先添加相应的View,想想如果没有View,后面的ViewModel层也就没有办法进行开发了。本来笔者设想的挺好的,尽量将View层的样式、属性拆解到资源文件里面。可是做到最后,才发现这其实是一件很难顾及到的事情,因为必须时时在意。好了,View的工作简单而迅速。在经过一周左右的时间,笔者终于将View层开发出来了。然后应该做什么呢?你可能会说应该是ViewModel层吧?错,试想没有数据,你从何而来的ViewModel层呢?所以接下来应该做的事情就是网络请求,还有数据解析那块。只有将这块处理好的话,Model层才能定义出来,同时ViewModel层也可以看到雏形。其实说到网络层,笔者在以前的项目里面所进行的操作也非常简单,就是封装了一个网络请求。但是这次从android网络层借鉴过来一套很好的轻量级设计思路,在这套设计里面,原作者很好的阐释了面向扩展开放、面向修改关闭的原则。具体细节笔者不方便透露,但是想法就是新增一个接口的时候,我们只需要新增一个参数封装方法,新增一个Response实体类,新增一个Parser解析类。

     当笔者将项目迁移到这里的时候,基本上项目就已经成型了。后面所要花时间做的工作就是:调试串口,保证硬件层的东西可以正常运行。在这个项目里面,笔者所报的心态其实非常不好,没有抱有一个程序员所应该具有的匠心去做。所以笔者很多时间都在为这件事情担心,拍就怕后面会有哪些小细节、大疏忽没考虑到。因为项目也算一个大项目,所以笔者后面将会话更多的时间去检查、优化、重构代码,尽量将细节控制好。

      好了,这篇博客的废话挺多的,希望自己在项目里面能够更加沉下来,怀着一颗匠心去做事情。

原文地址:https://www.cnblogs.com/xiaocai20091687/p/xiaocai_design_ten.html