fork download
  1. <?php
  2.  
  3. class MyException extends Exception {}
  4.  
  5. abstract class Thing
  6. {
  7. protected $_child;
  8.  
  9. protected $_name;
  10.  
  11. protected $_selfId;
  12.  
  13. /** @var DataModel */
  14. protected $_model;
  15.  
  16. public function __construct($name)
  17. {
  18. $this->_name = $name;
  19. }
  20.  
  21. /**
  22.   * @return Thing
  23.   */
  24. public function getChild()
  25. {
  26. return $this->_child;
  27. }
  28.  
  29. public function setChild(Thing $child)
  30. {
  31. $this->_child = $child;
  32. }
  33.  
  34. public function create()
  35. {
  36. if($this->getChild() != null){
  37. if($this->getChild()->create() == null){
  38. throw new MyException('Нет ' . $this->getChild()->getName());
  39. }
  40. }
  41. if(!$model = $this->_selfCreate()){
  42. if($this->getChild() != null){
  43. $this->getChild()->delete();
  44. }
  45. throw new MyException('Нет' . $this->getName());
  46. }
  47. return $model;
  48. }
  49.  
  50. abstract protected function _selfCreate();
  51.  
  52. public function delete()
  53. {
  54. if($this->getChild() != null){
  55. $this->getChild()->delete();
  56. }
  57. $this->selfDelete();
  58. }
  59.  
  60. public function selfDelete()
  61. {
  62. $this->_model->delete();
  63. }
  64.  
  65. public function getName()
  66. {
  67. return $this->_name;
  68. }
  69.  
  70. public function getSelfId()
  71. {
  72. return $this->_selfId;
  73. }
  74.  
  75.  
  76. }
  77.  
  78. abstract class DataModel
  79. {
  80.  
  81. public function __construct(){}
  82. /**
  83.   * Может не создатся
  84.   */
  85. public function create()
  86. {
  87. if(rand(1, 5) > 3){
  88. return true;
  89. }
  90. return false;
  91. }
  92.  
  93. public function delete(){//delete
  94. }
  95.  
  96. public function getId()
  97. {
  98. return rand();
  99. }
  100. }
  101.  
  102. class RootDataModel extends DataModel{}
  103.  
  104. class MiddleDataModel extends DataModel
  105. {
  106. public function create($child_id)
  107. {
  108. if(rand(1, 5) > 3){
  109. return true;
  110. }
  111. return false;
  112. }
  113. }
  114.  
  115. class ProductDataModel extends DataModel
  116. {
  117. protected $_some_prop;
  118. public function __construct($prop)
  119. {
  120. parent::__construct();
  121. $this->_some_prop = $prop;
  122. }
  123.  
  124. public function create($child_id)
  125. {
  126. if(rand(1, 5) > 3){
  127. return true;
  128. }
  129. return false;
  130. }
  131. }
  132.  
  133. class Root extends Thing
  134. {
  135. protected function _selfCreate()
  136. {
  137. $model = new RootDataModel();
  138. if(!$model->create()){
  139. return null;
  140. }
  141. $this->_model = $model;
  142. $this->_selfId = $model->getId();
  143. return $model;
  144. }
  145. }
  146.  
  147. class Middle extends Thing
  148. {
  149. protected function _selfCreate()
  150. {
  151. $child_id = $this->getChild()->getSelfId();
  152. $model = new MiddleDataModel();
  153. if(!$model->create($child_id)){
  154. return null;
  155. }
  156. $this->_model = $model;
  157. $this->_selfId = $model->getId();
  158. return $model;
  159.  
  160. }
  161. }
  162.  
  163. class Product extends Thing
  164. {
  165. protected $_some_model_prop;
  166.  
  167. public function __construct($name, $prop)
  168. {
  169. parent::__construct($name);
  170. $this->_some_model_prop = $prop;
  171. }
  172.  
  173. protected function _selfCreate()
  174. {
  175. $child_id = $this->getChild()->getSelfId();
  176. $model = new ProductDataModel($this->_some_model_prop);
  177. if(!$model->create($child_id)){
  178. throw new MyException('Для продукта ' . $this->getName());
  179. }
  180. $this->_model = $model;
  181. $this->_selfId = $model->getId();
  182. return $model;
  183.  
  184. }
  185. }
  186.  
  187. class Factory
  188. {
  189. /**
  190.   * @param $prop
  191.   * @return Product
  192.   */
  193. public static function make($prop)
  194. {
  195. $root = new Root('root');
  196. $middle = new Middle('middle');
  197. $product = new Product('product', $prop);
  198. $middle->setChild($root);
  199. $product->setChild($middle);
  200. return $product;
  201. }
  202. }
  203.  
  204. $some_prop = 'Ололо';
  205. $product = Factory::make($some_prop);
  206. try{
  207. $product->create();
  208. } catch(MyException $e){
  209. echo $e->getMessage();
  210. }
  211. ?>
Success #stdin #stdout 0.01s 20568KB
stdin
Standard input is empty
stdout
Нетmiddle