interface IStorage {
function add($key,$data,$ttl=null);
function hasKey($key);
function delete($key);
function flush();
function get($key);
function replace($key,$data,$ttl=null);
function set($key,$data,$ttl=null);
}
class FRegistry implements IStorage
{
protected $storage=array();
protected $args=array();
public function __construct()
{
$args=func_get_args();
$this->args=$args[0];
}
protected function makeKey($key)
{
return $key;
}
/** Is there a key in storage? */
public function hasKey($key)
{
$_key=$this->makeKey($key);
return array_key_exists($_key,$this->storage);
}
/** Writes data in runtime storage. TTL parameter is not in use. */
public function set($key,$data,$ttl=null)
{
$_key=$this->makeKey($key);
$this->storage[$_key]['data']=$data;
}
/** Adds data in runtime storage if key not exists. */
public function add($key,$data,$ttl=null)
{
if(!$this->hasKey($key))
{
$this->set($key,$data);
return true;
}
return false;
}
/** Replaces data in runtime storage if key exists. */
public function replace($key,$data,$ttl=null)
{
if($this->hasKey($key))
{
$this->set($key,$data);
return true;
}
return false;
}
/** Reads data from runtime storage */
public function get($key,$default_value=null)
{
$_key=$this->makeKey($key);
return $this->hasKey($key) ? $this->storage[$_key]['data'] : $default_value;
}
/** Returns all data in runtime storage */
public function show()
{
return $this->storage;
}
/** Deletes data in storage by key*/
public function delete($key)
{
$_key=$this->makeKey($key);
unset($this->storage[$_key]);
}
/** Deletes all data in storage*/
public function flush()
{
unset($this->storage);
$this->storage=array();
}
}
$registry=new FRegistry;
$registry->add('mykey',1111);
$registry->set('mykey',2222);
echo $registry->get('mykey');
var_dump($registry->show());
$registry->flush();
// вариант 1
function foo() {
$r = new FRegistry();
return $r->get('key');
}
foo();
// вариант 2
function foo(FRegistry $r) {
return $r->get('key');
}
foo(new FRegistry());
foo(new FRegistryOther()); // мы получили лёгкую подмену зависимости
Моя мысль же в том, что когда мы делаем инъекцию напрямую в приватное поле - это ничем не отличается от фасадов: то же самое бесконтрольное использование любых зависимостей в любом месте. Если же честно описывать все интерфейсы/теги зависимостей в конструкторе, а нужные реализации - в конфигурации, это нифига не "так же просто" (но зато правильно).Absinthe, моя мысль сводится к тому, что использование DI, вместо фасадов, или еще чего - также просто. Когда мы пишем код проекта - мы можем свободно использовать приведенные мной аннотации и все будет работать, все будет красиво.
А можно пример этого непростого, но правильного?Если же честно описывать все интерфейсы/теги зависимостей в конструкторе, а нужные реализации - в конфигурации, это нифига не "так же просто" (но зато правильно).
А вот, кстати, очень хороший способ определить, уместно ли использовать фасады.А, ну и кстати, ни о каком TDD с Service Locator и фасадами/синглтонами говорить не приходится: признайтесь, в таком случае тесты до реализации писать очень странно. Скорее всего вы будете по ходу реализации думать о том, что сейчас понадобится.
то есть - ни разу разработка через тесты: "не везде юниты" ты же не пишешь перед тестируемым кодом?не страшно даже что тесты будут не везде юниты.
Почему разброд и шатание? Наоборот, со временем приходит понимание, где надо бест практисес, а где можно и наговнокодить =)Ну вот опять докатились до того, что разброд и шатание превалирует над бест практикалс ))
Это одно и то же.Absinthe, 1) меньше зависимость (достаточно удалить комменты и use) от фреймворка
Дергай фасады только в конструкторе.2) конструктор содержит явные зависимости (если таки инжектить не напрямую в свойство)
Нет особой разницы.3) unit-тестрование самым естественным образом.
ide-helper. Но штормовый плагин мне больше нравится, хоть он и немного деревянный (многие классы в нем намертво прописаны, и с их наследниками он не работает)Плюс решение проблемы автокомплита для аннотаций, imho, проще: есть плагин для PhpStorm.
Время не хочу так тратить.Но это меньшее из двух зол, как по мне. Так-то я аннотации не люблю и не понимаю что плохого в XML-конфигах, там ж автокомплит.
Я еще раз повторю, что данный пример ни разу не DI, а обычный Service Locator, реализованный через аннотации.Absinthe, тот пример, что я привел - это самое простое использование DI. Фактически тот самый "говнокод во благо", который тут любят упоминать.
При возможности такого подхода существуют конфиги в yml/xml, которые писать не чуть не сложнее, но можно уже классы зависимостей конфигурировать как угодно, а умолчания прописывать с помощью параметров.
это ты про меня? неее.. я свято верю только в макаронного монстра ))другое дело, что есть ребята, которые свято верят, что код должен быть покрыт на 100% юнитами, да ещё в стиле before