Modern Programozás
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.
Modern Programozás
E N D
Presentation Transcript
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.