引言
上课,上实验,写文档,终于有时间写博客了。
我觉得这学期的Android
实验上的还是很有意义的,课上,与我的舍友张一帆(自学Android
及相关框架,有过Android
比赛项目经验)一起讨论了Android
的架构分层设计,以及对Retrofit
和RxAndroid
框架的封装。
经过在实验中的学习,以及请教了一些在Android
界算是有小有经验的人之后,发现自己年初对Android
实验设计的有些问题:
年初计划使用Data-Binding
与Fragmentation
实现单Activity
架构,后来发现这样并不好。
-
Data-Binding
学习成本太高,且对原项目结构破坏性较大,对新人学习并理解Android
无益。 - 单
Activity
架构虽然很优秀,但实际项目中仍然是多Activity
+多Fragment
架构,去追求单Activity
意义不大,手动管理Fragment
会十分麻烦。
发现错误,就改吧。目前已经在实验中引入并应用了ButterKnife
、Litepal
、Retrofit
、RxAndroid
等框架,感觉技术上应该不会有太大变化。以后再一起和大家分享一下我在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
里提示,不想拦截器提示信息。
后来反思了一下,自定义状态码应该是合理的,也就是后台返回512
、513
之类的,前台能直接通过状态码准确地判断当前后台到底哪错了。
但是这个拦截器这样写,就变成了,后台一个状态码对应一个提示信息,相当于我这个拦截器和后台抛出的异常绑定了,所以有时候虽然也是那个错,但是在这个界面提示出来就显得格格不入。
奇怪就奇怪在前台误解了自定义状态码的本质,自定义的状态码其实不是我后台有什么,前台就要拦截什么,新加一个状态码,就是为了前台可以更准确地提示信息,而不是一个500
的服务器错误
。
改正:以后拦截器只处理通用的状态码,如:401
跳转到登录,403
提示访问被拒绝。而一些涉及到具体业务的状态码,还是应该放到onError
方法中处理。
不完善的Loading
这是上次开会的时候晨澍提出来的,友好起见,当网络请求的时候应该显示Loading
的动画。
想起来NG-ALAIN
其实是为我们封装好了的,只是没有启用。
其实自己实现原理也简单,就是装饰器模式:
对原生的HttpClient
进行装饰一下,组合一个带Loading
的YunzhiHttpClient
。
以后Service
请求就使用YunzhiHttpClient
,发起时,将Loading
置为true
,数据回来的时候,将Loading
置为false
。
组件中如果想用怎么办呢?直接注YunzhiHttpClient
,因为在同一个模块中是单例的,所以直接使用注入的YunzhiHttpClient
的Loading
来控制加载动画是否显示。
改正:使用此方式添加Loading
动画。
字段名与数据结构分离
@Entity
public class HostGroup {
...
// 和电脑多对多
@ManyToMany
@JsonView({NoneJsonView.class,
HostGroupJsonView.getAllGroups.class,
HostGroupJsonView.getGroupById.class,
UserJsonView.getCurrentLoginUser.class
})
private List hostList = new ArrayList<>();
...
}
HostGroup
中有字段是hostList
,存储计算机列表。
具体的场景忘了,好像是潘佳琦在写功能的时候,我给提了点思路,突然一想,如果这个计算机存的是个Set
,那就不用这样费事了。
假设我们这样改:
private Set hostSet = new HashSet<>();
后台是简单了,前台表示很无辜。
List
和Set
,都是Json
里的[]
,前台绑定的都是Array
,我不管你后台怎么存,但是请你改数据结构的时候不要牵连前台。
既然List
和Set
在前台看起来一样,那为什么不改成hosts
呢?后台数据结构随便改,对前台无影响。
改正:以后再有新实体,字段名与数据结构分离。
使用HTTPS
使用BASIC
认证方式进行登录,前台将用户名和密码进行Base64
加密传给后台。
HTTP
请求,在网络传输过程中黑客可以直接拦截数据,并查看header
,Base64
解密很容易。
既然大势所趋,那以后要求安全的项目还是使用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
都不支持。
所以国外的主流技术一直是Angular
和React
,两者都支持TypeScript
,只是在设计思想上有所不同。
Google
和Facebook
都是互联网巨头,我们中国的互联网企业与之相比根据不算什么。(去年Facebook
的股票跌了6
个京东)
Angular
是框架,完善,直接把Angular
一安装,什么网络请求,什么路由都有了,直接拿来用。
React
是库,小巧灵活,需要整合其他库才能开发应用,在Facebook
改协议之前,React
当之无愧的前端第一框架。
Facebook
改了开源协议,就被Apache
基金会封杀,同时国内全面弃用React
,所以国内涌现了无数类React
框架。
即在不修改原React
项目的前提下,只修改依赖的框架,框架对外提供的api
相同,即可实现无缝切换。
最优秀的类React
框架要数京东的Nerv
,性能非常好。京东主页采用该框架构建。
之前看到过经过前端的性能优化博客,采用自己设计的链表优化性能,现在也算是明白了面试官的真意。能当上面试官的,肯定都是通读开源项目源码或自己写框架级别的人物,人太多,基础的框架使用是个人学习学习官方文档都会,怎么筛选呢?然后面试官写框架的技术功底就用上了。
所以,你进不去阿里,不是你不够优秀,是你不适合写框架。
总结
总有一天,我们也要写一款属于自己的框架。