********************** 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遮盖其余内容了 .. code-block:: html 2. 然后又重新接触了一遍flask-login,感觉其原理就是在login_user的时候将通过get_id方法将user_id存进session里面,然后碰到login_required就回调user_loader函数,产生一个user并赋给current_user 3. 还有一个比较坑的地方,就是千万不要在用url_for的时候把头部的.给忘记了 4. 网页版的url有个坑就是要不能和api冲突,如果有冲突的话flask怎么解决的呢?这个问题还没有深究 5. 在打包发布的时候遇到了一个NotADirectoryError,似乎是jinja2的函数无法读取eggs包下的文件,解决这个问题的有效手段是打包的时候使用 ``zip_safe=False`` 这么个选项,安装后就是一个directory,可以直接进行读取 6. 解决了前面这个问题之后接着又遇到了一个新的问题,就是没有把模板文件给打进去,开始在MANIFEST.in里面加了 ``include *.html`` ,发现根本没有效果,原来是因为路径的问题,要么指明执行打包命令的相对路径(是执行命令的相对路径还是setup.py所在的目录的相对路径呢),要么就直接使用 ``global-include *.html`` ,最终答案还是在官方文档找到的,看来是要多看文档了 ============= version 1.4.0 ============= 2. 优化客户端的token维持问题,有效token的时间太短,每次操作要更新token的时限 3. 优化客户端的分页,使用paginate做分页而不是客户端自己写,已选择的页面要点亮 4. 显示版本号 5. 客户端修改路由,增加不同版本api的blueprint,最多连续维护3个版本 6. 运用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,并且**子模块能够直接控制父模块或者其他子模块** a. 层级耦合:子模块初始化在父模块的构造函数当中,父模块对子模块会干什么有完全充分的预期,两者结合紧密。在这种情况下子模块往往需要调用父模块,那么其中的接口必须设计非常合理,需要考虑几个要点: (1)父模块的哪些方法、哪些属性是可供子模块调用的,不可用的全部使用`_`表示一下 (2)哪些属性应当存储在父模块当中?多个模块都会使用到的 (3)哪些属性应当存储在子模块当中?只有子模块自己会用到的 (4)子模块的哪些方法、哪些属性是可供父模块调用的,不可用的全部使用`_`表示 b. 层级非耦合:子模块初始化在父模块初始化之外(例如flask插件),父模块提供一大堆子供子模块使用的工具,子模块一般只使用父模块提供的工具,不会去调用其他子模块(父模块自带的子模块除外),这种设计可拓展性非常强,但是相对来说由于耦合性不高,效率也会低一些,因为有些地方可能牺牲了效率以带来可拓展性 2. Pycharm用起来真的是非常方便,比如分栏显示,以后要去挖掘更多的使用技巧 3. 有些现有的轮子不要自己造,比如tkinter的grid_slaves方法 4. logging的基本用法当前已经掌握,就是各个模块的logging如何建立联系还不甚清楚,之后进一步学习的时候解决这个问题,目前需要打日志的地方主要是debug,对于数据的获取(比如请求、文件的读取),这些有不确定性的地方需要打日志,日志级别可以定位info,开发过程当中每一个小的环节都可以打上日志,跑的时候很容易发现问题出在哪里,日志级别可以定位debug,还有就是对于所有异常都打上日志,在不断的实践当中再思考这个问题吧 5. 现在使用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. 需要做异常判断的领域主要是不能确保是否会出现问题的领域,有哪些呢?主要都是要和外部进行沟通的 a. 文件IO #. 网络IO #. 数据库处理 =========== version 1.1 =========== 1. 之后再补充吧