WEB开发笔记 www.chhua.com 每日练习 PHP设计模式——组合模式
以前我写过关于PHP组合模式的演示代码,感觉写的太过抽象,今天再重新写一下。
PHP设计模式中的组合模式是最明显也最常用最容易理解的一个模式,一个组合体可用典型的面向对象的方式来表示树形结构,如多级菜单或可以回复的论坛等。
下面我们就用面向对象的方法演示一个树形菜单的类,也许会更加容易理解一些。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
<span style="color: #000000;font-weight: bold"><?php</span> abstract <span style="color: #000000;font-weight: bold">class</span> MenuComp <span style="color: #009900">{</span><span style="color: #666666;font-style: italic">//写一个表示菜单和菜单选项之间相似性的抽象类</span> <span style="color: #000000;font-weight: bold">protected</span> <span style="color: #000088">$marked</span><span style="color: #339933">=</span><span style="color: #009900;font-weight: bold">FALSE</span><span style="color: #339933">;</span><span style="color: #666666;font-style: italic">//标识状态</span> <span style="color: #000000;font-weight: bold">protected</span> <span style="color: #000088">$label</span><span style="color: #339933">;</span> <span style="color: #000000;font-weight: bold">public</span> <span style="color: #000000;font-weight: bold">function</span> mark<span style="color: #009900">(</span><span style="color: #009900">)</span><span style="color: #009900">{</span><span style="color: #000088">$this</span><span style="color: #339933">-></span><span style="color: #004000">marked</span><span style="color: #339933">=</span><span style="color: #009900;font-weight: bold">TRUE</span><span style="color: #339933">;</span><span style="color: #009900">}</span><span style="color: #666666;font-style: italic">//设置标记状态</span> <span style="color: #000000;font-weight: bold">public</span> <span style="color: #000000;font-weight: bold">function</span> ismark<span style="color: #009900">(</span><span style="color: #009900">)</span><span style="color: #009900">{</span><span style="color: #b1b100">return</span> <span style="color: #000088">$this</span><span style="color: #339933">-></span><span style="color: #004000">marked</span><span style="color: #339933">;</span><span style="color: #009900">}</span><span style="color: #666666;font-style: italic">//返回标记状态</span> <span style="color: #000000;font-weight: bold">public</span> <span style="color: #000000;font-weight: bold">function</span> setLabel<span style="color: #009900">(</span><span style="color: #000088">$label</span><span style="color: #009900">)</span><span style="color: #009900">{</span> <span style="color: #000088">$this</span><span style="color: #339933">-></span><span style="color: #004000">label</span><span style="color: #339933">=</span><span style="color: #000088">$label</span><span style="color: #339933">;</span><span style="color: #009900">}</span><span style="color: #666666;font-style: italic">//设置标签</span> <span style="color: #000000;font-weight: bold">public</span> <span style="color: #000000;font-weight: bold">function</span> getLabel<span style="color: #009900">(</span><span style="color: #009900">)</span><span style="color: #009900">{</span> <span style="color: #b1b100">return</span> <span style="color: #000088">$this</span><span style="color: #339933">-></span><span style="color: #004000">label</span><span style="color: #339933">;</span><span style="color: #009900">}</span><span style="color: #666666;font-style: italic">//返回标签</span> abstract <span style="color: #000000;font-weight: bold">public</span> <span style="color: #000000;font-weight: bold">function</span> hasMenuOptionId<span style="color: #009900">(</span><span style="color: #000088">$id</span><span style="color: #009900">)</span><span style="color: #339933">;</span><span style="color: #666666;font-style: italic">//抽象方法用来标识ID</span> abstract <span style="color: #000000;font-weight: bold">public</span> <span style="color: #000000;font-weight: bold">function</span> MarkPathToMenuOption<span style="color: #009900">(</span><span style="color: #000088">$id</span><span style="color: #009900">)</span><span style="color: #339933">;</span><span style="color: #666666;font-style: italic">//抽象方法用来标识菜单路径</span> <span style="color: #009900">}</span> <span style="color: #000000;font-weight: bold">class</span> menu <span style="color: #000000;font-weight: bold">extends</span> MenuComp<span style="color: #009900">{</span> <span style="color: #000000;font-weight: bold">protected</span> <span style="color: #000088">$marked</span><span style="color: #339933">=</span><span style="color: #009900;font-weight: bold">false</span><span style="color: #339933">;</span><span style="color: #666666;font-style: italic">//标记状态</span> <span style="color: #000000;font-weight: bold">protected</span> <span style="color: #000088">$label</span><span style="color: #339933">;</span><span style="color: #666666;font-style: italic">//菜单标签</span> <span style="color: #000000;font-weight: bold">private</span> <span style="color: #000088">$children</span><span style="color: #339933">=</span><a rel="noopener noreferrer nofollow" href="http://www.php.net/array" rel="noopener noreferrer nofollow" target="_blank"><span style="color: #990000">array</span></a><span style="color: #009900">(</span><span style="color: #009900">)</span><span style="color: #339933">;</span><span style="color: #666666;font-style: italic">//子菜单或子菜单选项数组</span> <span style="color: #000000;font-weight: bold">private</span> <span style="color: #000088">$id</span><span style="color: #339933">;</span><span style="color: #666666;font-style: italic">//菜单ID</span> <span style="color: #000000;font-weight: bold">public</span> <span style="color: #000000;font-weight: bold">function</span> __construct<span style="color: #009900">(</span><span style="color: #000088">$label</span><span style="color: #339933">,</span><span style="color: #000088">$id</span><span style="color: #009900">)</span><span style="color: #009900">{</span><span style="color: #666666;font-style: italic">//构造函数用来设置标签和ID</span> <span style="color: #000088">$this</span><span style="color: #339933">-></span><span style="color: #004000">label</span><span style="color: #339933">=</span><span style="color: #000088">$label</span><span style="color: #339933">;</span> <span style="color: #000088">$this</span><span style="color: #339933">-></span><span style="color: #004000">id</span><span style="color: #339933">=</span><span style="color: #000088">$id</span><span style="color: #339933">;</span> <span style="color: #009900">}</span> <span style="color: #000000;font-weight: bold">public</span> <span style="color: #000000;font-weight: bold">function</span> add<span style="color: #009900">(</span><span style="color: #000088">$child</span><span style="color: #009900">)</span><span style="color: #009900">{</span><span style="color: #666666;font-style: italic">//添加菜单</span> <span style="color: #000088">$this</span><span style="color: #339933">-></span><span style="color: #004000">children</span><span style="color: #009900">[</span><span style="color: #009900">]</span><span style="color: #339933">=</span><span style="color: #000088">$child</span><span style="color: #339933">;</span> <span style="color: #009900">}</span> <span style="color: #000000;font-weight: bold">public</span> <span style="color: #000000;font-weight: bold">function</span> hasMenuOptionId<span style="color: #009900">(</span><span style="color: #000088">$id</span><span style="color: #009900">)</span><span style="color: #009900">{</span><span style="color: #666666;font-style: italic">//用迭代方式询问所有子对象上是否有对应ID的菜单选项</span> <span style="color: #b1b100">foreach</span> <span style="color: #009900">(</span><span style="color: #000088">$this</span><span style="color: #339933">-></span><span style="color: #004000">children</span> <span style="color: #b1b100">as</span> <span style="color: #000088">$child</span><span style="color: #009900">)</span><span style="color: #009900">{</span> <span style="color: #b1b100">if</span> <span style="color: #009900">(</span><span style="color: #000088">$child</span><span style="color: #339933">-></span><span style="color: #004000">hasMenuOptionID</span><span style="color: #009900">(</span><span style="color: #000088">$id</span><span style="color: #009900">)</span><span style="color: #009900">)</span> <span style="color: #b1b100">return</span> <span style="color: #009900;font-weight: bold">TRUE</span><span style="color: #339933">;</span> <span style="color: #009900">}</span> <span style="color: #b1b100">return</span> <span style="color: #009900;font-weight: bold">FALSE</span><span style="color: #339933">;</span> <span style="color: #009900">}</span> <span style="color: #000000;font-weight: bold">public</span> <span style="color: #000000;font-weight: bold">function</span> MarkPathToMenuOption<span style="color: #009900">(</span><span style="color: #000088">$id</span><span style="color: #009900">)</span><span style="color: #009900">{</span><span style="color: #666666;font-style: italic">//用迭代方式标记路径</span> <span style="color: #b1b100">if</span> <span style="color: #009900">(</span><span style="color: #339933">!</span><span style="color: #000088">$this</span><span style="color: #339933">-></span><span style="color: #004000">hasMenuOptionId</span><span style="color: #009900">(</span><span style="color: #000088">$id</span><span style="color: #009900">)</span><span style="color: #009900">)</span> <span style="color: #b1b100">return</span> <span style="color: #009900;font-weight: bold">FALSE</span><span style="color: #339933">;</span> <span style="color: #000088">$this</span><span style="color: #339933">-></span><span style="color: #004000">mark</span><span style="color: #009900">(</span><span style="color: #009900">)</span><span style="color: #339933">;</span> <span style="color: #b1b100">foreach</span> <span style="color: #009900">(</span><span style="color: #000088">$this</span><span style="color: #339933">-></span><span style="color: #004000">children</span> <span style="color: #b1b100">as</span> <span style="color: #000088">$child</span><span style="color: #009900">)</span><span style="color: #009900">{</span><span style="color: #666666;font-style: italic">//用迭代方式</span> <span style="color: #000088">$child</span><span style="color: #339933">-></span><span style="color: #004000">MarpathToMenuOption</span><span style="color: #009900">(</span><span style="color: #000088">$id</span><span style="color: #009900">)</span><span style="color: #339933">;</span> <span style="color: #009900">}</span> <span style="color: #009900">}</span> <span style="color: #009900">}</span> <span style="color: #000000;font-weight: bold">class</span> menuOption <span style="color: #000000;font-weight: bold">extends</span> MenuComp <span style="color: #009900">{</span><span style="color: #666666;font-style: italic">//菜单选项类</span> <span style="color: #000000;font-weight: bold">protected</span> <span style="color: #000088">$marked</span><span style="color: #339933">=</span><span style="color: #009900;font-weight: bold">false</span><span style="color: #339933">;</span><span style="color: #666666;font-style: italic">//标记状态</span> <span style="color: #000000;font-weight: bold">protected</span> <span style="color: #000088">$label</span><span style="color: #339933">;</span><span style="color: #666666;font-style: italic">//菜单标签例如:www.chhua.com</span> <span style="color: #000000;font-weight: bold">private</span> <span style="color: #000088">$id</span><span style="color: #339933">;</span><span style="color: #666666;font-style: italic">//菜单ID</span> <span style="color: #000000;font-weight: bold">public</span> <span style="color: #000000;font-weight: bold">function</span> __construct<span style="color: #009900">(</span><span style="color: #000088">$label</span><span style="color: #339933">,</span><span style="color: #000088">$id</span><span style="color: #009900">)</span><span style="color: #009900">{</span><span style="color: #666666;font-style: italic">//构造函数用来设置标签和ID</span> <span style="color: #000088">$this</span><span style="color: #339933">-></span><span style="color: #004000">label</span><span style="color: #339933">=</span><span style="color: #000088">$label</span><span style="color: #339933">;</span> <span style="color: #000088">$this</span><span style="color: #339933">-></span><span style="color: #004000">id</span><span style="color: #339933">=</span><span style="color: #000088">$id</span><span style="color: #339933">;</span> <span style="color: #009900">}</span> <span style="color: #000000;font-weight: bold">public</span> <span style="color: #000000;font-weight: bold">function</span> hasMenuOptionId<span style="color: #009900">(</span><span style="color: #000088">$id</span><span style="color: #009900">)</span><span style="color: #009900">{</span> <span style="color: #b1b100">return</span> <span style="color: #000088">$id</span><span style="color: #339933">==</span><span style="color: #000088">$this</span><span style="color: #339933">-></span><span style="color: #004000">id</span><span style="color: #339933">;</span> <span style="color: #009900">}</span> <span style="color: #000000;font-weight: bold">public</span> <span style="color: #000000;font-weight: bold">function</span> MarkPathToMenuOption<span style="color: #009900">(</span><span style="color: #000088">$id</span><span style="color: #009900">)</span><span style="color: #009900">{</span> <span style="color: #b1b100">if</span> <span style="color: #009900">(</span><span style="color: #000088">$this</span><span style="color: #339933">-></span><span style="color: #004000">hasMenuOptionId</span><span style="color: #009900">(</span><span style="color: #000088">$id</span><span style="color: #009900">)</span><span style="color: #009900">)</span> <span style="color: #000088">$this</span><span style="color: #339933">-></span><span style="color: #004000">mark</span><span style="color: #009900">(</span><span style="color: #009900">)</span><span style="color: #339933">;</span> <span style="color: #009900">}</span> <span style="color: #009900">}</span> <span style="color: #000000;font-weight: bold">?></span> |
/*以上方法就是演示了组合模式的使用,当然了,主要是要看menu类,没有迭代循环的更加明显。
* 记住我的PHP进阶群号:63417682*/