开发鱼书网站的收获

291 阅读5分钟

目录:

  • web应用结构
  • 模型与数据库,Code First
  • OOP: ViewModel的意义
  • 代码解释权反转
  • ORM和原生SQL语句
  • 数据库事务和其他
  • Flask框架知识
  • Python的知识
  • 总结

web应用结构

可以抽象成两个点:Request 和 Response,请求和响应。

  • 从这请求和响应两点展开看:

客户端按照HTTP协议格式发送请求到服务端。经过tcp三次握手,IP解析,到达服务端。然后服务端做出响应,返回HTTP协议格式的数据,经过tcp四次挥手,客户端收到数据。

  • 再展开到服务端:

一个请求到达了服务端 -> 硬件防火墙 -> 从nginx代理服务器 -> 遵循WSGI协议的socket服务器 -> 基于web框架的应用 -> web框架原路返回请求需要的数据

  • 再展开到基于web框架的应用:

路由分发,定位到相应路由下的具体函数 -> 全局验证器 -> 连接模型 -> 连接数据库 -> 根据业务得到最终数据 -> 创建Response对象,把数据放入,最后返回。

  • 再到全局验证器:

特别提一下基于AOP思想的全局验证器,通过它验证数据是否有效。这是保障应用健壮的关键一步。

模型,数据库和Code First

Code First是指直接在模型类里编写表字段,关心怎么创建数据。(ORM关心的范围更广)

Code First可以让我们专注业务模型的设计,而不是专注数据库的设计。

数据库只是用来存储数据的,它的表关系应该由我们的业务来决定。

所以,表设计直接在Model模型类里完成,业务逻辑也可以直接写在模型方法里,达到复用效果。

ViewModel的意义

ViewModel 顾名思义,指对应一个页面的Model,即这个ViewModel能提供这个页面需要的数据。

ViewModel对应的概念:原始Model,是一个和数据库表字段一一对应的模型类。如果直接用原始Model的数据填充页面的话,会有大量冗余的数据用不上。

这时就可以创建一个专门对应页面数据的Model,它的数据和页面需要的数据是一一对应的。

这样做的好处:

  • ViewModel可以更好的复用,包括在多个相同性质的页面中。
  • 业务逻辑可以定义在ViewModel的方法中,也实现了业务逻辑的复用。

可以说很好的利用了面向对象编程的特性。

一般的经验是创建单体和集合两个viewModel类。

代码解释权反转

一段编写好的代码里,预留一个位置给调用者,调用者可以使用也可以不使用这个位置。如果调用者使用了,那么就称为“代码解释权反转”。

为什么叫反转?是因为本来这段代码直接由编写者定好,解释权在编写者手里。但如果调用者使用了这个预留的“位置”,那么解释权就到了调用者手里,也就相当于反转了。

本质是定义者把逻辑控制交给了调用者。

具体实现:

使用函数式编程。调用者通过传递一个函数,以此实现使用这个“预留位置”,获取解释权。

原生SQL语句和ORM

从数据库读取数据时,有两种方法:

  • 直接写原生SQL语句,这种性能最优
  • 写ORM对象关系映射语句,这种性能较差

还有一种取平衡的中间方法,基于原生SQL语句封装成和ORM语句相同的API。当然也支持原生SQL语法的写法。

在Python里有peewee,Java里有jood。

数据库事务和其他

数据库事务是指,在某种错误发生后,重置刚才被打断的数据库写入,防止数据混乱。

事务有两个功能或者说好处:

  1. 保证数据的正确性。因为有commit提交和rollback回滚,确保数据不出错。
  2. 数据库链接之间是隔离的。比如多个删除的请求,一个请求删了一半,另外的请求还是可以看到完整的数据,不会就只看到一半的数据了。具体到flask中,请求被flask接收后,都会通过flask sqlalchemy的数据库链接池分配一个数据库链接,请求结束后,会把这个数据库链接返回给flask sqlalchemy的数据库链接池。flask通过这样的方式实现了数据库的隔离和链接的复用。

其他的:

一般查一张表和关联表的数据,就会遇到n+1问题,先有一条复杂度为O(1)的数据,然后循环遍历找其相关联的数据为O(n^2),数据大了后无疑是很慢的。

这里就会用join来解决。这样就使用了数据库本身的优化,在数据上做了计算,而不是单纯地移动数据,然后自己再计算,只是这样的话会被大量IO拖慢,没有一个上下文,数据库也不能统一优化查询。

Flask框架知识

Flask核心机制:

  • 存储上下文的栈结构
  • AppContext,应用上下文
  • RequestContext,请求上下文

  • Flask中的线程隔离对象Local和隔离栈Local Stack

Python的知识

  • 可调用对象:call
  • 上下文管理器:context manager
  • 各种魔法方法和运算符重载
  • 属性描述符@property和@属性名.setter实现get和set

还有很多,一时想不起了……

总结

列举了一些我掌握到的编码和Web知识点。这些知识点很杂乱,不是很好总结在一起。或许以一个应用项目为单位来总结,不失为一个方法,反正杂乱无法理顺,索性见招拆招。