Python实现设计模式--05.建造者模式(Builder Pattern)
2017-08-03 23:14
726 查看
建造者模式是一种创建类的模式,它尽可能的保证代码的复用性,而且可读性也非常好(最终产生对象的过程对调用方是透明的)。
很多朋友应该都做过微信公众号或者支付宝服务窗的消息推送,下面是微信公众平台给的消息示例:
具体参数可在公众平台开发者文档查看。现在的问题是如何设计消息模版呢?我身边有的同事是用字符串替换,有的对各个模版建立一个类,这里我不往深里讨论方案对优劣,本节结束后读者们可以尝试做下对比。下面我给出一种建造者模式对做法,创建builder类如下(简便起见,去掉了miniprogram参数):
建造者内部的字典采用OrderedDict,是为了保持顺序与微信示例一致
建造者每个方法都返回了本对象的引用,这是一个很常用的技巧
建造者有了,下面我们来生成两条消息。前几天我在丰巢快递柜寄了票件,下图是我收到的其中两个微信通知:
我们模拟作如上两条微信消息:
本人经验,这类情形下,建造者模式使得代码更加清晰易懂,读者有没有一点点启发呢?
很多朋友应该都做过微信公众号或者支付宝服务窗的消息推送,下面是微信公众平台给的消息示例:
{ "touser":"OPENID", "template_id":"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY", "url":"http://weixin.qq.com/download", "miniprogram":{ "appid":"xiaochengxuappid12345", "pagepath":"index?foo=bar" }, "data":{ "first":{ "value":"恭喜你购买成功!", "color":"#173177" }, "keynote1":{ "value":"巧克力", "color":"#173177" }, "keynote2":{ "value":"39.8元", "color":"#173177" }, "keynote3":{ "value":"2014年9月22日", "color":"#173177" }, "remark":{ "value":"欢迎再次购买!", "color":"#173177" } } }
具体参数可在公众平台开发者文档查看。现在的问题是如何设计消息模版呢?我身边有的同事是用字符串替换,有的对各个模版建立一个类,这里我不往深里讨论方案对优劣,本节结束后读者们可以尝试做下对比。下面我给出一种建造者模式对做法,创建builder类如下(简便起见,去掉了miniprogram参数):
# -*- coding: utf-8 -*- from collections import OrderedDict import json # 模版中“data”节点的各个元素的数据结构 class Metadata: def __init__(self, value, color): self.value = value self.color = color # 微信消息的建造器 class MessageBuilder: __contentDict = OrderedDict() # 定义整个模版的数据结构,保持添加的顺序 __dataDict = OrderedDict() # 定义data节点的数据结构,保持添加的顺序 __dataNoteNext = 1 # data节点要添加的下一个元素的序号 def __init__(self, touser, template_id, url): self.__contentDict['touser'] = touser self.__contentDict['template_id'] = template_id self.__contentDict['url'] = url self.__contentDict['data'] = self.__dataDict def add_first_data(self, value, color): data = Metadata(value, color) self.__dataDict['first'] = data return self def add_remark_data(self, value, color): data = Metadata(value, color) self.__dataDict['remark'] = data return self def add_note_data(self, value, color): data = Metadata(value, color) self.__dataDict['keynote' + str(self.__dataNoteNext)] = data self.__dataNoteNext += 1 return self def build(self): # 为打印出来看的方便,这里将json序列化后的结果缩进2个空格,并且不把中文转为unicode return json.dumps(self.__contentDict, default=lambda o: o.__dict__, indent=2, ensure_ascii=False)有两点要说明下:
建造者内部的字典采用OrderedDict,是为了保持顺序与微信示例一致
建造者每个方法都返回了本对象的引用,这是一个很常用的技巧
建造者有了,下面我们来生成两条消息。前几天我在丰巢快递柜寄了票件,下图是我收到的其中两个微信通知:
我们模拟作如上两条微信消息:
if __name__ == '__main__': order_builder = MessageBuilder('user111111', 'template_id_order', '') \ .add_first_data('您的寄件订单已经生成啦!请打包好您的包裹前往柜机投递。', '#173177') \ .add_note_data('03226580', '#173177') \ .add_note_data('10(小格);14(中格);18(大格);', '#173177') \ .add_note_data('顺丰速运', '#173177') \ .add_remark_data('“一分钱寄全国”优惠券以放入到你的账户,在柜机支付时记得使用哦。', '#173177') print('生成下单通知微信消息') print(order_builder.build()) print() send_builder = MessageBuilder('user222222', 'template_id_send', 'http://balabala') \ .add_first_data('丰巢已收到您的包裹,并已通知快递员来收取啦!', '#173177') \ .add_note_data('顺丰速运', '#173177') \ .add_note_data('422154541545', '#173177') \ .add_note_data('某地址某地址某地址某地址', '#173177') \ .add_note_data('2017-07-31 11:20', '#173177') \ .add_remark_data('点击详情查看物流进度', '#173177') print('生成投递微信消息') print(send_builder.build())运行结果:
生成下单通知微信消息 { "touser": "user111111", "template_id": "template_id_order", "url": "", "data": { "first": { "color": "#173177", "value": "您的寄件订单已经生成啦!请打包好您的包裹前往柜机投递。" }, "keynote1": { "color": "#173177", "value": "03226580" }, "keynote2": { "color": "#173177", "value": "10(小格);14(中格);18(大格);" }, "keynote3": { "color": "#173177", "value": "顺丰速运" }, "remark": { "color": "#173177", "value": "“一分钱寄全国”优惠券以放入到你的账户,在柜机支付时记得使用哦。" } } } 生成投递微信消息 { "touser": "user222222", "template_id": "template_id_send", "url": "http://balabala", "data": { "first": { "color": "#173177", "value": "丰巢已收到您的包裹,并已通知快递员来收取啦!" }, "keynote1": { "color": "#173177", "value": "顺丰速运" }, "keynote2": { "color": "#173177", "value": "422154541545" }, "keynote3": { "color": "#173177", "value": "某地址某地址某地址某地址" }, "remark": { "color": "#173177", "value": "点击详情查看物流进度" }, "keynote4": { "color": "#173177", "value": "2017-07-31 11:20" } } }
本人经验,这类情形下,建造者模式使得代码更加清晰易懂,读者有没有一点点启发呢?
相关文章推荐
- 我所理解的设计模式(C++实现)——建造者模式(Builder Pattern)
- 我所理解的设计模式(C++实现)——建造者模式(Builder Pattern)
- 我所理解的设计模式(C++实现)——建造者模式(Builder Pattern)
- 我所理解的设计模式(C++实现)——建造者模式(Builder Pattern)
- 设计模式----建造者模式(Builder Pattern)
- 设计模式-建造者模式(Builder Pattern)
- 乐在其中设计模式(C#) - 建造者模式(Builder Pattern)
- 乐在其中设计模式(C#) - 建造者模式(Builder Pattern)
- 设计模式之—建造者模式(Builder)-Java实现
- 设计模式——建造者模式(Builder Pattern)
- 设计模式学习总结-建造者模式(Builder Pattern)
- .NET设计模式-建造者模式(Builder Pattern)
- 设计模式学习笔记——建造者模式(Builder Pattern)
- 设计模式---建造者模式(Builder Pattern)
- 六.创建型设计模式——Builder Pattern(建造者模式)
- Head First 设计模式——观察者模式(Observer Pattern)——Python实现(3)
- 设计模式---建造者模式(Builder Pattern)
- NET设计模式4--建造者模式(Builder Pattern)
- 设计模式系列之03-建造者模式(Builder Pattern)
- Head First 设计模式——装饰器(Decorator Pattern)——Python实现