若转载教程,请注明出自SW-X框架官方文档1

    1. <?php
    2. /**
    3. * 设计模式之抽象工厂模式
    4. * 小黄牛
    5. */
    6. header("Content-type: text/html; charset=utf-8");
    7. /****************************** 产品 *********************************/
    8. # 接口 - 兵营
    9. interface Barracks{
    10. public function Make(); // 生产
    11. }
    12. # 接口 - 装备库
    13. interface Equipment{
    14. public function Make(); // 生产
    15. }
    16. /**************** 生产士兵 ******************/
    17. # 创建 - 步兵
    18. class Infantry implements Barracks{
    19. public function Make() { echo ',步兵防守! <br/>';}
    20. }
    21. # 创建 - 骑兵
    22. class Cavalry implements Barracks{
    23. public function Make() { echo ',骑兵冲锋! <br/>';}
    24. }
    25. /**************** 生产装备 ******************/
    26. # 创建 - 武器
    27. class Arms implements Equipment{
    28. public function Make() { echo '装备武器,攻击力+100 ';}
    29. }
    30. # 创建 - 盔甲
    31. class Nail implements Equipment{
    32. public function Make() { echo '装备盔甲,防御力+50 ';}
    33. }
    34. /****************************** 工厂 *********************************/
    35. # 接口 - 顶级抽象工厂
    36. interface TopFactory{
    37. public function Arms(); // 武器
    38. public function Nail(); // 盔甲
    39. public function Go($Barracks); // 士兵执行动作
    40. }
    41. # 具体化 - 工厂A - 该套餐只能装备武器
    42. class A implements TopFactory{
    43. public function Arms(){return new Arms();} // 只有武器
    44. public function Nail(){return null;} // 没有盔甲
    45. public function Go($Barracks){
    46. $A = $this->Arms();
    47. $N = $this->Nail();
    48. if($A){$A->Make();}
    49. if($N){$N->Make();}
    50. $Barracks->Make();
    51. }
    52. }
    53. # 具体化 - 工厂B - 该套餐只能装备盔甲
    54. class B implements TopFactory{
    55. public function Arms(){return null;} // 没有武器
    56. public function Nail(){return new Nail();} // 只有盔甲
    57. public function Go($Barracks){
    58. $A = $this->Arms();
    59. $N = $this->Nail();
    60. if($A){$A->Make();}
    61. if($N){$N->Make();}
    62. $Barracks->Make();
    63. }
    64. }
    65. # 具体化 - 工厂C - 该套餐什么装备都有,土豪必备
    66. class C implements TopFactory{
    67. public function Arms(){return new Arms();}// 有武器
    68. public function Nail(){return new Nail();} // 有盔甲
    69. public function Go($Barracks){
    70. $A = $this->Arms();
    71. $N = $this->Nail();
    72. if($A){$A->Make();}
    73. if($N){$N->Make();}
    74. $Barracks->Make();
    75. }
    76. }
    77. /****************************** 测试 *********************************/
    78. $A = new A(); // 套装-1
    79. $B = new B(); // 套装-2
    80. $C = new C(); // 套装-3
    81. $B->Go(new Infantry()); // 步兵使用套装-2
    82. $A->Go(new Cavalry()); // 骑兵使用套装-1
    83. $C->Go(new Cavalry()); // 骑兵使用套装-3

    浏览器输出

    1. 装备盔甲,防御力+50,步兵防守!
    2. 装备武器,攻击力+100,骑兵冲锋!
    3. 装备武器,攻击力+100装备盔甲,防御力+50,骑兵冲锋!

    本案例设计原型

    1. 假设兵营里只能生产两种士兵。
    2. 步兵 骑兵
    3. | |
    4. 防守 冲锋
    5. 装备
    6. 武器 盔甲
    7. 武器与盔甲之间交由工厂去组合,再交由士兵穿戴,执行防守或冲锋动作。

    应用场景

    1. 1、游戏开发中的多风格系列场景(套餐),比如道路(接口),房屋,管道等。
    2. 2、系统要在三个不同平台上运行,比如WindowsLinuxAndroid上运行,你会怎么设计?通过抽象工厂模式屏蔽掉操作系统对应用的影响。三个不同操作系统上的软件功能、应用逻辑、UI都应该是非常类似,唯一不同的是调用不同的工厂方法,由不同的产品类去处理与操作系统交互的信息。
    3. 3、需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。

    三种工厂模式总结

    1. 1.三种在形式和特点上极为相似,最终目的都是解耦。将对象的创建过程进行封装,使客户端可以直接得到对象,而不用去关心如何创建对象。
    2. 2.对比
    3. 工厂方法模式:用于创建复杂对象。(单点食物)
    4. 抽象工厂模式:用于创建一组相关或相互依赖的复杂对象。(买套餐)
    5. 工厂方法创建一般只有一个方法,创建一种产品。抽象工厂一般有多个方法,创建一系列产品。

    我们不必去在意模式到底工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。明明使用的工厂方法模式,当新需求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了,而对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。