1. 意图
-
动态地 向一个现有的对象添加新的功能,同时又不改变其结构。
-
我们为了扩展一个类经常使用继承方式实现。由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。
2. 设计图
3. 设计分析(对照以上UML类图)
4. 应用场景
5. 代码展示
用python实现,python除了可以用常规的实现方式外(与其它语言如java的实现一致),python自身在语法上直接支持装饰器decorator
5.1 以log输出为例
- 用函数来实现Log装饰器
def log1(strlog):
def decorator(fn):
@functools.wraps(fn)
def wrapper(*args, **kw):
print(strlog)
print('start %s()' % fn.__name__)
res = fn(*args, **kw)
print('end %s()' % fn.__name__)
return res
return wrapper
return decorator
- 用类来实现Log装饰器
class log2(object):
def __init__(self,strlog):
self.strlog=strlog
def __call__(self, fn):
@functools.wraps(fn)
def wrapper(*args, **kw):
print(self.strlog)
print('start %s()' % fn.__name__)
res = fn(*args, **kw)
print('end %s()' % fn.__name__)
return res
return wrapper
- 如何使用Log装饰器
@log('hello')
def test1():
print('I am function test1')
@log('hello')
def test2():
print('I am function test2')
@log2('hello')
def test3():
print('I am function test3')
def main():
test1()
test2()
test3()
5.2 以ODPS的UDF执行过程为例
- 用函数来模拟实现以上annotate装饰器
def annotate1(str_param):
def decorator(cls):
class wrapper_class():
def __init__(self, *args, **kw):
newcls=cls(*args, **kw)
print(str_param)
newcls.evaluate(*args, **kw)
return wrapper_class
return decorator
- 用类来模拟实现以上annotate装饰器
class annotate2(object):
def __init__(self,str_param):
self.strinfo=str_param
def __call__(self, cls):
strinfo = self.strinfo
class wrapper_class():
def __init__(self, *args, **kw):
newcls=cls(*args, **kw)
print(strinfo)
newcls.evaluate(*args, **kw)
return wrapper_class
- 如何使用以上annotate装饰器
@annotate1('I am param in decorator')
class cls1(object):
def __init__(self):
print('I am class cls1')
def evaluate(self):
print('I am fun evaluate() in cls1')
@annotate2('I am param in decorator')
class cls2(object):
def __init__(self, param1, parma2):
print('I am class cls2')
def evaluate(self, param1, param2):
print('I am fun evaluate() in cls2. param1=%s, param2=%s.'% (param1,param2))
def main():
aa=cls1()
bb=cls2('param1','param2')