其实最好的办法是让自己保持神秘,尽量少的公开自己的信息,使民无知。
好的软件设计追求的就是这种境界。
这里的“民”指得就是“客户”。尽量少的公开接口,给客户一个“瘦”接口,使客户不知道具体是如何操作的,这样于人于己都是有好处的。
我还是用排序算法的例子。我们的目标是把排序算法通过动态库的形式提供给用户。
在这里用了一个简单的策略模式。用户调用函数的目的是把给定的链表排序,他关心的是速度,而不是排序算法。代码如下:
CSort* pSort = new CBubbleSort;
pSort->Sort(pList);
这样我们要给用户提供些什么呢?
答:Sort.lib, Sort.Dll, Sort.h, BubbleSort.h
用户知道了哪些信息呢?
答:知道排序库当前提供的是冒泡排序算法。(当然你要把BubbleSort.h乱命名我也没有办法了,但这不是我们所提倡的。)
用户会提什么需求?
答:可能Shell排序算法性能会更好些。
然后你要干什么?
答:重新考虑Shell排序算法。
我们不能被用户牵着鼻子走,我们要保护自己,让用户知道的越少越好,隐藏自己的具体信息。切入到正题了,那么我们如何隐藏信息呢?
隐藏方法第一招:工厂模式
工厂是什么?说简单点,工厂就是生产一些产品的地方,至于如何生产产品,用户根本就不关心产品是如何生产的。就说当前的很多饭店,卫生不过关,但端出来的饭菜还是很好的,顾客关心的是饭菜,至于在什么环境下烧出来的,就不都而知了。
在这里我把排序算法的创建过程用简单工厂进行封装,UML图如下:
代码如下:
CSort* pSort = SortFactory();
pSort->Sort(pList);
现在我们再来提一遍相同的问题。
这样我们要给用户提供些什么呢?
答:Sort.lib, Sort.Dll, Sort.h, SortFactory.h
用户知道了哪些信息呢?
答:不知道用什么排序算法。
用户会提什么需求?
答:如果性能还过的去,提需求的可能性降低。
然后你要干什么?
答:没有需求,就做你自己的事。
如果我改变排序的算法,用户知道吗?回答是肯定的,不知道,用户也无需做任何事情,哪怕重新编译的工作都不用做,因为接口函数没有变。
隐藏方法第二招:代理模式
代理对大家来说都不陌生,说简单点就是花钱请人替你干活的机构。比如房屋中介,你要租房,中介替你一手搞定,至于如何搞定的,顾客不知道。
看代理模式是如何隐藏信息的:
客户端调用代码如下:
CSort pSort = CSortProxy;
pSort->Sort(pList);
试着问问上面同样的问题,都到的答案也基本相同。如果要替换排序算法,只要修改CSortProxy类中的Sort函数即可,对客户端毫无影响。
好处在哪里呢?
我想也不必我详细地说明了,上面的论述已经很明确的体现了好处所在。我只简单地总结一下:
1. 使自己处于主动的地位。
2. 使民无知,堵住用户的嘴。知道的越少,提的需求也越少。
3. 扩展性好。只要接口不变,我想怎么改就怎么改。
需要你的支持
毕竟个人的知识是有限的,可能还有更好的方法。如果你想到了好的方法,请和我分享,我会加入到文章中。