# -*- 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. SMO(Sequential Minimal Optimization) 伪代码(注释)

    Algorithm: Simplified SMO 这个版本是简化版的,并没有采用启发式选择,但是比较容易理解. 输入: C: 调和系数 tol: 容差 (tolerance) max passes: ...

  2. php增删改查,自己写的demo

    1.链接数据库通用方法:conn.php <?php //第一步:链接数据库 $conn=@mysql_connect("localhost:3306","root ...

  3. html+jq实现简单的图片轮播

    今天上班没事,就自己琢磨着写一下图片轮播,可是没想到,哈哈竟然写出来啦,下面就贴出来代码,作为纪念保存下下哈: <body style="text-align: center;&quo ...

  4. Java多线程练习二

    public class ex3 { public static void main(String [] args) { thread2 t1 = new thread2("hello&qu ...

  5. sqlserver中的序列

    序列是由用户定义的绑定到架构的对象.序列依据定义的间隔按升序或降序生成,并可配置为用尽时重新启动(循环).序列不与特定表关联.序列与表之间的关系由应用程序进行控制. 创建序列的语法: CREATE S ...

  6. Jquery 使用JSOPN实例

    1.说明 dataType:返回的数据类型 jsonp:传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback) jsonpCallback:自定义的jsonp ...

  7. 3.Android Studio系列教程3——快捷键

    原文链接:http://stormzhang.com/devtools/2014/12/09/android-studio-tutorial3/   一.更新Android Studio 项目根目录的 ...

  8. ViewPager欢迎页

    布局  <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:to ...

  9. C/C++中的拷贝构造函数和赋值构造函数

    代码: #include <iostream> #include <cstdio> using namespace std; class A{ public: A(){ cou ...

  10. OpenSceneGraph FAQ

    转自http://www.cnblogs.com/indif/archive/2011/04/22/2024805.html 1.地球背面的一个点,计算它在屏幕上的坐标,能得到吗? 不是被挡住了吗? ...