440 likes | 588 Views
Modern Programozás. Jenei Attila 2013. www.attilajenei.com. Strukturált programozás. Strukturált programozás. Eljárásokra bontás Kisebb feladatok Procedurális programozás. Mikor használjuk. Objektum orientált programozás Közös részek Alrészek Ismétlődően futó részek.
E N D
Modern Programozás Jenei Attila 2013. www.attilajenei.com
Strukturált programozás • Eljárásokra bontás • Kisebb feladatok • Procedurális programozás
Mikor használjuk • Objektum orientált programozás • Közös részek • Alrészek • Ismétlődően futó részek
Példa • echo $form->render();…function render(){ $result = ‘<form name=“‘ . $this->_escape($this->name) . ”>’; • foreach ($this->elements as $element) { $result .= $element->render(); } return $result . “</form>”;}
Előnyök • Áttekinthetőbb forrás • Kisebb fókusz • Saját névtér
Modularitás • Illeszthető komponensek • Újrafelhasználhatóság • Cserélhető komponensek
Modularitás • Illeszthető komponensek • Újrafelhasználhatóság • Cserélhető komponensek
Teljes modularitás • Osztályhivatkozások elhagyása • Singletonok mellőzése • Dinamikus táblanevek (query-k) • Kulcsok
Kulcsok • Gyártók • Osztálynevek • Szükség esetén • Megosztott vagy új példány • Kezelő(k)
Példa $user = new User; $path = Config::get(‘ViewPath’);
Példa $user = clone $services->get(‘Model\User’); $path = $services->get(‘MyConfig’)->get(‘ViewPath’);
Beállítás példa • array( ‘invokables’ => array( ‘Model\User’ => ‘Project\Model\User’ ), ‘factories’ => array( ‘Model\User\Table’ => function ($sm) { return \Project\Model\User\Table( $sm->get(‘Model\User\TableGateway’)); }, ‘Model\User\TableGateway’ => function ($sm) { return \Project\Model\User\TableGateway( $sm->get(‘Zend\Db\Adapter\Adapter’), ‘user’, $sm->get(‘Model\User’)); }, ‘Zend\Db\Adapter\Adapter’ => ‘Zend\Db\Adapter\AdapterServiceFactory’, ),);
Egyszerű Service Manager • public function get($name){ if (isset($this->instances[$name]) { return $this->instances[$name]; } • if (isset($this->invokables[$name])) { $className = $this->invokables[$name]; if (class_exists($className)) { $instance = new $className; } else { throw new \Exception(‘Ismeretlen osztály: ’ . $className); } }
Egyszerű Service Manager • else if (isset($this->factories[$name]) { $factory = $this->factories[$name]; if ($factory instanceof FactoryInterface) { $factory = array($factory, ‘createService’); } • if (is_callable($factory) { $instance = call_user_func($factory, $this, $name); } else { throw new \Exception(‘Hibás gyártó: ’ . $name); } }
Egyszerű Service Manager • else { throw new \Exception(‘Ismeretlen kulcs: ’ . $name); } • if ($instance) { $this->instances[$name] = $instance; return $instance; } • throw new \Exception(‘Nincs példány: ’ . $name);}
Maximalizálás • Adatbázis független • Ismeretlen “külvilág” • Saját feladat • Kiszervezés
Entitás • Információ • ≠ adatbázis bejegyzés • Futtatás helye is
Különbség Adatbázis bejegyzés képviselete objektumként. Objektumok tárolása adatbázisban.
Példa: Tartalomkezelők • Oldal, mint entitás • Fővezérlés szála • Hasáb, mint entitás • Megjelenítési szál
Entity • abstract class Entity{ protected $serviceLocator; protected $storedPrimaryKey; protected $table;
Entity • final public function getServiceLocator() { return $this->serviceLocator; } • final public function getStoredPrimaryKey() { return $this->storedPrimaryKey; } • final public function getTable() { return $this->table; }
Entity • final public function setServiceLocator(Ser…ace $serviceLocator) { $this->serviceLocator = $serviceLocator; return $this; } • final public function setStoredPrimaryKey(array $storedPrimaryKey) { $this->storedPrimaryKey = $storedPrimaryKey; return $this; } • final public function setTable(Table $table) { $this->table = $table; return $this; }
Entity • public function delete() { if (!$this->storedPrimaryKey) { throw new \Exception(‘Nincs tárolva’); } $this->table->delete($this->storedPrimaryKey); $this->storedPrimaryKey = array(); return $this; } • abstract public function exchangeArray(array $data);
Entity • public function save() { $this->table->save($this); $reloaded = $this->table ->fetchAll($this->storedPrimaryKey)->current(); if ($reloaded) { $this->exchangeEntity($reloaded); } else { throw new \Exception(‘Hiba történt visszaolvasás közben’); } }}
User Entity • class User extends Entity{ protected $name; protected $userID; public function getName() {…} public function getUserID() {…} public function setName($name) {…} public function setUserID($userID) {…}
User Entity • public function exchangeArray(array $data) { $this->name = isset($data[‘name’]) ? $data[‘name’] : null; $this->userID = isset($data[‘userID’]) ? $data[‘userID’] : null; $this->storedPrimaryKey = array(‘userID’ => $this->userID); return $this; } • public function exchangeEntity(User $entity) { $this->name = $entity->name; $this->userID = $entity->userID; $this->storedPrimaryKey = $entity->storedPrimaryKey; return $this; }
User Entity • public function exchangeArray(array $data) { $this->name = isset($data[‘name’]) ? $data[‘name’] : null; $this->userID = isset($data[‘userID’]) ? $data[‘userID’] : null; $this->storedPrimaryKey = array(‘userID’ => $this->userID); return $this; } • public function exchangeEntity(User $entity) { $this->name = $entity->name; $this->userID = $entity->userID; $this->storedPrimaryKey = $entity->storedPrimaryKey; return $this; } Hydrator
Table abstract class Table{ protected $serviceLocator; protected $tableGateway; public function __construct(TableGateway $tableGateway) { $this->tableGateway = $tableGateway; } final public function getServiceLocator() {…} final public function getTableGateway() {…} final public function setServiceLocator(…tor) {…}
Table • public function delete($where) { $this->tableGateway->delete($where); return $this; } • final public function fetchAll($where = null) { return $this->tableGateway->select($where); }}
User Table class User\Table extends Table{ public function save(User $entity) { $data = array(‘userID’ => $entity->getUserID(), ‘name’ => $entity->getName()); if ($entity->getStoredPrimaryKey()) { $this->tableGateway->update($data, $entity->getStoredPrimaryKey()); } else { $this->tableGateway->insert($data); $data[‘userID’] = $this->tableGateway->getLastInsertValue(); } $entity->setStoredPrimaryKey(array(‘userID’ => $data[‘userID’])); }
User Table class User\Table extends Table{ public function save(User $entity) { $data = array(‘userID’ => $entity->getUserID(), ‘name’ => $entity->getName()); if ($entity->getStoredPrimaryKey()) { $this->tableGateway->update($data, $entity->getStoredPrimaryKey()); } else { $this->tableGateway->insert($data); $data[‘userID’] = $this->tableGateway->getLastInsertValue(); } $entity->setStoredPrimaryKey(array(‘userID’ => $data[‘userID’])); } Hydrator
Table Gateway abstract class TableGateway extends AbstractTableGateway{ protected $entityPrototype; protected $serviceLocator; public function __construct(Adapter $adapter, $table, $entityPrototype) { $this->adapter = $adapter; $this->table = $table; $this->entityPrototype = $entityPrototype; $this->resultSetPrototype = new ResultSet; $this->resultSetPrototype->setArrayObjectPrototype($entityPrototype); $this->sql = new Sql($adapter, $table); }
Table Gateway final public function getServiceLocator() {…} final public function setServiceLocator(…tor) {…} public function create() { return clone $this->entityPrototype; }}
Abstract Table Gateway • select() • insert() • update() • delete()
User - Group • class User extends Entity{ … protected $group; • public function getGroup() { if (!is_object($this->group) && !empty($this->group)) { $this->group = $this->serviceLocator->get(‘Group\Table’) ->fetchAll(array(‘groupID’ => $this->group))->current(); } return $this->group; }
User - Group • public function getGroupID() { return is_object($this->group) ? $this->group->getGroupID() : $this->group; } • public function setGroup($group) {…}}
Összefoglalás • Entitás • Egyszerű modulok • Bonyolult hálózat • Rétegelt felépítés
www@attilajenei.com Jenei Attila 2013.