Python 的 Decorator 在使用上和 Java 的 Annotation(以及 C# 的 Attribute)很相似,就是在方法名前面加一个 @XXX 注解来为这个方法装饰一些东西。但是,Java/C# 的 Annotation 也很让人望而却步,太过于复杂了。你要玩它,需要先了解一堆 Annotation 的类库文档,感觉几乎就是在学另外一门语言。
而 Python 使用了一种相对于 Decorator Pattern 和 Annotation 来说非常优雅的方法,这种方法不需要你去掌握什么复杂的 OO 模型或是 Annotation 的各种类库规定,完全就是语言层面的玩法:一种函数式编程的技巧。
def hello(fn):
def wrapper():
print("hello, %s" % fn.__name__)
fn()
print("bye, %s" % fn.__name__)
return wrapper
@hello
def Hao():
print("i am Liu Mr")
Hao()
代码的执行结果如下:
hello, Hao i am Liu Mr bye, Hao
对于 Python 的这个 @注解语法糖(Syntactic sugar)来说,当你在用某个 @decorator 来修饰某个函数 func 时,如下所示:
@decorator
def func():
print("hello world")
其解释器会解释成下面这样的语句:
func = decorator(func)
就是把一个函数当参数传到另一个函数中,然后再回调。但是,我们需要注意,那里还有一个赋值语句,把 decorator 这个函数的返回值赋值回了原来的 func。
Python 有语法糖,所以写出来的代码比较酷。但是对于没有修饰器语法糖Go语言,写出来的代码会是怎么样呢?
package main
import "fmt"
func decorator(f func(s string)) func(s string) {
return func(s string) {
fmt.Println("Started")
f(s)
fmt.Println("Done")
}
}
func Hello(s string) {
fmt.Println(s)
}
func main() {
hello := decorator(Hello)
hello("Hello World!!!")
}
Golang动用了一个高阶函数 decorator(),在调用的时候,先把 Hello() 函数传进去,然后其返回一个匿名函数。这个匿名函数中除了运行自己的代码,也调用了被传入的 Hello() 函数。
通过Python 和 Go 修饰器的例子,修饰器模式主要做了下面的几件事。
函数式编程总结起来就是把一些功能或逻辑代码通过函数拼装方式来组织的玩法。这其中涉及最多的是函数,也就是编程中的代码逻辑。但我们知道,代码中还是需要处理数据的,这些就是所谓的“状态”,函数式编程需要我们写出无状态的代码。
对于状态和数据的处理,我们有必要提一下“面向对象编程”(Object-oriented programming,OOP)这个编程范式了。我们知道,面向对象的编程有三大特性:封装、继承和多态。
面向对象编程是一种具有对象概念的程序编程范型,同时也是一种程序开发的抽象思想,它包含属性与方法。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的可重用性、灵活性和可扩展性,对象里的程序可以访问及修改对象相关联的数据。
说起面向对象,就不得不提由 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides 合作出版的《设计模式:可复用面向对象软件的基础》(Design Patterns – Elements of Reusable Object-Oriented Software)一书,在此书中共收录了 23 种设计模式。
“Program to an ‘interface’, not an ‘implementation’.”
“Favor ‘object composition’ over ‘class inheritance'”
IoC的概念已经提出来很多年了,其被用于一种面向对象的设计IoC/DIP(控制反转/依赖倒置)。控制反转和面向接口编程其实如出一辙,就是把以前底层强依赖于实现的方式,变成了底层提供接口和规范,调用方依赖接口就可以。
生活例子也有很多,比如说:
在我们工作中,经常会在标准化和定制化中纠结,我们痛苦于哪些应该是平台要做的,哪些应该要丢出去。这里就会出现很多与业务无关的软件或中间件,包括协议、数据、接口…,基于面向对象的方式,我们可以通过抽象、中间件来解耦,来降低软件的复杂度。
优点:
缺点:
Java里很多注入方式,像Spring那些注入、鼓励黏合,导致了大量的封装,完全不知道里面在干什么事情。而且封装屏蔽了细节,具体发生啥事你根本不知道。这些都是面向对象不太好的地方。
如果您发现该资源为电子书等存在侵权的资源或对该资源描述不正确等,可点击“私信”按钮向作者进行反馈;如作者无回复可进行平台仲裁,我们会在第一时间进行处理!
添加我为好友,拉您入交流群!
请使用微信扫一扫!