我跟几个人谈到过我这个标签系统。
标签系统,tagging,在 web 2.0 时代大行其道,特别是 del.icio.us 大量应用而广受关注。但如今,随着 del.icio.us 的消逝鲜有人关注了。
但,标签系统是一个极具扩展力的系统,作为一种“元数据”信息,可应用的场景其实非常多样化。因为开展了开发外包业务,接触了几个需求以后,愈加觉得如此。比如有如下需求:
有一个订餐系统,类似“饿了么”,店家增加菜品麻婆豆腐,希望它加入“周二半价”活动,后来活动又多了一个“满10减1”。考虑到活动可能常常增加、变动,那么如何设计方案?
也许你不信,其实 tagging 可以很好地解决这一类问题,额,确切来说是加上装修器模式。
当界面显示某一菜品时,显示的信息其实与从数据库中取得的初始数据不同,比如对于每一道菜:
tag_decorators = [...] #init tag decorators
def tuesday_promote(menu_item):
if menu_item.has_tag('周二半价') and today_is_tuesday():
menu_item.price *= 0.5
tag_decorators.append(tuesday_promote)
menu = get_menu_from_db(...)
for item in menu:
for deco in tag_decorators:
deco(item)
render_html(menu)
如上可见,当“麻婆豆腐”遇上星期二时,它的价格就会打五折。相对于给每一个菜品表增加一个“周二半价”的字段,使用 tagging 让整个系统更加简洁。
在实现时,每一个 tag 和它所对应的 decorator 完全可以存储在数据库中,在后台新增加一个 tag 时,可以绑定相对应的 decorator,甚至 decorator 的某些参数,就可以实现不需要编程即可变更业务逻辑的目的。
在真正的业务代码中,肯定不会出现 menu_item.price *= 0.5
这种代码,每一个 decorator 的作用都要记录下来,应该会把 menu_item 作一个包装。
另外,把 decorator 放在数据读取层中会更加好,这样业务层的代码可以把标签系统当透明,程序员写起代码来完全没有心智负担。