View difference between Paste ID: mz4WKEzD and dmhJ6ZeP
SHOW: | | - or go back to the newest paste.
1
<?php
2
3
abstract class Component extends stdCLass
4
{
5
	protected $Decorators	= array();
6
	protected $Water		= NULL;
7
	protected $Cup			= NULL;
8
	
9
	public function GetProperties(Component $Child)
10
	{
11
		foreach($this as $k => $v)
12
		{
13
			$Child->{$k} = &$this->{$k};
14
		}
15
		
16
		if(!isset($this->datahash))
17
		{
18
			$Child->{'parent'} 	 = &$this;
19
			$Child->{'datahash'} = spl_object_hash($this);
20
		}
21
	}
22
	
23
	public function AddDecorator($func, $args = array())
24
	{
25
		if(is_callable($func))
26
		{
27
			array_push($this->Decorators, array($func, $args));
28
		}
29
		else
30
		{
31
			throw new InvalidArgumentException(sprintf('%s::AddDecorator(callable $func, array $args): Invalid function ( %s ).', get_class($this), var_export($func, true)));
32
		}
33
	}
34
	
35
	public function RemoveDecorator($func, $args = array())
36
	{
37
		foreach($this->Decorators as & $decorator)
38
		{
39
			if($decorator === array($func, $args))
40
			{
41
				unset($decorator);
42
				return true;
43
			}
44
		}
45
		
46
		return false;
47
	}
48
	
49
	public function __call($Key, $Params)
50
	{
51
		$Key = (string)$Key;
52
		
53
		if(!isset($this->{$Key}))
54
		{
55
			throw new BadMethodCallException(sprintf('Call to undefined method `%s::%s()`', get_class($this), $Key));
56
			return;
57
		}
58
		
59
		if(!is_callable($this->{$Key}))
60
		{
61
			throw new BadMethodCallException(sprintf('Call to undefined method `%s::{%s}()`.', get_class($this), var_export($this->{$Key}, true)));
62
			return;
63
		}
64
		
65
		call_user_func_array($this->{$Key}, $Params);
66
	}
67
	
68
	function PourWater()
69
	{
70
		printf('Adding Water: %d%s', $this->Water, "\n");
71
	}
72
}
73
74
class SimpleCofee extends Component
75
{
76
	protected $Water 		= 0;
77
	protected $Cup 			= array();
78
	
79
	public function __construct($Parent = NULL)
80
	{
81
		$this->Water		 = 100;
82
		$this->Cup['cofeee'] = 25;
83
		
84
		if($Parent instanceof Component)
85
		{
86
			$Parent->GetProperties($this);
87
		}
88
		else
89
		{
90
			$hash = spl_object_hash($this);
91
			
92
			$this->{$hash.'Water'}		= &$this->Water;
93
			$this->{$hash.'Cup'}		= &$this->Cup;
94
			$this->{$hash.'Decorators'}	= &$this->Decorators;
95
		}
96
	}
97
	
98
	public function Produce()
99
	{
100
		print "Making coffee....\n";
101
		
102
		foreach($this->Decorators as $call)
103
		{
104
			call_user_func_array($call[0], $call[1]);
105
		}
106
		
107
		//.....
108
		$this->PourWater();
109
		//......
110
		
111
		printf('Making cofee: %s%s', var_export($this->Cup, true), "\n");		
112
	}
113
}
114
115
class SimpleTea extends SimpleCofee
116
{
117
	public function __construct($Parent = NULL)
118
	{
119
		$this->Water		 = 75;
120
		$this->Cup['tea']	 = 25;
121
		
122
		if($Parent instanceof Component)
123
		{
124
			$Parent->GetProperties($this);
125
		}
126
		else
127
		{
128
			$hash = spl_object_hash($this);
129
			
130
			$this->{$hash.'Water'}		= &$this->Water;
131
			$this->{$hash.'Cup'}		= &$this->Cup;
132
			$this->{$hash.'Decorators'}	= &$this->Decorators;
133
		}
134
	}
135
	
136
	public function Produce()
137
	{
138
		print "Making tea....\n";
139
		
140
		foreach($this->Decorators as $call)
141
		{
142
			call_user_func_array($call[0], $call[1]);
143
		}
144
		
145
		//.....
146
		$this->PourWater();
147
		//......
148
		
149
		printf('Making tea: %s%s', var_export($this->Cup, true), "\n");		
150
	}
151
}
152
153
abstract class Decorator extends Component
154
{
155
	public function __construct(Component $Parent)
156
	{
157
		$Parent->GetProperties($this);
158
	}
159
}
160
161
class SugarCube extends Decorator
162
{
163
	public function __construct(Component $Parent)
164
	{
165
		parent::__construct($Parent);
166
		
167
		$Parent->AddDecorator(array($this, 'AddSugar'));
168
	}
169
	
170
	public function AddSugar()
171
	{
172
		$hash = $this->{'datahash'};
173
		
174
		$this->{$hash.'Cup'}['Spoon']	 = 1;
175
		$this->{$hash.'Ammount'}		 = @$this->{$hash.'Ammount'} + 1;
176
		$this->{$hash.'Water'}			-= 5;
177
		
178
		printf('Adding sugar: %d%s', 1, "\n");
179
	}
180
}
181
182
class DoubleSugarCube extends SugarCube
183
{
184
	public function AddSugar()
185
	{
186
		$hash = $this->{'datahash'};
187
		
188
		$this->{$hash.'Cup'}['Spoon']	 = 1;
189
		$this->{$hash.'Ammount'}	 	 = @$this->{$hash.'ammount'} + 2;
190
		
191-
		$this->{$hash.'Water'}			-= 20;
191+
192
		
193
		printf('Adding sugar: %d%s', 2, "\n");
194
	}
195
}
196
197
198-
$Sugar = 1;
198+
	$Sugar = 1;
199-
$DoubleSugar = 1;
199+
	$DoubleSugar = 1;
200
	
201-
$Cofee = new SimpleCofee();
201+
	$Cofee = new SimpleCofee();
202-
$Tea   = new SimpleTea();
202+
	$Tea   = new SimpleTea();
203
	
204-
$Cofee->Produce();
204+
205-
$Tea->Produce();
205+
206
	
207-
print "\n============\n\n";
207+
	print "\n============\n\n";
208
	
209-
if($Sugar)
209+
	if($Sugar)
210
	{
211-
	new SugarCube($Cofee);
211+
		new SugarCube($Cofee);
212
		$Cofee->Produce();
213-
	new SugarCube($Cofee);
213+
		new SugarCube($Cofee);
214
		$Cofee->Produce();
215
	}
216
	
217-
if($DoubleSugar)
217+
	if($DoubleSugar)
218
	{
219-
	new SugarCube($Tea);
219+
		new DoubleSugarCube($Tea);
220
		$Tea->Produce();
221-
	new SugarCube($Tea);
221+
		new DoubleSugarCube($Tea);
222
		$Tea->Produce();
223-
}
223+
	}