# -*- coding: utf-8 -*-
__author__ = 'Administrator'
#python高级编程:有用的设计模式
#设计械是可复用的,某种程序上它对软件设计中觉问题提供的语言相关解决识方案,最近最流行的书籍:
"""
gamma、heim、johson和vlissides a.k.a"四人组(gof)"编写的elements of reusable object-oriented software(中文:<设计模式:可复用面向对象软件基础>)
它被认为这个领域中重要作品
python提供了3种设计模式:
"""
#创建型模式:用于生成具有特定行为的对象模式
"""它提供了实例化机制,它可以是一个特殊的对象工厂甚至类工厂,这在比如x之类的编译型 语言中很重要的模式,因为在运行时按照要求生成类型更加困难
,但是在python中,这些是内建的,比如type,可以通过代码来定义新的类型,如下:"""
mytext=type('mytyper',(object,),{'a':1})
ob=mytext()
print type(ob)
print ob.a
print isinstance(ob,object)
"""
类和类型是内建工厂,这些功能是实现工厂设计模式的基础
除了工厂之外,python中gof的唯一有趣的创建模式是单例模式(singleton)
"""
#单例模式:用来限制一个类只能实例化为一个对象
"""
单例模式确保给定的类在应用程序中始终只存在一个实例.例如:当希望限制一个资源在进程中访问一个并且只有一个内在上下文的时候,就可以使用它
举个例子:一个数据库连接器类就是一个单例,在内存中处理同步并其数据,它假设没有其他实例同时与数据库交互。
这个模式可以大大简化应用程序中并发的处理,为整个应用程序满园提供功能的实用程序往往被声明为单例,通过 以下例子解释这个
使用__new__方法,如下:
"""
class A(object):
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls,'_instance'):
            orig=super(A,cls)
            cls._instance=orig.__new__(cls,*args,**kwargs)
        return cls._instance
class B(A):
    a=1

one=B()
two=B()
two.a=3
print one.a
#不过这种模式子类化方面也存在一些问题--所有实例化是B的实例,而不管方法解析顺序(__mro__)结果,如下:
class C(B):
    b=2

tree=C()
#print tree.bAttributeError: 'B' object has no attribute 'b'
"""
为了避免这样的限制,alex martelli提供了一个基于共享状态的替代实现,即borg
这个思路是,单例模式中真正重要的还是类存在的实例数量,而且它们在任何时候都将共享相同状态事实,所以
alex martelli引入了一个类,使用所有实例共享相同的__dict__,如下:
"""
class Borg(object):
    _state={}
    def __new__(cls, *args, **kwargs):
        ob=super(Borg,cls).__new__(cls,*args,**kwargs)
        ob.__dict__=cls._state
        return ob

class B1(Borg):
    a=1

a=B1()
b=B1()
b.a=3
print a.a
class B2(B1):
    b=2
tree=B2()
print tree.b
print tree.a
tree.a=2
print a.a
"""
这解决了子类的问题,但是仍然依赖于子类代码的工作方式,如果__getattr__被重载,那么这个模式可能会被破坏。
虽然如此,单例不应该有多级别的继承,标记为单例的类已经是特殊类了
也就是说,该模式被许多开发人员视为处理应用程序唯一性问题的重要方法,如果需要一个单例,既然python模式也是一个单例,
那么为什么不使用带有函数的模块来代替呢
单例工厂是牗应用程序中唯一性的一个隐含方法,也可以不使用它,除非在一个使用java风格的框架,否则应该使用模块来代替类
"""

#结构型模式 有助于针对特定使用场景的代码结构模式
"""
它们决定代码的组织方式并且提供了开发人员和应用程序各部分交互的方法.
在python世界中,最著名的实现是zope component architecture(zope组件架构,简写为zca,请看:<http://wiki.zope.org/zope3/componentarchitectureoverview>)
它实现了大部分模式,并提供了处理这些模式的丰富工具集,zca并不只zope框架,还可用于诸如twisted之类的其他框架,还提供了界面和适配器的一个实现。
所以即使是不大的作品,也应该考虑用它,而不是从头开始重写这样的模式。
有很多从gof11原作中继承而来结构化模式
允许使用装饰器一个函数,但是不是在运行时,在未来版本中被扩展为类
如下:http://www.python.org/dev/peps/pep-3129
其他流行的模式是:
"""
#适配器:用来封闭一个类或者一个对象A,它可以工作在用于一个类或者对象B的上下文中
#当一些代码被用来处理一个指定的类,从另一个类给予它对象是很好的,这些对象提供代码所使用的方法和特性即可,这形成了python中的duck-typing思想的基础
#如果它走起来像鸭子,说起来也像鸭子,那么它就是鸭子
#当然,这假定代码没有调用instanceof以验证该实例是一个特定类
#我说它是一个鸭子,没有必要检查它的dna
#行为型模式  有助于对进程进行结构化的模式
"""
适配器基于这种思想并定义了一个封装机制,在这样的机制,封装了一个类或者对象,以便使其在不是为它提供上下文中工作,stringIO是个典型的例子
它改编了str类型使其可以像file类型一样使用,如图:

"""
from StringIO import StringIO
my_file=StringIO(u'some content')
print my_file.read()
my_file.seek(0)
print my_file.read(1)
"""
再举个例子,dublincoreinfos类知道如何为指定的文档显示dublin core信息(请看http://dublincore.org),它读取几个字段
比如作者名或者标题并且打印,为了能够为一个文件显示dublin core,它必须和stringio一样改变,上面的图片给出了这个模式类-uml图,这个类提供了一个实例,并且提供了针对它的元数据访问,如下:
"""
from os.path import split,splitext
class Dublincoreinfos(object):
    def __init__(self,filename):
        self._filename=filename
    def title(self):
        return splitext(split(self._filename)[-1])[0]
    def creator(self):
        return 'unknow'#真实获取
    def languages(self):
        return ('en',)

class dublincoreinfosinfo(object):
    def summary(self,dc_ob):
        print 'title:%s'%dc_ob.title()
        print 'creator:%s'%dc_ob.creator()
        print 'languages :%s',','.join(dc_ob.languages())
adatep=Dublincoreinfos('example.txt')
info=dublincoreinfosinfo()
info.summary(adatep)
"""
除了允许替换之外,适配器模式不能改变开发人员的工作,改编一个对象使其工作于特定的上下文,设想对象是什么类无关紧要
重要的是这个类dublincoreinfosinfo()所期待的特性,这种行为由一个适配器来修复或者完成,所以代码只要以某种方式告知它与实现特定行为的对象兼容即可,而且是可以由接口(interfaces)来表示
"""
#1:接口
"""
是api的一个定义,它描述了一个类为所需要的行为必须实现的方法和特性的列表,这个描述不实现任何代码,只定义希望实现的该接口的类所用的明确契约(contract)之后,任何类都可以以其希望的方式实现一个或者多个对象。
虽然在python中,相比接定义更喜欢duck typing,但是有时候使用接口可能更好
这样做的好处是:类是低耦合的,这被认为是好的做法
许多开发人员要求将接口添加为python的核心功能,当前这些希望使用接口的人现在都被迫使用zope接口或者pyprotocols
以前,guido拒绝将接口添加到python中,因为它们不适合python动态的duck-typing特性,但是,接口系统在某些情况下证明了它们价值,所以python3000将引入一个被称为
option type annotations(可选类型符号)的特性,这个特性可以作为针对第三方接口库的语法
"""
"""
最近python 3000还添加了抽象基类(ABC)支持,以下是从pep中摘录的
<abc只是被添加到对象继承中的python类,它用来向外部检查程序传达该对象某些功能>
适配器对于使类和执行上下文保持耦合而言是完美的,但是,如果将适配当作编程思想,而不是作为在特定过程中对必须使用的
对象做一个快速修复,那么应该用接口.
"""

python高级编程:有用的设计模式1的更多相关文章

  1. python高级编程:有用的设计模式3

    # -*- coding: utf-8 -*-__author__ = 'Administrator'#python高级编程:有用的设计模式#访问者:有助于将算法从数据结构中分离出来"&qu ...

  2. python高级编程:有用的设计模式2

    # -*- coding: utf-8 -*- __author__ = 'Administrator' #python高级编程:有用的设计模式 #代理 """ 代理对一 ...

  3. python高级编程技巧

    由python高级编程处学习 http://blog.sina.com.cn/s/blog_a89e19440101fb28.html Python列表解析语法[]和生成 器()语法类似 [expr  ...

  4. python高级编程之选择好名称:完

    由于时间关系,python高级编程不在放在这边进行学习了,如果需要的朋友可以看下面的网盘进行下载 # # -*- coding: utf-8 -*- # # python:2.x # __author ...

  5. python高级编程读书笔记(一)

    python高级编程读书笔记(一) python 高级编程读书笔记,记录一下基础和高级用法 python2和python3兼容处理 使用sys模块使程序python2和python3兼容 import ...

  6. python高级编程之列表推导式

    1. 一个简单的例子 在Python中,如果我们想修改列表中所有元素的值,可以使用 for 循环语句来实现. 例如,将一个列表中的每个元素都替换为它的平方: >>> L = [1, ...

  7. Python高级编程之生成器(Generator)与coroutine(二):coroutine介绍

    原创作品,转载请注明出处:点我 上一篇文章Python高级编程之生成器(Generator)与coroutine(一):Generator中,我们介绍了什么是Generator,以及写了几个使用Gen ...

  8. Python高级编程-Python一切皆对象

    Python高级编程-Python一切皆对象 Python3高级核心技术97讲 笔记 1. Python一切皆对象 1.1 函数和类也是对象,属于Python的一等公民 ""&qu ...

  9. 第三章:Python高级编程-深入类和对象

    第三章:Python高级编程-深入类和对象 Python3高级核心技术97讲 笔记 3.1 鸭子类型和多态 """ 当看到一直鸟走起来像鸭子.游泳起来像鸭子.叫起来像鸭子 ...

随机推荐

  1. Python操作Redis的5种数据类型

    1.连接redis(两种方式) # decode_responses=True: 解决获取的值类型是bytes字节问题 r = redis.Redis(host=', db=0, decode_res ...

  2. @JoinTable和@JoinColumn

    默认情况下,JPA 持续性提供程序在映射多对多关联(或在单向的一对多关联中)的拥有方上的实体关联时使用一个连接表.连接表名称及其列名均在默认情况下指定,且 JPA 持续性提供程序假设:在关系的拥有方上 ...

  3. Kinect for Windows V2和V1对照开发___彩色数据获取并用OpenCV2.4.10显示

    V1彩色分辨率:640x480 V2彩色分辨率:1920x1080 1,打开彩色图像帧的方式 对于V1: 使用NuiImageStreamOpen方法打开 hr = m_PNuiSensor-> ...

  4. 在VM中安装Android4.4连接小米手环 之 在VM中安装Android4.4

    今天刚买了个小米手环,系统须要4.4及以上,但自己手机系统版本号不匹配.故打算在VM中安装Android4.4连接小米手环. 这一节先介绍在VM中安装Android4.4(怎么安装VM就不介绍了) 1 ...

  5. Ajax客户登陆验证

        服务器端操作方便之处我就不吹了,地球人都知道,它最烦莫过于页面刷新,头都被刷晕了,而且他在刷新的时候,还触发服务器端的事件,现在Ajax的出现,他们的结合是发展的必然!    一.介绍一下Aj ...

  6. python 登陆一个网站

    今天想用python写一个登陆的脚本,搜了一下,网上挺多的,看了一些后写了个登陆虎扑论坛的脚本. 原理: 只要在发送http请求时,带上含有正常登陆的cookie就可以了. 1.首先我们要先了解coo ...

  7. Sql Server批量停止作业

    CREATE Proc [dbo].[Proc_StopJob] as begin declare @I int declare @JobID uniqueidentifier -- 1. creat ...

  8. 使用PHP-Barcode轻松生成条形码(一)

    最近由于工作需要,研究了一下PHP如何生成条形码.虽然二维码时下比较流行,但是条形码依然应用广泛,不可替代.园子里有很多讲利用PHP生成条形码的文章,基本上都是围绕Barcode Bakery的,它虽 ...

  9. 很强的PHP图片处理类

    /*** 基本图片处理,用于完成图片缩入,水印添加* 当水印图超过目标图片尺寸时,水印图能自动适应目标图片而缩小* 水印图可以设置跟背景的合并度** Copyright(c) 2005 by ustb ...

  10. 用Ajax读取XML格式的数据

    ].firstChild.data);}catch(exception){ }}}}</script>