vocabularyBook项目规划

server端的java实现项目计划

  1. 使用单元测试测试所有代码
  2. 初步封装jdbc,实现简洁明了的增删改查
  3. 使用mybatis,并进一步深挖mybatis的功能
  4. 使用cglib动态代理实现aop,完善日志系统
  5. 进一步深挖spring mvc的功能
  6. 进一步深挖spring的功能

搞这个项目主要是通过实践搞明白mybatis+spring-mvc+spring这些框架

version 1.5.0 and later

  1. 单词复习的功能,点击记住了的单词会在之后再次出现,每个单词会出现x次,时间间隔自己定
  2. 增加所有单词功能,显示所有的单词,并显示复习的次数,能够删除单词
  3. 增加redis的支持,部分内容使用redis进行存储
  4. 重构客户端代码,进一部分拆分逻辑,使得所有的请求都带上token验证,并判断是否返回新token
  5. 网页版增加一个错误页面

version 1.4.2

  1. 完善web端应有的功能,比如flash提示、错误提示之类的
  2. 完善单元测试、注释、异常处理、日志
  3. 加入sentry监控
  4. 加入配置文件
  5. 单元测试加入coverage检查测试覆盖
  6. 测试一下views当中的函数

version 1.4.1

  1. 使用flask-bootstrap开发web端

version 1.4.1 项目总结

本次开发过程当中遇到的问题还是很多的

  1. 首先是flask-bootstrap的使用,稍微了解了一下大致的用法已经清楚了,有几个小窍门可以注意一下并整理到文档当中
(1)使用super()可以调用父模板的内容
(2)link形式的按钮样式冲突的问题直接使用正常的link就能解决了,不要使用button
(3)模板里面很多东西不能使用,以后任何数据的处理直接在view层或者model层处理完毕,view里面尽量传最终数据
(4)使用center-block可以使用bootstrap中的对象居中,但是不能和栅格大小的class混用
(5)给body增加一个padding就可以防止吸顶的navbar遮盖其余内容了
<style type="text/css">
body { padding-top: 70px; }
</style>
  1. 然后又重新接触了一遍flask-login,感觉其原理就是在login_user的时候将通过get_id方法将user_id存进session里面,然后碰到login_required就回调user_loader函数,产生一个user并赋给current_user
  2. 还有一个比较坑的地方,就是千万不要在用url_for的时候把头部的.给忘记了
  3. 网页版的url有个坑就是要不能和api冲突,如果有冲突的话flask怎么解决的呢?这个问题还没有深究
  4. 在打包发布的时候遇到了一个NotADirectoryError,似乎是jinja2的函数无法读取eggs包下的文件,解决这个问题的有效手段是打包的时候使用 zip_safe=False 这么个选项,安装后就是一个directory,可以直接进行读取
  5. 解决了前面这个问题之后接着又遇到了一个新的问题,就是没有把模板文件给打进去,开始在MANIFEST.in里面加了 include *.html ,发现根本没有效果,原来是因为路径的问题,要么指明执行打包命令的相对路径(是执行命令的相对路径还是setup.py所在的目录的相对路径呢),要么就直接使用 global-include *.html ,最终答案还是在官方文档找到的,看来是要多看文档了

version 1.4.0

  1. 优化客户端的token维持问题,有效token的时间太短,每次操作要更新token的时限
  2. 优化客户端的分页,使用paginate做分页而不是客户端自己写,已选择的页面要点亮
  3. 显示版本号
  4. 客户端修改路由,增加不同版本api的blueprint,最多连续维护3个版本
  5. 运用REST风格重新建构API

version 1.4.0 项目总结

2017-08-31

  1. 维护多个版本api需要注意的是model改变的同时也需要改变旧版本api的一些逻辑
  2. 客户端本地持久化数据有个坑,就是文件读写千万不能用相对路径,因为你不知道到启动脚本是在那个目录下调用的,这会导致持久化数据的文件位置是不定的,所有的文件都应该以app包的路径为依据构建路径,并为了在多系统下使用需要使用os.path.join来构造路径
  3. token的更新我采取的方案是通过装饰器去做,对于被装饰的路由函数首先读取token,如果token有效但剩余时间少于一半则发一个新的token过去,为了使装饰器与路由函数解耦,路由函数尽量不做任何必要范围之外的事情,但是由于jsonify返回的是一个response对象,难以拆开后再封装,所以路由函数不得不返回一个tuple来让装饰器进行进一步的处理(这个暂时没有想到更好的方案)。不过使用一个装饰器来解决这些问题我感觉是已经做得比较完美了
  4. 新的token方案需要客户端进行配合,因此客户端实现了一个对于新token的读存函数
  5. 客户端分页使用flask-sqlalchemy的paginate来做简单多了,要注意的是客户端请求的时候需要加一个请求参数
  6. REST风格的新建单词应当使用words这个路由,对words这个路由使用POST方法即可。
  7. REST风格客户端仅需要确定几个顶级路由,对于其他资源的路由都通过请求信息的获取,比如对于word的路由在请求words的时候直接返回单个word资源的url信息,这样可以保证后端路由的可配置型

version 1.3.1

  1. 服务端和客户端均增加增加异常处理,对于所有的IO操作都必须做异常处理,甚至要对所有会raise异常的函数或方法都要做异常处理,而非在事先进行一系列判断
  2. 完善注释,完整过一遍文档,觉得有必要注释的地方都加一下注释,并且对现有的代码进行进一步的优化
  3. 顺便整理一套注释方案和异常处理方案
  4. 完善日志管理,日志管理的进阶

version 1.3.1 项目总结

2017-08-29

  1. 首先对于日志的处理有了更深的理解,一个logger可以使用多个handler对日志进行处理,一般的处理方式是低级别日志使用一个StreamHandler,高级别日志使用一个FileHandler,这样基本够用了
  2. 其次对于异常的处理也有了一定的想法,一般情况下对于那些受外部环境影响操作进行异常的捕捉,这是异常的最初级使用方式,因为如果不是外部环境影响的,那是bug,是你可以直接规避的,如果你能捕捉异常,那么你自然可以解决这些bug
  3. 对于flask的异常、日志体系有了更进一步的了解,对于特定错误设置错误码不要和flask的默认错误码重合了,不然会导致客户端判断错误
  4. 异常处理还是条件判断的选择首要因素是是否直观,比如first(),如果没有值明显返回为None,这个直接用if判断很清晰,如果用异常的话判断TypeError很奇怪,最好判断的异常是语句操作的典型异常直观异常,否则会很奇怪

version 1.3

  1. 客户端使用面向对象方法对项目进行重构,拆解为注册页面、登录页面、单词本页面三个页面,使用三个对象去进行处理,这些对象可以考虑直接继承Frame类
  2. 服务端增加logging日志管理
  3. 服务端增加Model的单元测试

version 1.3 项目总结

2017-08-26

  1. 学到了一种设计模式,不应该说是两种,这两种设计模式都是应用在层级嵌套结构当中的(即一个对象由多个不同的对象组成,最简单的是java课上的那个clock,并且**子模块能够直接控制父模块或者其他子模块**
  1. 层级耦合:子模块初始化在父模块的构造函数当中,父模块对子模块会干什么有完全充分的预期,两者结合紧密。在这种情况下子模块往往需要调用父模块,那么其中的接口必须设计非常合理,需要考虑几个要点:
(1)父模块的哪些方法、哪些属性是可供子模块调用的,不可用的全部使用`_`表示一下 (2)哪些属性应当存储在父模块当中?多个模块都会使用到的 (3)哪些属性应当存储在子模块当中?只有子模块自己会用到的 (4)子模块的哪些方法、哪些属性是可供父模块调用的,不可用的全部使用`_`表示
  1. 层级非耦合:子模块初始化在父模块初始化之外(例如flask插件),父模块提供一大堆子供子模块使用的工具,子模块一般只使用父模块提供的工具,不会去调用其他子模块(父模块自带的子模块除外),这种设计可拓展性非常强,但是相对来说由于耦合性不高,效率也会低一些,因为有些地方可能牺牲了效率以带来可拓展性
  1. Pycharm用起来真的是非常方便,比如分栏显示,以后要去挖掘更多的使用技巧
  2. 有些现有的轮子不要自己造,比如tkinter的grid_slaves方法
  3. logging的基本用法当前已经掌握,就是各个模块的logging如何建立联系还不甚清楚,之后进一步学习的时候解决这个问题,目前需要打日志的地方主要是debug,对于数据的获取(比如请求、文件的读取),这些有不确定性的地方需要打日志,日志级别可以定位info,开发过程当中每一个小的环节都可以打上日志,跑的时候很容易发现问题出在哪里,日志级别可以定位debug,还有就是对于所有异常都打上日志,在不断的实践当中再思考这个问题吧
  4. 现在使用unittest做基本的单元测试已经是没有问题了,接下来考虑更高级的测试,models当中的这些函数测试难度太小了

version 1.2

  1. 分离各用户的单词显示,每个用户只显示自己的单词
  2. 持久化存储token,token过期才需要进行登录
  3. 所有注册登录异常的客户端正常提示
  4. control模块的改造,在不同页面下显示不同的control button,计时器在进入view时才开始进行计时
  5. 计时器时间的持久化存储,暂时不提供查看的入口

version 1.2 项目总结

2017-08-24

有几个重点:

  1. python当中如果数据要持久化存储的话,一个是通过数据库进行存储,一个是通过序列化的方式存储在本地,两者各有合适的使用场景
  2. 项目达到几百行,而只有一个类的时候会发现所有的东西都太冗长了,而且有些变量是需要私有化的,对于类的分割还要再深一个层次
  3. 需要做异常判断的领域主要是不能确保是否会出现问题的领域,有哪些呢?主要都是要和外部进行沟通的
    1. 文件IO
    2. 网络IO
    3. 数据库处理

version 1.1

  1. 之后再补充吧