第十五章 抽象工厂模式(就不能不换DB吗?)

  1. <?php
  2. /////////version1
  3. //数据库访问
  4. class User
  5. {
  6. private $id = null;
  7. public function setId($id)
  8. {
  9. $this->id = $id;
  10. }
  11. public function getId($id)
  12. {
  13. return $this->id;
  14. }
  15. private $name = null;
  16. public function setName($name)
  17. {
  18. $this->name = $name;
  19. }
  20. public function getName($name)
  21. {
  22. return $this->id;
  23. }
  24. }
  25. class Department
  26. {
  27. private $id = null;
  28. public function setId($id)
  29. {
  30. $this->id = $id;
  31. }
  32. public function getId($id)
  33. {
  34. return $this->id;
  35. }
  36. private $name = null;
  37. public function setName($name)
  38. {
  39. $this->name = $name;
  40. }
  41. public function getName($name)
  42. {
  43. return $this->id;
  44. }
  45. }
  46. interface IUser
  47. {
  48. public function insert(User $user);
  49. public function getUser($id);
  50. }
  51. class SqlserverUser implements IUser
  52. {
  53. public function insert(User $user)
  54. {
  55. echo "往SQL Server中的User表添加一条记录\n";
  56. }
  57. public function getUser($id)
  58. {
  59. echo "根据id得到SQL Server中User表一条记录\n";
  60. }
  61. }
  62. class AcessUser implements IUser
  63. {
  64. public function insert(User $user)
  65. {
  66. echo "往Acess Server中的User表添加一条记录\n";
  67. }
  68. public function getUser($id)
  69. {
  70. echo "根据id得到Acess Server中User表一条记录\n";
  71. }
  72. }
  73. // interface IFactory
  74. // {
  75. // public function CreateUser();
  76. // public function CreateDepartment();
  77. // }
  78. // class SqlserverFactory implements IFactory
  79. // {
  80. // public function CreateUser()
  81. // {
  82. // return new SqlserverUser();
  83. // }
  84. // public function CreateDepartment()
  85. // {
  86. // return new SqlserverDepartment();
  87. // }
  88. // }
  89. // class AcessFactory implements IFactory
  90. // {
  91. // public function CreateUser()
  92. // {
  93. // return new AcessUser();
  94. // }
  95. // public function CreateDepartment()
  96. // {
  97. // return new AcessDepartment();
  98. // }
  99. // }
  100. //简单工厂替换抽象工厂
  101. class DataBase
  102. {
  103. const DB = 'Sqlserver';
  104. // private $db = 'Access';
  105. public static function CreateUser()
  106. {
  107. $class = static::DB.'User';
  108. return new $class();
  109. }
  110. public static function CreateDepartment()
  111. {
  112. $class = static::DB.'Department';
  113. return new $class();
  114. }
  115. }
  116. interface IDepartment
  117. {
  118. public function insert(Department $user);
  119. public function getDepartment($id);
  120. }
  121. class SqlserverDepartment implements IDepartment
  122. {
  123. public function insert(Department $department)
  124. {
  125. echo "往SQL Server中的Department表添加一条记录\n";
  126. }
  127. public function getDepartment($id)
  128. {
  129. echo "根据id得到SQL Server中Department表一条记录\n";
  130. }
  131. }
  132. class AcessDepartment implements IDepartment
  133. {
  134. public function insert(Department $department)
  135. {
  136. echo "往Acess Server中的Department表添加一条记录\n";
  137. }
  138. public function getDepartment($id)
  139. {
  140. echo "根据id得到Acess Server中Department表一条记录\n";
  141. }
  142. }
  143. //客户端代码
  144. // $user = new User();
  145. // $iu = (new AcessFactory())->CreateUser();
  146. // $iu->insert($user);
  147. // $iu->getUser(1);
  148. // $department = new Department();
  149. // $id = (new AcessFactory())->CreateDepartment();
  150. // $id->insert($department);
  151. // $id->getDepartment(1);
  152. /////////////////////////////////////////////////
  153. //改为简单工厂后的客户端代码
  154. $user = new User();
  155. $iu = DataBase::CreateUser();
  156. $iu->insert($user);
  157. $iu->getUser(1);
  158. $department = new Department();
  159. $id = DataBase::CreateDepartment();
  160. $id->insert($department);
  161. $id->getDepartment(1);

抽象工厂模式,提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们的具体类。

菜鸟程序员遇到问题,只会用时间来摆平。

工厂方法模式是定义一个用于创建对象的接口,让子类决定实例化哪一个类。

抽象工厂模式的好处便是易于交换产品系列,由于具体工厂类,在一个应用中只需要在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只是需要改变具体工厂即可使用不同的产品配置。它让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操作实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户端代码中。

编程是门艺术,大批量的改动是非常丑陋的做法。

所有在用简单工厂的地方,都可以考虑用反射技术来去除switch或if,解除分支判断代码的耦合。