Decoupling Objects With Standard Interfaces
-
Upload
thomas-weinert -
Category
Technology
-
view
309 -
download
1
Transcript of Decoupling Objects With Standard Interfaces
![Page 1: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/1.jpg)
IPC Spring 2013IPC Spring 2013
Decoupling Objects WithStandard Interfaces
![Page 2: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/2.jpg)
About MeAbout Me● Thomas Weinert
● papaya Software GmbH● papaya CMS
● Twitter: @ThomasWeinert● Web: http://www.a-basketful-of-papayas.net
![Page 3: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/3.jpg)
InterfacesInterfaces● By Declaration● By Convention
● Magic Methods
![Page 4: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/4.jpg)
ReasonsReasons● Encapsulation● Reuse● S.O.L.I.D.
![Page 5: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/5.jpg)
ImplementImplement
class Foo implements Countable, IteratorAggregate { }
![Page 6: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/6.jpg)
ExtendExtend
interface Foo extends IteratorAggregate { }
![Page 7: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/7.jpg)
ValidateValidate
if ($foo instanceOf Traversable) { }
![Page 8: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/8.jpg)
Type HintsType Hints
function bar(Traversable $foo) { }
![Page 9: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/9.jpg)
InterfacesInterfaces
By Convention
![Page 10: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/10.jpg)
Object InitializationObject Initialization● Magic Methods
● __construct()● __destruct()● __clone()● __sleep()/__wakeup() → Serializeable● __set_state()
![Page 11: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/11.jpg)
__toString__toString● Cast an object to string
/** * Casting the object to string will *return the last value * @return string */public function __toString() { return (string)end($this->_values);}
![Page 12: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/12.jpg)
Dynamic PropertiesDynamic Properties● $object->value = 123● $value = $object->value;● $object->setValue(123);● $value = $object->getValue();
![Page 13: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/13.jpg)
Dynamic PropertiesDynamic Properties● __isset()● __get()● __set()● __unset()
![Page 14: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/14.jpg)
__isset()__isset() /** * @param string $name * @return boolean */ public function __isset($name) { switch ($name) { case 'name' : case 'value' : case 'values' : return TRUE; } return FALSE; }
![Page 15: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/15.jpg)
__get()__get()/** * @param string $name * @throws InvalidArgumentException * @return mixed */public function __get($name) { switch ($name) { case 'name' : return $this->_name; case 'value' : return end($this->_values); case 'values' : return $this->_values; } throw new \LogicException( sprintf( 'Can not read non existing property: %s::$%s', __CLASS__, $name ) );}
![Page 16: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/16.jpg)
__set()__set()/** * @param string $name * @param string|array|Traversable $value * @throws \LogicException */public function __set($name, $value) { switch ($name) { case 'name' : $this->setName($value); return; case 'value' : $this->setData((string)$value); return; case 'values' : $this->setData($value); return; } throw new \LogicException( sprintf('Can not write non existing property: %s::$%s', __CLASS__, $name ...
![Page 17: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/17.jpg)
__call/__callStatic__call/__callStatic
Dynamic Methods/Functions
![Page 18: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/18.jpg)
Generic CallbacksGeneric Callbacksclass MyEvents extends Events {
public function __construct() { parent::__construct(['example' => 21]); }}
$my = new MyEvents();echo $my->onExample(), "\n"; //21
$my->onExample = function () { return 42;};echo $my->onExample(), "\n"; //42
$my->onExample = 23;echo $my->onExample(), "\n"; //23
![Page 19: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/19.jpg)
PHP DocumentorPHP Documentor/* * … * * @property Callable $onExample * @method mixed onExample() */class MyEvents extends Events {
public function __construct() { parent::__construct(['example' => 21]); }}
![Page 20: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/20.jpg)
CallableCallable● 'function'● array($object, 'method')● function() {}● class {}
![Page 21: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/21.jpg)
__invoke__invoke● Functors
● Callable
![Page 22: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/22.jpg)
Callback ListsCallback Lists...$queries = Io\Deferred::When( $mysqlOne("SELECT 'Query 1', SLEEP(5)") ->done( function($result) use ($time) { var_dump(iterator_to_array($result)); var_dump(microtime(TRUE) - $time); } ), $mysqlTwo("SELECT 'Query 2', SLEEP(1)") ->done( function($result) use ($time) { var_dump(iterator_to_array($result)); var_dump(microtime(TRUE) - $time); } ));
![Page 23: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/23.jpg)
Functor ExampleFunctor Example
class DatabaseResultDebugger {
private $_startTime = 0;
public function __construct($startTime) { $this->_startTime = $startTime; }
public function __invoke($result) { var_dump(iterator_to_array($result)); var_dump(microtime(TRUE) - $this->_startTime); }}
![Page 24: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/24.jpg)
Callback HandlersCallback Handlers$queries = Io\Deferred::When( $mysqlOne("SELECT 'Query 1', SLEEP(5)") ->done( new DatabaseResultDebugger($time) ), $mysqlTwo("SELECT 'Query 2', SLEEP(1)") ->done( new DatabaseResultDebugger($time) ));
![Page 25: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/25.jpg)
More Callback HandlersMore Callback Handlers$queries = Io\Deferred::When( $mysqlOne("SELECT 'Query 1', SLEEP(5)") ->done( new ConcreteDatabaseResultHandler() ) ->done( new DatabaseResultDebugger($time) ), $mysqlTwo("SELECT 'Query 2', SLEEP(1)") ->done( new DatabaseResultDebugger($time) ));
![Page 26: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/26.jpg)
Predeclared Interfaces
![Page 27: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/27.jpg)
SerializeableSerializeable● Usage
● serialize($object)● unserialize($string);
● Methods● $object->serialize()● $object->unserialize($string);
![Page 28: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/28.jpg)
JsonSerializableJsonSerializable● Usage
● json_encode()
● Method● $object->jsonSerialize()
![Page 29: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/29.jpg)
ArrayAccessArrayAccess● [] -Syntax● Validation● Conversion● Lazy Initialization
![Page 30: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/30.jpg)
ArrayAccess MethodsArrayAccess Methods● offsetExists()● offsetGet()● offsetSet()● offsetUnset()
![Page 31: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/31.jpg)
OffsetExists()OffsetExists()
/** * @param integer $offset * @return boolean */ public function offsetExists($offset) { return array_key_exists($offset, $this->_values); }
![Page 32: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/32.jpg)
OffsetGet()OffsetGet()
/** * @param integer $offset */ public function offsetGet($offset) { return $this->_values[$offset]; }
![Page 33: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/33.jpg)
OffsetSet()OffsetSet()
/** * @param integer $offset * @param string $value */ public function offsetSet($offset, $value) { if (NULL === $offset) { $this->_values[] = $value; } else { $this->_values[$offset] = $value; } }
![Page 34: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/34.jpg)
OffsetUnset()OffsetUnset()
/** * @param integer $offset */ public function offsetUnset($offset) { unset($this->_values[$offset]); }
![Page 35: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/35.jpg)
Array DereferencingArray Dereferencing
echo $object->foo()[0];
![Page 36: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/36.jpg)
CountableCountable● count($foo)
class DatabaseResult implements Countable { ... public function count() { return $this->_count; } ...}
![Page 37: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/37.jpg)
TraversableTraversable● foreach● Iterator● IteratorAggregate
![Page 38: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/38.jpg)
Iterator InterfacesIterator Interfaces
Traversable
Iterator
OuterIterator
IteratorAggregate
RecursiveIteratorSeekableIterator
SPL
![Page 39: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/39.jpg)
Iterator functionsIterator functions● foreach() ● iterator_to_array()● iterator_count()● iterator_apply()
![Page 40: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/40.jpg)
IteratorIterator● rewind()● next()● valid()● current()● key()
![Page 41: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/41.jpg)
IteratorAggregateIteratorAggregate● getIterator()
class Foo implements IteratorAggregate { private $_items = array(); public function __construct(array $items) { $this->_items = $items; } public function getIterator() { return new ArrayIterator($this->_items); }}
![Page 42: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/42.jpg)
Predefined IteratorsPredefined Iterators● ArrayIterator● EmptyIterator● RegexIterator● …
![Page 43: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/43.jpg)
Nest IteratorsNest Iterators● IteratorIterator
● AppendIterator● CallbackFilterIterator● ...
![Page 44: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/44.jpg)
RecursiveIteratorRecursiveIterator● List with Children
$items = [ 1 => '1', 2 => '1.1', 3 => '2'];
$structure = [ 0 => [1, 3], 1 => [2]];
![Page 45: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/45.jpg)
Inherit from IteratorIteratorInherit from IteratorIteratorclass Bar extends IteratorIterator implements RecursiveIterator {
private $_items = []; private $_structure = [];
public function __construct($items, $structure, $parent = 0) { $siblings = []; if (!empty($structure[$parent])) { foreach ($structure[$parent] as $id) { if (isset($items[$id])) { $siblings[$id] = $items[$id]; } } } parent::__construct(new ArrayIterator($siblings)); $this->_items = $items; $this->_structure = $structure; }...
![Page 46: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/46.jpg)
hasChildren()hasChildren()
public function hasChildren() { return $this->valid() && isset($this->_structure[$this->key()]); }
![Page 47: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/47.jpg)
getChildren()getChildren()
public function getChildren() { if ($this->hasChildren()) { return new $this( $this->_items, $this->_structure, $this->key() ); } else { return new $this([], []); } }
![Page 48: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/48.jpg)
RecursiveIteratorIteratorRecursiveIteratorIterator● Iterator for RecursiveIterator$iterator = new RecursiveIteratorIterator( new Bar($items, $structure), RecursiveIteratorIterator::SELF_FIRST);
foreach ($iterator as $element) { echo str_repeat('*', $iterator->getDepth() + 1); echo $element; echo "\n";}
![Page 49: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/49.jpg)
ResultResult* 1
** 1.1
* 2
● No recursive function call● Works with Traversable/ArrayAccess● Allows for Lazy Initalization
![Page 50: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/50.jpg)
ObserverObserver
Subject
Observer 2 Observer 2Observer 2
![Page 51: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/51.jpg)
ObserverObserver
CMS Page published
Log Action Announce ToWebservice
Invalidate Cache
![Page 52: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/52.jpg)
ObserverObserver● SplObserver
● update()
● SplSubject● attach()● detach()● notify()
![Page 53: Decoupling Objects With Standard Interfaces](https://reader033.fdocuments.net/reader033/viewer/2022052900/5562a3f2d8b42a6e4f8b49d5/html5/thumbnails/53.jpg)
Thank YouThank You
● Twitter: @ThomasWeinert
● https://joind.in/8807