www.shuxiaolong.com 网站已经升级, 最新网址 请关注 www.ink1989.com
架构师成长之路

『设计』用马肆卖马 浅谈 特性+接口 的插件扩展设计

2013-10-25  (1/2698) ShuXiaolong

 

设计动机:

  • 很多时候,我们开发一个程序,程序功能越多,会发现代码也越多;比方说一个WinForm 程序,一个页面甚至超过5000行代码 —— 这为后期的维护,带来了极大的麻烦:你寻找需要修改的代码 可能就需要 5分钟;修改一个函数,可能还会引入新的BUG(因为这个函数被其他地方调用了)
  • 还有一种程序,我们希望 普通版功能少一点,旗舰版功能多一点——于是,我们可以通过配置等方式,让普通版的很多功能不展示出来。但这样的弊端就是:软件被人破解之后,普通版就变成了旗舰版;
  • 对于已经交付的项目,客户要添加功能;于是,我们可以 重新修改代码,重新编译 给客户再发送一份。办公室的理想主义代码 和 客户现场的实际环境 可能导致的BUG,可能还得多跑一趟客户现场予以解决。

 

设计目的:

  • 能不能有一种设计,让各种功能 拆分到 各自的类文件中,而不是混合放在一个 类文件中;
  • 能不能有一种程序,失去其中部分个程序集之后,只是削弱程序功能,而不是 程序崩溃——以此在物理上,区分 普通版 和 旗舰版;
  • 能不能有一种维护,新的功能 或者 修改的功能,只需要 新写代码,对之前已经稳定的代码 不做任何 修改,编译的程序集,发送给客户,就能 增加功能 或 覆盖现有功能,且不破坏 之前的稳定。

 

设计实现:

基于上面的设计初衷,于是就有了 本篇文章。本篇文章 是 作者众多的插件项目经验,最终 稳定 而成。

 

打个比方:

比方说 京城有一个 马肆,任何想买马的人 都可以来这里买马;但是马 也有自己的特性,只愿意 特定的人 骑乘;

  • 普通马 不挑剔,任何主人 都愿意;
  • 五花马 只挑选 有才华人的人 当主人;
  • 赤兔马 只挑选 力大,威望高的人 当主人;
  • 的卢马 只挑选 命脆,威望高的人 当主人;
  • 红鬃烈马 只挑选 薛仁贵 当主人;

这些马,按照分类 有各自 的 伯乐管理;

客人到了 马肆,客人告知一下 自己的特征;几位伯乐就会 推荐自己管理的马;

 

张三来买马,只有 普通伯乐 推荐自己的马;

李白来买马,普通伯乐,五花马伯乐 推荐自己的马;

薛仁贵买马,普通伯乐,赤兔马伯乐,红鬃烈马伯乐 推荐自己的马;

刘备买马,普通伯乐,的卢马伯乐 推荐自己的马;

庞统买马,普通伯乐,五花马伯乐,的卢马伯乐 推荐自己的马;

 

背后的设计考量:

  • 上面的马肆,如果用 工厂模式:客人告知想要什么马,就给什么马 —— 这违背的马的初衷;
  • 这里 客人挑马,马也挑客;
  • 如果给马 添加一个“挑客方法”—— 也是可行,但不科学:因为前提是得有马;
  • 那就得先创建马,再判断是否符合条件 —— 不符合条件,这个马对象就多余创建,空占内存了!
  • 当然,如果这些马都是单例的话,那么就 另当别论:即使多也只多一个,占不了多少内存;
  • 或者,你思路清晰的话,你可以写一个 对象池:将多余创建的无用对象 再次使用;
  • 而本文的思想是:将“挑客”这个方法 交给 伯乐 —— 伯乐知道客人适合什么马,他可能手上没有马,但是只要客人选定了,他再创建马的对象;(创建的对象都是有用的对象)

 

设计解释:

这里管理各种马的不同伯乐,将会成为本设计的 特性类;

而各种马 还是按照 继承关系设计,只是标记一下管理自己的伯乐——即标记所需的特性;

 

Demo代码:

Demo等有时间再写,现在没有时间哈;

 

基于本文思想的项目展示:

 

  • 针对不同的 子窗体,创建不同的 工具栏选项;
  • 其中 “所有按钮”——就相当于 比方中的普通马:任何类型的窗体都会出现;
  • 其他的按钮,当然也是扩展的插件——支持 同名插件按照优先级覆盖(这个当然也是 特性类的属性,而和 具体插件 主要办的事情无关);
  • 当然,这个界面中的 子窗体,也是 相似设计的插件扩展;
  • 当然,那个 “插件执行”的下拉列表 也是 相似设计的插件扩展;
评论回复
共有:1 条评论信息
程序诗人 [123.7.*.140]  2014-03-18 13:20:51 评论道:
写的不错,插件式开发是很主流的一种做法。我看NopCommerce这套电子商务源码,采用的就是插件式开发,方便易用。

发表评论

点击刷新