刚刚看《Head First 设计模式》,第一章讲了一个故事: 设计师Joe设计了只鸭子,但董事会(难道不是执行经理管这事)要求每六个月改变产品; 于是乎什么飞鸭、烤鸭、机器鸭、橡胶鸭……乱七八招的都来了,而且你还不知道下次是什么变态要求! 怎么办? 关于编程的方法:继承多态都无用,因为下次的代码改动量太大,并且需要改动多处原有代码。 那么怎的办!? 呵呵,在这危机时刻(Joe面临炒鱿鱼的危险),设计模式推出了两条原则:

  • 找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
  • 针对接口编程,而不是针对实现编程。

最后奇迹出现,Joe大放异彩!

需要说的是虽然我的”唐诗宋词“插件也是使用类似于设计模式写的(以后加一个模块最少只要5行代码),但那时看的尚学堂的视频,一知半解,也就那样吧。这是我第一次看编程的书能看到这么晚,而且还把书中例子写成代码,此书可谓“头脑风暴”。~0~| 贴上PHP版的源码(看看CoolCode的极限 ^_^):

  1. < ?php
  2. /**
  3. * 飞行行为接口,
  4. * 只要是飞,都得找它
  5. */
  6. interface FlyBehavior {
  7.     // 飞行行为
  8.     function fly();
  9. } // END inter FlyBehavior
  10.  
  11. /**
  12. * 叫行为接口,
  13. * 不管你是哭爹还是喊娘,还是得找它
  14. */
  15. interface QuackBehavior {
  16.     // 叫行为
  17.     function quack();
  18. } // END inter QuackBehavior
  19.  
  20. /**
  21. * 随风而飞,燕雀怎知鸿鹄之志
  22. */
  23. class FlyWithWings implements FlyBehavior {
  24.     /**
  25.      * @see FlyBehavior::fly()
  26.      *
  27.      */
  28.     function fly() {
  29.         echo "FlyWithWngs<br />";
  30.     }
  31. } // END class FlyWithWings
  32.  
  33. /**
  34. * 根本不会飞,瘟鸡一只
  35. */
  36. class FlyNoWay implements FlyBehavior {
  37.     /**
  38.      * @see FlyBehavior::fly()
  39.      *
  40.      */
  41.     function fly() {
  42.         echo "FlyNoWay<br />";
  43.     }
  44. } // END class FlyNoWay
  45.  
  46. /**
  47. * 鸭子呱呱叫,癞蛤蟆想吃天鹅肉 [这里用TQuack代替Quack::PHP对大小写不敏感]
  48. */
  49. class TQuack implements QuackBehavior {
  50.     /**
  51.      * @see QuackBehavior::quack()
  52.      *
  53.      */
  54.     function quack() {
  55.         echo "Quack<br />";
  56.     }
  57. } // END class Quack
  58.  
  59. /**
  60. * 橡皮鸭吱吱叫,鼠辈横行
  61. */
  62. class Squeak implements QuackBehavior {
  63.     /**
  64.      * @see QuackBehavior::quack()
  65.      *
  66.      */
  67.     function quack() {
  68.         echo "Squeak<br />";
  69.     }
  70. } // END class Squeak
  71.  
  72. /**
  73. * 哑巴,多么想说话呀
  74. */
  75. class MuteQuack implements QuackBehavior {
  76.     /**
  77.      * @see QuackBehavior::quack()
  78.      *
  79.      */
  80.     function quack() {
  81.         echo "MuteQuack<br />";
  82.     }
  83. } // END class MuteQuack
  84.  
  85. /**
  86. * 鸭子类
  87. * 你一定要说鸳鸯也行,实在不行就搞个鸟类
  88. */
  89. class Duck {
  90.     public $quackBehavior; //叫嚣接口变量
  91.     public $flyBehavior; //飞翔接口变量
  92.    
  93.     /**
  94.      * 构造函数
  95.      * Shit! 竟然没事干
  96.      */
  97.     public function __construct() {
  98.     }
  99.    
  100.     /**
  101.      * 鸭子不出意外,天生就可以“游泳”
  102.      */
  103.     public function swim() {
  104.         echo "<span style=\"color:red;\">Duck::I belive i can swim.<br />";
  105.     } // END func swim
  106.  
  107.     /**
  108.      * 爱美之心鸭皆有之 [原版这里是一个虚函数]
  109.      */
  110.     public function display() {
  111.         echo "<span style=\"color:red;\">Duck::My dream is be a swan.<br />";
  112.     } //END func display
  113.    
  114.     /**
  115.      * 鸭子可叫乎?然异也
  116.      *
  117.      * @param QuackBehavior $quackBehavior
  118.      */
  119.     public function perfromQuack() {
  120.         $this->quackBehavior->quack(); //“叫”就一个字       
  121.     } // END func perfromQuack
  122.  
  123.     /**
  124.      * 超人鸭 是可以飞的
  125.      *
  126.      * @param FlyBehavior $flyBehavior
  127.      */
  128.     public function perfromFly() {
  129.         $this->flyBehavior->fly(); //即使打飞机也要表现得很豪迈
  130.     } //END func performFly
  131.    
  132.     /**
  133.      * 设置飞行接口,于是从这一刻起飞机就变得多样化了
  134.      */
  135.     public function setFlyBehavior(FlyBehavior $fb) {
  136.         $this->flyBehavior = $fb;
  137.     } //END func setFlyBehavior
  138.    
  139.     /**
  140.      * 设置叫接口类型,然后成就了“口技”
  141.      */
  142.     public function setQuackBehavior(QuackBehavior $qb) {
  143.         $this->quackBehavior = $qb;
  144.     } //END func setQuackBehavior
  145. } //END class Duck
  146.  
  147. /**
  148. * 这是一只野鸭,
  149. * 野鸭总比家鸭好吃 ── 小心传染病(例如:非典、口蹄疫……)
  150. */
  151. class MallardDuck extends Duck {
  152.    
  153.     /**
  154.      * 构造野鸭,先孵蛋再喂食……
  155.      */
  156.     public function __construct() {
  157.         $this->quackBehavior = new TQuack(); //曾记否:呱呱叫
  158.         $this->flyBehavior = new FlyWithWings(); //I belive i can fly. ^_^
  159.     } //END func __construct
  160.    
  161.     /**
  162.      * @see Duck::display()
  163.      * 重载display,说明一下这是只特立独行的鸭子
  164.      */
  165.     public function display() {
  166.         echo "<span style=\"blue;\">MallardDuck::</span>I'm a real Mallard duck.";
  167.     } // END func display
  168. } // class MallardDuck
  169.  
  170. /**
  171. * 这是一只模型鸭
  172. * 玩具 or 玩偶 or 玩家 ???
  173. */
  174. class ModelDuck extends Duck {
  175.     /**
  176.      * 铸模->成型->包装->出货
  177.      */
  178.     public function __construct() {
  179.         $this->flyBehavior = new FlyNoWay(); //模型鸭是不会飞的
  180.         $this->quackBehavior = new TQuack(); //1块钱店里的东西都会叫,何况这个“高”科技
  181.     }
  182.    
  183.     public function display() {
  184.         echo "<span style=\"blue;\">ModelDuck::</span>I'm a Model duck.";
  185.     }
  186. } //END class ModelDuck
  187.  
  188. /**
  189. * 使用接口后的变态类: 火箭推进器
  190. */
  191. class FlyRocketPowered implements FlyBehavior {
  192.     /**
  193.      * @see FlyBehavior::fly()
  194.      *
  195.      */
  196.     function fly() {
  197.         echo "I'm flying with a rocket!<br />";
  198.     }
  199. } //END class FlyRocketPowered
  200.  
  201. /**
  202. * 以下测试代码:
  203. */
  204. echo "<h3>测试第一组:野鸭</h3>";
  205.  
  206. /**
  207. * 最后,来点绿的,Come On ...
  208. */
  209. $first_duck = new MallardDuck();
  210. $first_duck->perfromQuack();
  211. $first_duck->perfromFly();
  212. unset($first_duck);
  213.  
  214. echo "<br /><h3>第二组测试:模型鸭</h3>";
  215.  
  216. /**
  217. * 这个就是红的了,污染环境
  218. */
  219. $second_duck = new ModelDuck();
  220. $second_duck->perfromFly();
  221. $second_duck->setFlyBehavior(new FlyRocketPowered());
  222. $second_duck->perfromFly();
  223. unset($second_duck);
  224. </span></span>
  225. ?>

文章标识
如果你是第一次来这儿,欢迎 订阅 这个博客。 第一时间看到更多精彩内容,谢谢你的访问!
本文固定链接: http://mifunny.info/phps-duck-of-head-first-design-patterns-88.html
转载请注明出处及链接,非常感谢!
LD on 08月 25th, 2008 | File Under 设计模式 | -