- A+
1.1. 前言
前面的文章让我们的程序能轻松的应对业务的变更了。这本该是一件皆大欢喜的事。但是,本系列文章的目的不仅仅在于此,而且还没有满足哪些要少些代码的程序员的要求。
1.2. 请不要来虚
“装饰器模式”想必这对程序员来说并不陌生。基本上问每一个程序员,他们都能回答的头头是道。而且有写面试官肯定在面试的时候回问(这个框架用了什么模式啊。用装饰器有什么好处啊)。
我想说的是,你知道装饰器那么多。你在你的项目中使用了这种模式么(除了使用框架给你分装的)?我想有大半的程序员没有在自己的项目中编写装饰器来使用吧。所以还是恳求,知道就用上吧。
1.3. 目的
本篇文章的目的是使用装饰器来方便和简化我们开发,让我们的业务方法变简单。
1.4. 实现程序
我们使用三个装饰器方法来完成我们的目标:
装饰器方法名 | 用途 |
join_order | 和订单信息进行合并(无论什么数据只要有user_id做关联) |
join_order_good | 和订单商品信息进行合并(无论什么数据只要有order_id做关联) |
join_coupon | 和券信息进行合并(无论什么数据只要有order_id做关联) |
第一步、获取用户信息和获取订单信息进行程序拼凑后返回结果(在装饰器join_order方法中实现)。
第二步、获取订单商品信息并且并和“第一步”获得的结果进行拼凑并返回结果(在装饰器join_order_good方法中实现)。
第三步、获取订单券信息并且和“第二步”获得的结果进行拼凑并返回结果(在装饰器join_coupon方法中实现)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
#!/usr/bin/env python # -*- coding:utf-8 -*- import pandas as pd import mysql.connector import sys import sys reload(sys) sys.setdefaultencoding('utf-8') def get_user_info(user_ids, conn=None): ''' 通过user_id获得用户信息 ''' user_sql = ''' SELECT user_id, name FROM user WHERE user_id = {user_id}; '''.format(user_id = ','.join(user_ids)) user_info = pd.read_sql(user_sql, conn) return user_info def get_order_info(user_ids, conn=None): ''' 通过 用户ID 获得订单信息 ''' order_sql = ''' SELECT user_id, order_id, num FROM orders WHERE user_id = {user_id}; '''.format(user_id = ','.join(user_ids)) order_info = pd.read_sql(order_sql, conn) return order_info def get_order_good_info(order_ids, conn=None): ''' 通过上面获得的 订单ID 获得订单商品信息。 ''' order_good_sql = ''' SELECT order_id, good_name FROM order_good WHERE order_id IN ({ids}); '''.format(ids = ','.join(order_ids)) order_good_info = pd.read_sql(order_good_sql, conn) return order_good_info def get_coupon_info(order_ids, conn=None): ''' 通过 订单ID 获得券信息 ''' coupon_sql = ''' SELECT order_id, name FROM coupon WHERE order_id IN({ids}); '''.format(ids = ','.join(order_ids)) coupon_info = pd.read_sql(coupon_sql, conn) return coupon_info def join_order(func): ''' 添加订单信息 ''' def _join_order(user_id, conn=None): user_info = func(user_id, conn=conn) user_ids = user_info['user_id'].astype(str) order_info = get_order_info(user_ids, conn=conn) new_order = user_info.merge(order_info, left_on='user_id', right_on='user_id', how='left') return new_order return _join_order def join_order_good(func): ''' 添加订单商品信息 ''' def _join_order_good(*args, **kargs): order_info = func(*args, **kargs) order_ids = order_info['order_id'].astype(str) order_good_info = get_order_good_info(order_ids, **kargs) new_order = order_info.merge(order_good_info, left_on='order_id', right_on='order_id', how='left') return new_order return _join_order_good def join_coupon(func): ''' 添加券 ''' def _join_coupon(*args, **kargs): order_info = func(*args, **kargs) order_ids = order_info['order_id'].astype(str) coupon_info = get_coupon_info(order_ids, **kargs) new_order = order_info.merge(coupon_info, left_on='order_id', right_on='order_id', how='left') return new_order return _join_coupon @join_coupon @join_order_good @join_order def get_order_detail(user_id, conn=None): ''' 拼凑获得订单信息 ''' user_ids = [str(user_id)] return get_user_info(user_ids, conn=conn) if __name__ == '__main__': conf = { 'host' : '127.0.0.1', 'port' : '3306', 'database' : 'test', 'user' : 'root', 'password' : 'root' } conn = mysql.connector.connect(**conf) print get_order_detail(10, conn=conn) conn.close() |
输出结果:
1 2 3 4 5 6 7 8 9 10 11 |
user_id name_x order_id num good_name name_y 0 10 HH 1 11111 order_good_1 coupon_1 1 10 HH 1 11111 order_good_2 coupon_1 2 10 HH 2 22222 order_good_3 NaN 3 10 HH 2 22222 order_good_4 NaN 4 10 HH 3 33333 order_good_5 coupon_3 5 10 HH 3 33333 order_good_6 coupon_3 6 10 HH 4 44444 order_good_7 NaN 7 10 HH 4 44444 order_good_8 NaN 8 10 HH 5 55555 order_good_9 coupon_5 9 10 HH 5 55555 order_good_10 coupon_5 |
源代码:use_decorator
现在来看上面的业务方法get_order_detail现在是不是变的简单了?它总共还不到10行代码。较劲的肯定会说你别忽悠我了,你那只是业务代码少了,但是你每增加一个需求你都要添加一个相关的装饰器(如果需求说需要展示订单的门店信息我们就需要创建一个类似join_store的装饰器方法并在业务方法上使用@join_store来实现),你只是把工作量放在了编写装饰器上面,本质上并没有改变。我只能说哎,竟然被你发现了。
我们继续回避代码量这个话题,看看我们代码应变需求的能力。如果需求说我们不需要展示券的信息了。这时我们只需要在get_order_detail方法上将@join_coupon给删除了就好了。这真是太方便了。但是需要增加业务的话可能就需要再次编写一个装饰器(如果是相同条件的就不用了)。
下一篇文章我们就来满足你真正的代码少扩展好的装饰器。
昵称:HH
QQ:275258836
ttlsa群交流沟通(QQ群②:6690706 QQ群③:168085569 QQ群④:415230207(新) 微信公众号:ttlsacom)
感觉本文内容不错,读后有收获?
