3. План
1)Как плохо без Dependency Injection
2)Как хорошо с Dependency Injection
3)Как плохо с Dependency Injection
4)Как хорошо с Phemto
5)Как хорошо :)
VETMANAGER TEAM 26.4.12 Стр. 3
4. Как плохо
class Stores {
function add($data){
$query = 'INSERT INTO stores SET title=?
, assigned_user_id=?, type=?';
NDatabase::query($query, array($data['title']
, $data['assigned_user_id'], $data['type_id']));
}
Stores::add
VETMANAGER TEAM 26.4.12 Стр. 4
5. Как плохо
Как тестировать?(никак)
Как работать с несколькими коннектами? (никак)
Как подменить СУБД?(кое-как)
Как использовать в другом проекте?(кое-как)
Как перейти на NoSQL?(никак)
VETMANAGER TEAM 26.4.12 Стр. 5
6. Делаем инъекцию
class Stores{
public function __construct($database) {
}
function add($data){
$query = 'INSERT INTO stores SET title=?
, assigned_user_id=?, type=?';
$this->_database
->query($query, $data);
}
VETMANAGER TEAM 26.4.12 Стр. 6
7. Лучше
Как тестировать?(легко)
Как работать с несколькими коннектами? (легко)
Как подменить СУБД?(легче)
Как использовать в другом проекте?(легче)
Как перейти на NoSQL?(никак)
VETMANAGER TEAM 26.4.12 Стр. 7
8. Пишем тест...
class StoresTest extends
PHPUnit_Framework_TestCase
{
function setUp(){
$this->dbMock = $this
->getMock('VMDatabase');
$this->testObject =
new Stores($this->dbMock
}
VETMANAGER TEAM 26.4.12 Стр. 8
10. Как плохо с DI
$stores = new Stores(new VMDatabase());
$stores = new Stores(
new VMDatabase()
, new VMRequest()
, new VMSession()
, new UserModel()
…
);
VETMANAGER TEAM 26.4.12 Стр. 10
11. Как хорошо с Phemto
public function __construct(VMDatabase $database) {
$this->_database = $database;
}
require_once 'phemto/phemto.php';
$injector = new Phemto();
$stores = $injector->create('Stores');
VETMANAGER TEAM 26.4.12 Стр. 11
12. Как хорошо с Phemto2
public function __construct($database) {
$this->_database = $database;
}
require_once 'phemto/phemto.php';
$injector = new Phemto();
$injector->forVariable('database')
->willUse(new Reused('VMDatabase'));
$stores = $injector->create('Stores');
VETMANAGER TEAM 26.4.12 Стр. 12
13. Лучше
Как тестировать?(легко)
Как работать с несколькими коннектами? (легко)
Как подменить СУБД?(легче)
Как использовать в другом проекте?(легче)
Как перейти на NoSQL?(никак)
VETMANAGER TEAM 26.4.12 Стр. 13
14. ActiveRecord
class Stores {
function dataWrap($data){...}
protected function getEntity(){...}
function add($data){
$entity = $this->getEntity();
$entity->import($this->dataWrap($data));
$entity->save();
}
VETMANAGER TEAM 26.4.12 Стр. 14
15. Лучше?(getEntity)
Как тестировать?(???)
Как работать с несколькими коннектами?(???)
Как подменить СУБД?(легко)
Как использовать в другом проекте?(???)
Как перейти на NoSQL?(легко)
VETMANAGER TEAM 26.4.12 Стр. 15
16. Стальной getEntity
protected function getEntity(){
$entity = new StoresRow();
return $entity;
}
VETMANAGER TEAM 26.4.12 Стр. 16
17. Фабричный getEntity
protected function getEntity(){
return $this->factory->create('StoresRow');
}
Тест
$ourMock = $this->getMock('StoresRow');
$factoryMock = $this->expects($this->once())
->method('create')
->will($this->returnValue($ourMock))
VETMANAGER TEAM 26.4.12 Стр. 17
18. getEntity
protected function getEntity(){
return $this->_entity;
}
VETMANAGER TEAM 26.4.12 Стр. 18
19. Новый Stores
class Stores {
public function __construct($entity) {
$this->_entity = $entity;
}
$injector->whenCreating('Stores')
->forVariable('entity')
->willUse('StoresRow');
VETMANAGER TEAM 26.4.12 Стр. 19
20. Новый тест Stores
$this->entityMock->expects($this->once())
->method('import')
->with($this->equalTo($needParam));
$this->entityMock->expects($this->once())
->method('save');
$this->testObject->add($testData);
VETMANAGER TEAM 26.4.12 Стр. 20
21. Наш ActiveRecord
class StoresRow extends Entity {
protected $_fields = array ();
protected $_table = 'stores';
public function __construct($database) {
$this->setDB($database);
}
VETMANAGER TEAM 26.4.12 Стр. 21
22. Тест ActiveRecord
function testSaveWithoutId(){
$this->dbMock->expects($this->once())
->method('query')
->with($this->stringContains("INSERT"));
$this->testObject->import($testData);
$this->testObject->save();
}
VETMANAGER TEAM 26.4.12 Стр. 22
23. Phemto итог
#wiring.php
require_once 'phemto/phemto.php';
$injector = new Phemto();
$injector->forVariable('database')
->willUse(new Reused('VMDatabase'));
$injector->whenCreating('Stores')
->forVariable('entity')->willUse('StoresRow');
return $injector;
#ajax_store.php
$injector = include 'wiring.php';
$stores = $injector->create('Stores');
VETMANAGER TEAM 26.4.12 Стр. 23
24. Лучше
Как тестировать?(легко)
Как работать с несколькими коннектами? (легко)
Как подменить СУБД?(легко)
Как использовать в другом проекте?(легко)
Как перейти на NoSQL?(легко)
VETMANAGER TEAM 26.4.12 Стр. 24