今天老板说要做一个模拟鸭子应用。
1.从简单鸭子应用做起
设计如下图
此系统内部设计使用了标准的OO技术,设计一个鸭子超类,让各种鸭子继承此超类,老板给我的今天任务搞定了。
2.现在老板要让鸭子能飞
这不简单吗?我给Duck类加上fly()就可以了,托托的。
红鸭绿鸭都会飞了
老板:“你TM逗我?我要一只橡皮鸭竟然能飞?我要的绿头鸭叫声一定是呱呱叫的?不能是吱吱叫?我要一只诱饵鸭你给我会飞又会叫?“
好吧,我改吧。。。
这也不难啊,我把橡皮鸭和诱饵鸭继承的方法覆盖一下不就完了。
哎,终于可以吃午饭了,我擦,NTM都两点了。。。
吃午饭中.....万一老板又给我弄几种鸭出来,我岂不是要每次覆盖fly()和quack(),这还让我活吗?不行得改进一下设计。
继承缺点:当你改动父鸭类的时候,其他鸭子被迫变化。运行时行为不能改变父鸭类继承来的方法。
修改一下午后
我把quack()和fly()抽出来,放进接口里,你要飞要实现飞接口,要叫就实现叫接口,哈哈,我这是要超神的节奏啊。
设计原则:找出应用中可能需要变化之处,把他们独立出来,不要和那些不需要变化的代码搞在一起。
主要上面“可能”一词,俗话说方法防范于未然,最好能在之前就有所觉察。
Duck类的fly()和quack()都会随着鸭子改变而改变,所以要把他们从Duck里取出来建立新类。
老板:“接口这里的想法还算过得去,但是你看看你这一来,我实现了接口之后,你还不是要帮我每次重写每种鸭子的方法?再想想吧,骚年。”
额。。。
java接口不支持实现代码,继承接口无法达到代码复用。
OT中。。。
不能复用?这么坑爹,咦,复用?我把接口用一个类先继承实现好,之后这个类被需要的继承,代码不就可以复用了吗?
code。。。
复用?so easy,这两个接口这样设计,有了继承复用的好处,又没有继承带来的包袱,我很是佩服我自己。。
设计原则:真的接口编程,而不是针对实现编程。
老板:“嗯,这东西还像个样子,我想要动态指定鸭子动作呢?你能完成?”
我想想。。。
Duck超类里添加接口类型的引用变量和两个set函数
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
setFlyBehavior(FlyBehavior fb) {flyBehavior = fb;}
setQuackBehavior(QuackBehavior qb) {quackBehavior = qb;}
这也我要哪个行为new哪个具有这个行为的对象传给set方法, 就是动态指定了,哇哈哈,我是多碉堡的存在啊。。
设计原则:多于组合,少用继承
上面得叫和飞行为都已经是委托给别人代理了,现在鸭子行为不是继承来的,是和行为对象组合来的
老板:"哎,现在的年轻人,搞技术的越来越不行,搞个小东西要我等这么久,相当年,这么一个东西我一个盒饭的时间就搞定了"
纳尼。。。
上面所讲的就是传说中的策略模式,讲了几个设计的原则,很重要,好好体会.
给个官方点的定义。。
策略模式:定义了算法族,分别封装起来,让他们直接可以相互替代,此模式让算法变换独立与使用算法的客户.
好,先写到这里,需要更详细的了解的话可以参考Head First的设计模式第一章,里面有贴出最终源码。