Pulpcode

捕获,搅碎,拼接,吞咽

0%

python web开发中的设计模式

前言

之前一直总结了很长时间的设计模式,只不过一直都是写在笔记上,并没有整理成博客。之前在学校跟一个老师聊起来的时候,他还说过,有很多东西,他只会写在本子上,从来不会公开的,我见过一些开发了十几年的java大牛,他们也不会轻易的把自己值钱的经验随便告诉给别人,跟他们一起工作,都要相近一切办法才能把值钱的东西挖过来。实际上就是这样,分享归分享,有些东西是会垄断的,你们所谓的google,facebook开源,实际上都是他们觉得不值钱的东西,值钱的东西当然不能开源,毕竟研究起来太费劲,耗费大量人力物力。还有很多人问我问题的时候会说,自己懒得看了,直接告诉他算了。对于这种伸手党也是呵呵了。

那么为什么我要总结这样一篇博客呢?因为我觉得这真不是啥值钱的玩意儿,如果把这点东西还当宝贝,那这辈子眼界也就这么窄了,还有我觉得很少有人会看我的博客。

以上就当我扯淡了,这篇博客的题目叫python的web设计模式。为什么会叫一个这样的题目呢?
首先我觉得,要给自己在工作中所做的事,下一个定义,首先我是一个python工程师,并且我在做web开发,那么一些设计模式,对于我而言是没有用的(当然实际上我也是会的)。而另一些,是我要去加强的。

那么我们就来讲讲,作为一个python web开发者,我们可以忽略掉哪些设计模式,可以加强哪些设计模式? 那么在看这篇博客之前,你自然需要先了解设计模式啦,否则下面的内容你是看不懂的。

创建型模式

实际上我觉得web开发用的最少的就是创建者模式,在我的印象中,GUI和一些游戏的开发可能用的会更多。作为用来建模的设计模式而言,web开发的orm层可能才会用到,毕竟web开发的核心在数据流的处理和状态的维护。

抽象工厂模式

抽象工厂用来创建产品簇,这个我记得在java开发跨平台GUI的解决方案有用到,比如Text,Diagram,Rectangle这些,在window上一套,在linux上一套,这个时候就需要抽象工厂模式来创建这种产品簇,web?我没用过。

建造者模式

之前说道抽象工厂是在不同平台去实现统一的产品簇,而建造者模式用于实现一个xx的产品,比如有个XAF的c#开发库,写好orm和基础handler,就可以生成web和GUI两套界面,内容和操作交互基本都是一样的。web?我没用过。

工厂方法模式

orm中建立数据库链接的那一套东西,基本都是工厂方法的。getConnection,能获得不同类型的数据库链接对象,因为额工厂方法的用以就是定义一个创建产品对象的工厂接口,将实际工作推迟到子类中。在.net里面的数据库链接对象就是产生数据命令对象的工厂,每种数据库的Connection对象里(继承自己的IDbconnection)都对自己的createCommand(定义在IDbCommand里)的实现。

单例模式

实际上python非常好实现单例模式,只要把全局状态放在私有变量中,并提供用于访问此变量的公开函数就行了。网上还有写标准的python单例类写法,继承此类就可以使用,这么说吧,logging对象就算是一个单例,数据库连接池也是单例。这个模式还是很简单常见的。

原型模式

我只有在写单测的时候,用过此技术来从初始对象deepcopy过来,进行修改运行不同单测。

与直接new一个对象不同的是,原型模式的clone技术,更加说明两个对象是上下文相关的,而new出来的对象是上下文无关的。而且比如你的对象初始化要靠读取文件或者数据库,那么clone出来一个的代价要比new一个小得多。

据说orm底层使用了原型模式,在orm对象上做了修改之后,其实会通过原型模式做一个对象链,在保存的时候,会将前后两个对象做对比,相同的就不会修改,不相同的就生成相应的sql语句。

结构型模式

适配器模式

适配器模式算是最常见的设计模式了。主要用途就是将一种对象改造成另一种对象,或者将小对象拼成大对象。这种场景更像是,现在已经有一部分稳定上线的接口了,你开发的产品,要能使用新的接口,又能让老的接口运行,就要使用适配器来兼容老接口了。

在ADO.NET,Microsoft NET Framework,DataAdapter用作DataSet和数据源之间的桥接器,以便检索和保存数据。DataAdopter通过映射Fill(更改DataSet中的数据以便与数据源中的数据相匹配)和update(这更改了数据源中数据以便与DataSet中的数据相匹配)来提供这一桥接器。

桥接模式

桥接模式,将抽象(接口或算法)与实现的方式相分离,你如果做python web开发,那么你一定知道wsgi,这个就算是桥接模式,这使得python的web服务器和python的web框架完美衔接。实际上桥接模式企图搭建一个平台。比如java虚拟机,一方面,它可以运行在windows,linux,mac等不同的平台,另一方面,在它之上又运行着不同的java程序。

JDBC那一套东西也算是桥接模式,Driver Manager管理的API,不同的数据库厂商去实现这些接口,另一方面Jdbc应用又都是在JDBC API的基础上开发的。这样就做到了开发者与数据库厂商的分离。

组合模式

将对象组合成树型结构以表示“整体,部分”的层次结构,composite模式使得客户对单个对象和组合对象的使用具有一致性。

文件系统就是组合模式,xml也算是组合模式。写js的同学在操作html的时候,就对组合模式深有体会,在python的开发上,我很少使用到组合模式,可能xml库会用到吧。

装饰模式

装饰模式是在不必改变原类文件和原用继承的情况下,动态的扩展一个对象的功能,通过一个包装对象,也就是装饰器来包裹真实的对象。实际上python在语法层面上就支持装饰模式,也是就@,比较经典的使用,我记得是tornado中@tornado.gen.coroutine使用yield来写异步代码,还有就是python中对于类的一些属性方法装饰器。

提到一点的是,java io就在使用装饰器模式,什么InputStream,ByteArrayInputStream,FileInputStream,实际上,如果你的代码在处理数据的时候,用yield来拆分功能点,那么使用装饰器也是很爽的。

外观模式

外观模式主要提供一个整洁的一致性接口给客户端,N层构架的应用程序,就算是Facade模式了。也就是同一类产品簇提供相同的接口。这个我觉得在设计web服务的时候会用到,比如我之前的web服务都会有两层,在基础服务这一层前面再挡一层业务曾,这样对于客户端前端的调用而言,业务层暴露的接口就是统一,简单的。

享元模式

它通过使用共享物件,用来经可能的减少内存使用量以及分享咨询给尽可能多的相似物体。文字处理系统中图形字符,.net的string类型,python的str,和一些不可变对象都使用了享元模式。这个在web开发中,几乎没用到过。这个在开发中几乎用不到,因为此模式,一般用于解决系统性能问题,所以经常用于底层开发,在项目中并不常用。

代理模式

代理模式也是一种常见的模式,1.为其他对象提供一种代理以控制这个对象的访问,解决直接访问某些对象出现的问题。

代理模式的根本根本是,保护一个对象的操作,在一个对象的操作上,追加其他方法。

在实际生产中,我们可以看到:

  1. 远程代理,能够为一个位于不同的地址空间的对象提供一个本地的代理对象。
  2. 保护代理,用于保护对象的访问权限。
  3. 智能指针,取代简单的指针,在访问对象时,提供额外的附加操作。
  4. copy-on-write, 延迟处理的代理。

我觉得单元测试中的mock对象也算是代理对象,当然你最常见到的还是代理服务器,vpn之类的。

行为模式

创建型模式关注对象的创建,结构型模式关注类和对象之间的组织关系,而行为模式关注对象间的交互和职责分配。

所以我觉得结构型模式才是web开发最常用的,创建和行为模式都不是特别常用。

命令模式

将行为抽象成对象的模式?记录每一步操作,可以undo,redo。我是没用过。。。

迭代器模式

迭代器模式是一个很常用的模式,它分离了聚合对象的遍历行为,抽象出了一个迭代器负责,这样既可以做到不暴露集合内部结构,又可以让外部代码透明的访问集合内部数据。
范型都用了迭代器模式,但是这个和web开发没啥关系,算是比较基础的模式吧。

观察者模式

发布订阅模式,这个在web开发中倒是很常用,比如你要关注此消息,那你就订阅此消息,这样把你放到一个“用户”队列中,这样消息好了,会依次通知每一个用户的。事件驱动也是玩的这招。监听某个事件。

中介者模式

我只知道电脑的主板,就算是中介者模式,用来解决一组对象之间的相互通信,而它们之间不需要显示的交互,但是我真没用过此模式做开发。

备忘录模式

这个模式是不是可以理解为每次上线服务都要做个备份?方便能够回滚?我在web开发也没用过,保存和跟踪对象的状态,以便于必要时可以把对象恢复到以前的状态。

解释器模式

这个估计只有领域型语言设计才会用到吧,解释表达式什么的,web开发估计真不会用到。

模板方法

定义一个操作的骨架,将步骤延迟到子类中,如果你在写web框架,那么模板模式是一种在常用不过的模式了,比如你在使用tornado的时候,就会重写start()和on_finish()方法,unit库,你会去实现setup和teardown方法。

责任链模式

你会做一个对象链,而请求就在这个链条上传递,直到链上某个对象解决处理此请求。

其实异常处理就算是一种责任链,而java 中的servlet的filter也算是责任链模式,拦截就处理,不拦截就传递,你可以在web服务中插入多层责任链,验证数据和一些风控,又方便扩展。

状态模式

状态模式和状态机是两个概念,状态模式实际上为了一个对象在内部状态改变时改变其行为。
也就是说这些状态类实现了统一的操作接口,只不过同一个操作在不同的状态下,结果也不同。
这个在游戏开发的时候,精灵类会用到,web开发我没用过,可能只有设计一站式框架才会用到把。

策略模式

将算法推迟到子类去实现,而策略代表了一种算法簇,钩子函数就是常见的策略模式,如果这么说来,map,reduce,filter都算是策略模式了,还有sort排序传入的比较函数。

访问者模式

三个字,“我不会”,这个模式很难,而且基本永不到,类似于多重继承和元类设计这种东西,要么你会用,要么你别用,别你觉得你会你想试着用下,算了吧你。。。

总结

其实看到我想说的是,23种设计模式,以你的工作场景来选择学习使用总结,还要去记住真实的使用场景和例子,不要一股脑全背了。还有在python中实现方式和java中也有很大的不同。如果用python写java代码,那就是你太蠢了。还有你会发现orm中有很多值得去学习的技术。