转载

华软项目总结

引言

上课,上实验,写文档,终于有时间写博客了。

我觉得这学期的 Android 实验上的还是很有意义的,课上,与我的舍友张一帆(自学 Android 及相关框架,有过 Android 比赛项目经验)一起讨论了 Android 的架构分层设计,以及对 RetrofitRxAndroid 框架的封装。

经过在实验中的学习,以及请教了一些在 Android 界算是有小有经验的人之后,发现自己年初对 Android 实验设计的有些问题:

华软项目总结

年初计划使用 Data-BindingFragmentation 实现单 Activity 架构,后来发现这样并不好。

  1. Data-Binding 学习成本太高,且对原项目结构破坏性较大,对新人学习并理解 Android 无益。
  2. Activity 架构虽然很优秀,但实际项目中仍然是多 Activity +多 Fragment 架构,去追求单 Activity 意义不大,手动管理 Fragment 会十分麻烦。

发现错误,就改吧。目前已经在实验中引入并应用了 ButterKnifeLitepalRetrofitRxAndroid 等框架,感觉技术上应该不会有太大变化。以后再一起和大家分享一下我在 Android 方面的学习收获。

同时,华软虚拟化管理系统 1.0 版本正式完成,本周花费整三天完成了项目发布及部署文档的撰写(感谢潘佳琦,为了尽快交付, MySQL 的安装与配置文档是他帮我写的,写得非常好)。

现在再回想华软项目,还是存在很多细节当时没有考虑到,在此进行反思与总结。

反思

笨拙的异常处理

后台设计得没什么问题:当发生错误时,后台会抛出异常,全局异常处理处理掉该异常,并将错误信息返回给前台。

笨拙在前台的拦截器这里:

华软项目总结

起初设计的是拦截器处理掉所有异常,并给予用户友好的提示,这样订阅时就不用处理 error 了。

当需要的时候,再去写 error 方法,比如登录时要在 error 里提示用户名或密码错误的提示信息。

拦截器处理异常,为了拦截器能准确地提示错误信息,所以扩展了 HTTP 状态码,对 512 等状态码扩展了新的含义。

switch (error.status) {
    case 401:
        if (this.router.url !== '/passport/login') {
            this.msg.error('用户认证发生错误');
            // noinspection JSIgnoredPromiseFromCall
            this.router.navigateByUrl('/passport/login');
        }
        break;
    case 403:
        this.msg.error('访问被拒绝, ' + error.error);
        break;
    case 404:
        this.msg.error('资源不存在, ' + error.error);
        break;
    case 502:
        this.msg.error('服务器网关错误,请联系系统管理员');
        break;
    case 504:
        this.msg.error('服务器网关请求超时,请联系系统管理员');
        break;
    case 512:
        this.msg.error('数据同步异常,' + error.error);
        break;
    case 513:
        this.msg.error('主机操作异常,' + error.error);
        break;
    case 514:
        this.msg.error('访问被拒绝异常,' + error.error);
        break;
}

当时写完这个拦截器的时候心里还是挺爽的,心想,以后可再也不用管理 error 了,多省事。现在再看看这个拦截器,说不上来什么原因,就是感觉怪怪的。

因为拦截器中是一个通用的提示信息,所以就出现了有时候需要在拦截器里加提示,有时候需要在 error 里提示,不想拦截器提示信息。

后来反思了一下,自定义状态码应该是合理的,也就是后台返回 512513 之类的,前台能直接通过状态码准确地判断当前后台到底哪错了。

但是这个拦截器这样写,就变成了,后台一个状态码对应一个提示信息,相当于我这个拦截器和后台抛出的异常绑定了,所以有时候虽然也是那个错,但是在这个界面提示出来就显得格格不入。

奇怪就奇怪在前台误解了自定义状态码的本质,自定义的状态码其实不是我后台有什么,前台就要拦截什么,新加一个状态码,就是为了前台可以更准确地提示信息,而不是一个 500服务器错误

华软项目总结

改正:以后拦截器只处理通用的状态码,如: 401 跳转到登录, 403 提示访问被拒绝。而一些涉及到具体业务的状态码,还是应该放到 onError 方法中处理。

不完善的 Loading

这是上次开会的时候晨澍提出来的,友好起见,当网络请求的时候应该显示 Loading 的动画。

想起来 NG-ALAIN 其实是为我们封装好了的,只是没有启用。

其实自己实现原理也简单,就是装饰器模式:

华软项目总结

对原生的 HttpClient 进行装饰一下,组合一个带 LoadingYunzhiHttpClient

以后 Service 请求就使用 YunzhiHttpClient ,发起时,将 Loading 置为 true ,数据回来的时候,将 Loading 置为 false

组件中如果想用怎么办呢?直接注 YunzhiHttpClient ,因为在同一个模块中是单例的,所以直接使用注入的 YunzhiHttpClientLoading 来控制加载动画是否显示。

改正:使用此方式添加 Loading 动画。

字段名与数据结构分离

@Entity
public class HostGroup {

    ...

    // 和电脑多对多
    @ManyToMany
    @JsonView({NoneJsonView.class,
            HostGroupJsonView.getAllGroups.class,
            HostGroupJsonView.getGroupById.class,
            UserJsonView.getCurrentLoginUser.class
    })
    private List<Host> hostList = new ArrayList<>();

    ...
    
}

HostGroup 中有字段是 hostList ,存储计算机列表。

具体的场景忘了,好像是潘佳琦在写功能的时候,我给提了点思路,突然一想,如果这个计算机存的是个 Set ,那就不用这样费事了。

假设我们这样改:

private Set<Host> hostSet = new HashSet<>();

后台是简单了,前台表示很无辜。

ListSet ,都是 Json 里的 [] ,前台绑定的都是 Array ,我不管你后台怎么存,但是请你改数据结构的时候不要牵连前台。

既然 ListSet 在前台看起来一样,那为什么不改成 hosts 呢?后台数据结构随便改,对前台无影响。

改正:以后再有新实体,字段名与数据结构分离。

使用 HTTPS

使用 BASIC 认证方式进行登录,前台将用户名和密码进行 Base64 加密传给后台。

HTTP 请求,在网络传输过程中黑客可以直接拦截数据,并查看 headerBase64 解密很容易。

华软项目总结

既然大势所趋,那以后要求安全的项目还是使用 HTTPS 吧。

简单学习了一下, SpringBoot 配置 SSL 需要证书,证书可以买也可以自己生成。 既然能自己生成,为什么还要买呢? HTTPS 证书好像还挺贵呢?

华软项目总结

无意间点开天猫的 cookie ,发现里面只认识 XSRF-TOKEN ,其他的都不知道。仔细想了一下,应该是天猫对安全的要求很高,不光是 HTTPS 保证数据传输的安全,更重要的是要保证发起请求的一定是客户本人,可能有好多算法的验证,保证用户不受损失。

想想我写的,用户的 token 如果被窃取了,谁访问都行。

看来在数据安全的道路上,我们还有很多路要走。

团队文档仓库

写华软部署文档的时候发现,写一个软件如何安装的教程真的是太困难了,并且如何再有项目,再写文档,还需要再写一遍。

可以直接建一个软件安装的文档仓库,再写部署文档,直接说我需要 mysql ,需要 nginx

华软项目总结

直接在 adoc 中使用文件包含,将网上的这个 adoc 文件包含到我的文档中,就好像是自己写的一样,其实是外部引进来的。

Angular 架构

华软项目总结

大家看图,这是我的前台设计思路。

多模块主要是在 NG-ALAIN 那里学习的,此架构设计适用于权限分配系统,因为采用 loadChildren 动态加载模块,也就是说,只有当用户访问 /student 这个路由时,才会加载学生管理 Module ,而不是不管有没有这个模块的权限,直接都交给浏览器去加载。

Core Module ,被学生管理等实际的业务 Module 引用,该模块引入外部第三方组件。

包含基础实体,即与后台对应的实体,拓展实体,实际项目中发现不仅需要基础实体,还需要根据组件要的数据结构自己构建实体并传过去。

基础组件、基础过滤器、 Service ,都放在这里,这样在业务组件里想用就用,很方便。

设计出来了,感觉付诸实践时应该还是有所困难,毕竟目前用的是 NG-ALAIN 现成的,以后需要自己搭。

点赞 Angular

最后为 Angular 点个赞,经过一个项目的洗礼,发现技术选型是正确的,选择 Angular 是多么的明智。

我们追随的一直是国外的脚步, VAR 三者,肯定不用 Vue ,毕竟 TypeScript 都不支持。

所以国外的主流技术一直是 AngularReact ,两者都支持 TypeScript ,只是在设计思想上有所不同。

GoogleFacebook 都是互联网巨头,我们中国的互联网企业与之相比根据不算什么。(去年 Facebook 的股票跌了 6 个京东)

Angular 是框架,完善,直接把 Angular 一安装,什么网络请求,什么路由都有了,直接拿来用。

React 是库,小巧灵活,需要整合其他库才能开发应用,在 Facebook 改协议之前, React 当之无愧的前端第一框架。

Facebook 改了开源协议,就被 Apache 基金会封杀,同时国内全面弃用 React ,所以国内涌现了无数类 React 框架。

即在不修改原 React 项目的前提下,只修改依赖的框架,框架对外提供的 api 相同,即可实现无缝切换。

华软项目总结

最优秀的类 React 框架要数京东的 Nerv ,性能非常好。京东主页采用该框架构建。

之前看到过经过前端的性能优化博客,采用自己设计的链表优化性能,现在也算是明白了面试官的真意。能当上面试官的,肯定都是通读开源项目源码或自己写框架级别的人物,人太多,基础的框架使用是个人学习学习官方文档都会,怎么筛选呢?然后面试官写框架的技术功底就用上了。

所以,你进不去阿里,不是你不够优秀,是你不适合写框架。

总结

总有一天,我们也要写一款属于自己的框架。

原文  https://segmentfault.com/a/1190000018620923
正文到此结束
Loading...