Python设计模式用模式改变软件设计DOCWord文件下载.docx
- 文档编号:19010019
- 上传时间:2023-01-03
- 格式:DOCX
- 页数:9
- 大小:72.23KB
Python设计模式用模式改变软件设计DOCWord文件下载.docx
《Python设计模式用模式改变软件设计DOCWord文件下载.docx》由会员分享,可在线阅读,更多相关《Python设计模式用模式改变软件设计DOCWord文件下载.docx(9页珍藏版)》请在冰豆网上搜索。
4.当模型的状态发生改变时,模型会通知与之相关的视图进行更新。
如果用UML来表示MVC设计模式,则如图1所示:
Python与设计模式
尽管设计模式的目标是努力做到与语言的无关性,但事实上许多模式在应用时还是需要依赖于具体实现语言的某些特性,尤其是该语言的对象模型。
由于《设计模式》一书采用的是C++和Smalltalk来讲述设计模式,因此访问控制符和静态成员方法(类方法)等都可以直接使用,可惜的是这些特性在Python中都无法用到,原因是Python采了与C++完全不同的对象模式。
简单说来,Python是一种优秀的面向对象脚本语言,它具有动态语义和快速的原型开发能力,也许在短短的几分钟内,你就可以开发出使用其它语言可能需要花费几个小时的原型系统。
Python丰富的工具集使得它位于传统脚本语言(如Tcl、Perl和Scheme)和系统编程语言(如C、C++和Java)之间,既具备了脚本语言的简单易用性,同时又能够提供只有系统语言才可能拥有的某些高级特性。
从面向对象角度来看,Python和Smalltalk一样都采用了完全的面向对象设计思想,其对象模型能够支持诸如运算符重载、多重继承等高级概念。
但Python在设计时似乎忽略了面向对象的一项基本原则,那就是数据隐藏。
与C++和Java不同,Python没有为类定义提供public、protected和private等关键字,这就意味着任何人都可以直接修改对象的属性。
Python之所以这么做,也许是为了保证语法上的简洁性,就像Python的发明人GuidovanRossum所认为的那样:
"
丰富的语法带来的负担多于帮助"
。
但在某些设计模式中,向外界隐藏数据和方法都是非常必要的,为此我们不得不利用Python对象模型提供的某些高级特性,来实现某种程度上的隐藏性。
在Python中应用设计模式的一个有利因素是它的动态类型绑定,也就是说一个对象很少只是一个类的实例,而是可以在运行时动态改变。
在面向对象系统中,接口是一个基本的组成部分,对象只有通过它们的接口才能与外界进行交互。
对象的接口与其功能是完全分离的,支持相同请求的不同对象针对同一请求所触发的操作可能完全不同,这就是动态绑定的概念。
动态绑定虽然看起来在一定程度上使得代码不同那么容易理解和维护,但它的确可以使整个软件系统的结构显得更加清晰和合理。
作为一门优秀的脚本语言,Python正在被越来越多的人所接受,使用Python开发的项目也越来越多,这也难怪会被大家推崇为"
下一代编程语言"
中的典型代表。
随着应用范围的不断扩展,如何在用Python开发软件时充分利用已有的经验和成果将成为人们关注的焦点,而设计模式作为软件复用的一个重要方面,其价值自然是不言而喻。
可问题是目前所使用的设计模式大都是人们在用Smalltalk、C++和Java开发软件时所总结出来的,因此或多或少地带有这些语言的影子,而要想在Python中使用这些设计模式,必须根据Python的自身特点和实际需要,灵活地加以运用。
Python对象模型
对一门具体的编程语言来说,在应用设计模式时影响最大的莫过于它的对象模型了,这是因为大部分设计模式都源自于C++和Java这类面向对象编程语言。
要想在Python中复用这些设计模式,首先需要对Python的对象模型有一个比较清晰的认识。
1.类
同其它面向对象编程语言一样,Python中的类也是一种用户自定义的数据类型,其基本的语法格式是:
1.class
<
name>
(superclass,
...):
#
定义类
2.
data
=
value
共享的类变量
3.
def
method(self,
类中的方法
4.self.member
实例的数据
类定义从关键字class开始,并包含整个缩进代码块,类中定义的方法和属性构成了类的名字空间(namespace)。
一个类通常会有多个方法,它们都以关键字def开头,并且第一个参数通常都是self,Python中的变量self相当于C++中的关键字this,其作用是传递一个对象的引用。
Python中的类属性位于类的名字空间中,可以被所有的类实例所共享,这一点同C++和Java相同。
访问类属性时不需要事先创建类的实例,直接使用类名就可以了。
例如:
1.>
>
class
Friend:
2.default_age
20
3.>
Friend.default_age
4.20
除了自定义的类属性外,Python中的每个类其实都具有一些特殊的类属性,它们都是由Python的对象模型所提供的。
表1列出了这些类属性:
2.实例
定义类的目的是为了创建它的实例,从面向对象的角度看,类是对数据及其相关操作的封装,而类实例则是对现实生活中某个实体的抽象。
假设定义了如下一个类:
School:
__init__(self,
name):
self.name
name
4.
self.students
[]
5.
addStudent(self,
student):
6.
self.students.append(student)
要创建School类的一个实例,可以执行下面的语句:
1.bit
School("
Beijing
Institute
of
Technology"
)
在C++和Java中创建类实例时,与类具有相同名称的构造函数被调用,而在Python中创建一个类的实例时,将调用名为__init__的特殊方法。
Python中的类实例继承了类的所有方法和属性,并且有自己独立的名字空间,使用下面的方法可以访问类实例的方法和属性:
1.bit.addStudent("
gary"
)
2.bit.students
Python中的对象属性有一个非常有趣的地方,那就是使用它们之前不用像C++和Java那样,必须先在类中进行声明,因为这些都是可以动态创建的。
作为一门动态类型语言,Python的这一特性的确非常灵活,但有时也难免产生问题。
例如在许多针对接口的设计模式中,通常都需要知道对象所属的类,以便能够调用不同的实现方法,这些在C++和Java这些强类型语言的对象模型中不难实现,但对Python来讲可就不那么简单了,因为Python中的每个变量事实上都没有固定的类型。
为了解决这一问题,Python的__builtin__模块提供了两个非常实用的内建函数:
isinstance()和issubclass()。
其中函数isinstance()用于测试一个对象是否是某个类的实例,如果是的话则返回1否则返回0。
其基本的语法格式是:
1.isinstance
(instance_object,
class_object)
Test:
2.pass
inst
Test()
4.>
isinstance(inst,
Test)
5.1
而函数issubclass()则用于测试一个类是否是另一个类的子类,如果是的话则返回1,否则返回0。
1.issubclass(classobj1,
classobj2)
TestA:
pass
TestB(TestA):
5.>
issubclass(TestA,
TestB)
6.0
7.>
issubclass(TestB,
TestA)
8.1
和类一样,Python中的每个类实例也具有一些特殊的属性,它们都是由Python的对象模型所提供的。
表2列出了这些属性:
3.继承
在面向对象的程序设计中,继承(Inheritance)允许子类从父类那里获得属性和方法,同时子类可以添加或者重载其父类中的任何方法。
在Python中定义继承类的语法格式是:
superclass,
...)
2.suit
例如,对于下面这个类:
Employee:
name,
salary
0):
self.salary
salary
raisesalary(self,
percent):
selfself.salary
*
(1
+
percent)
7.
work(self):
8.
self.name,
writes
computer
code"
可以为其定义如下的子类:
Designer(Employee):
Employee.__init__(self,
5000)
design
document"
在C++和Java的对象模型中,子类的构造函数会自动调用父类的构造函数,但在Python中却不是这样,你必须在子类中显示调用父类的构造函数,这就是为什么在Designer.__init__方法中必须调用Employee.__init__方法的原因。
人们对多重继承的看法一直褒贬不一,C++对象模型允许多重继承,而Java对象模型则是通过接口(Interface)来间接实现多重继承的。
在对多重继承的处理上,Python采用了和C++类似的方法,即允许多重继承,例如:
A:
3.class
B(A):
5.class
C:
7.class
D(B,
C):
pass
4.多态
严格说来,像C++和Java这些强类型语言对象模型中的多态概念并不适用于Python,因为Python没有提供类型声明机制。
但由于Python本身是一种动态类型语言,允许将任意值赋给任何一个变量,如果我们对多态的概念稍加扩充,将其理解为具有能同时处理多种数据类型的函数或方法,那么Python对象模型实际上也支持经过弱化后的多态。
Python直到代码运行之时才去决定一个变量所属的类型,这一特性称为运行时绑定(runtimebinding)。
Python解析器内部虽然也对变量进行类型分配,但却十分模糊,并且只有在真正使用它们时才隐式地分配类型。
例如,如果程序调用abs(num),则除数字之外的任何类型对变量num都没有意义,此时变量num事实上就进行了非正式的类型分配。
能够处理不同抽象层次的对象,是面向对象编程最重要的特性之一,也是Python的一个非常重要的组成部分。
下面的例子示范了如何让Python中的一个函数能够同时处理多种类型的数据,在C++的对象模型中,这种多态被称为方法重载。
Polymorph:
deal_int(self,
arg):
'
%d
is
an
integer'
%
arg
deal_str(self,
%s
a
string'
deal(self,
if
type(arg)
==
type
(1):
8.self.deal_int(arg)
9.
elif
type('
):
10.self.deal_str(arg)
11.
else:
12.print
not
integer
or
arg
这样,Polymorph类中的方法deal就可以同时处理数字和字符串了:
p
Polymorph()
2.>
p.deal(100)
3.100
integer
p.deal("
Hello
World!
5.Hello
string
可见性
Python对象模型对可见性的处理与C++和Java完全不同。
在C++和Java中,如果属性或者方法被声明为private,那就意味着它们只能在类中被访问,而如果被声明为protected,则只有该类或者其子类中的代码能够访问这些属性和方法。
但在Python对象模型中,所有属性和方法都是public的,也就是说数据没有做相应的保护,你可以在任何地方对它们进行任意的修改。
能够对可见性进行约束是面向对象编程的一个重要特点,其目的是使对象具有优良的封装性:
对象仅仅向外界提供访问接口,而内部实现细节则被很好地隐藏起来。
奇怪的是作为一门面向对象脚本语言,Python并没有提供对可见性进行约束的机制,所有属性和方法对任何人都是可见的,任何人想知道对象的内部实现细节都是可能的。
虽然这样做能够带来部分效率上的优化,但却无法阻止其它程序员对已经封装好的类进行破坏,从某种程度上这不得不说是Python带给我们的一丝的缺憾。
直到Python1.5,Guido才引入了名字压缩(namemangling)的概念,使得类中的一些属性得以局部化。
在进行定义类时,如果一个属性的名称是以两个下划线开始,同时又不是以下划线结束的,那么它在编译时将自动地被改写为类名加上属性名。
Greeting:
2.__data
3.def
str):
4.Greeting.__data
str
g
Greeting("
Gary!
6.>
dir
(g)
7.['
_Greeting__data'
__doc__'
__init__'
__module__'
]
从上面的显示结果可以看出,Greeting类的属性__data变成了_Greeting__data。
虽然这样仍然无法阻止外界对它的访问,但的确使得访问变得不再那么直接了,从而在一定程序上保护了类中的数据不被外界破坏。
在Python中应用设计模式
◆创建型模式描述怎样创建一个对象,以及如何隐藏对象创建的细节,从而使得程序代码不依赖于具体的对象,这样在增加一个新的对象时对代码的改动非常小。
◆结构型模式描述类和对象之间如何进行有效的组织,形成良好的软件体系结构,主要的方法是使用继承关系来组织各个类。
◆行为型模式描述类或对象之间如何交互以及如何分配职责,实际上它所牵涉的不仅仅是类或对象的设计模式,还有它们之间的通讯模式。
这些设计模式如果能够在Python中直接应用的话,对所有Python程序员来讲毫无疑问将是一笔非常宝贵的财富,因为它们的正确性和有效性已经被无数次的实践所验证过了。
如果想在Python中灵活地运行这些设计模式,可以遵循下面的几个步骤:
(1)接受设计模式
(2)识别设计模式
(3)运用设计模式
首先,你应该认识到设计模式的确能够改善你所设计的软件。
其次,你必须仔细研究每一种设计模式,学习如何在Python中应用这些模式,以便在今后需要时能够用到它们。
最后,你要努力做到对各个设计模式都有非常清晰的认识,最好能够形成自己的独到见解,清楚哪个模式能够解决哪个设计上的问题,并将它们真正应用到你用Python开发的软件中去。
所有的设计模式都来源于实践,最终也将付诸于实践,只有通过实践中你才可能掌握每个模式的精髓所在。
小结
设计模式就是解决软件开发和设计过程中某个特定问题的特定方法,它最初起源于建筑设计,目前已经被广泛地应用在软件开发领域中。
设计模式是软件复用的一种特定形式,理论上它与具体的语言无关,但实际应用时通常会依赖于语言所提供的某些特性。
Python是一门优秀的面向对象脚本语言,它的对象模型会影响到部分设计模式的实现。
设计模式按其目的可以被划分成不同的种类,分别用于解决不同方面的实际问题。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Python 设计 模式 改变 软件设计 DOC