开闭原则
开:对扩展开放
闭:对修改关闭
对象增强方式
一般来说实现对象增强的方式有3种:
- 继承
- 代理
- 装饰器
装饰器模式
函数装饰
#include <iostream>
#include <functional>
using namespace std;
template <typename R, typename... Args>
struct Logger3
{
Logger3(function<R(Args...)> func) : func_(func)
{
}
R operator()(Args... args)
{
cout << "start" << endl;
R result = func_(args...);
cout << "end" << endl;
return result;
}
function<R(Args...)> func_;
};
template <typename R, typename... Args>
auto make_logger3(R (*func)(Args...))
{
return Logger3<R, Args...>(std::function<R(Args...)>(func));
}
double add(double a, double b)
{
return a + b;
}
long my_abs(int a)
{
return a > 0 ? a : -a;
}
int main()
{
auto caller = make_logger3(add);
auto result = caller(2.1, 3.2);
cout << result << endl;
auto caller2 = make_logger3(my_abs);
auto result2 = caller2(-100);
cout << result2 << endl;
}
python 装饰器
装饰器本质是个python函数,是由闭包支持。
- 常规写法
@decorator
def func(*args, **kwargs):
do_something()
- 应用
-
函数执行时间统计
import time def calculate_function_run_time(func): def call_fun(*args, **kwargs): start_time = time.time() f = func(*args, **kwargs) end_time = time.time() print('{0} run time:{1} ms'.format(func.__name__, 1000 * int(end_time - start_time))) return f return call_fun @calculate_function_run_time def test1(): for i in range(100000000): i = i + 1 if __name__ == "__main__": test1()
引入日志
执行函数前的预备处理
执行函数后的清理功能
-
权限校验
user_list = [ {'name': 'sb1', 'passwd': '123'}, {'name': 'sb2', 'passwd': '123'}, {'name': 'sb3', 'passwd': '123'}, {'name': 'sb4', 'passwd': '123'}] client_dic = {'username': None, 'login': False} def auth_func(func): def wrapper(*args, **kwargs): if client_dic['username'] and client_dic['login']: res = func(*args, **kwargs) return res user_name = 'sb1' password = '123' # 对比列表, 检查用户名和密码是否正确 for user_dic in user_list: if user_name == user_dic['name'] and password == user_dic['passwd']: client_dic['username'] = user_dic['name'] client_dic['login'] = True res = func(*args, **kwargs) return res else: print('用户名或者密码错误!') return wrapper @auth_func def index(): print("欢迎来到主页") @auth_func def home(name): print("欢迎回家:%s" % name) if __name__ == '__main__': index() home('sb1')
缓存
事物处理
-
Java IO流中的装饰器
和代理模式的异同
两者都是对类的方法进行扩展,但装饰器模式强调的是增强自身,在被装饰之后nenggo
参考资料
- https://www.jianshu.com/p/d80b6b4b76fc
- https://blog.csdn.net/qq_33531400/article/details/79324551
- https://mp.weixin.qq.com/s?__biz=Mzg5ODAwODM0Mg%3D%3D&mid=2247483679&idx=1&sn=0469fc64b030ad57660294bba1a1c453&chksm=c0685566f71fdc7059d6f92ecc82097d8a556c7e8d97c3a5a5e6b3b6bcc1e08735a17d828343&token=1492230032&lang=zh_CN