?

Log in

No account? Create an account
tech

Зло Синглтона и Peer из ActiveRecord

Настал момент, когда чуствуешь, что СинглТон это зло. Ну правда, если  у тебя есть родительский процесс, например запускатель тестов и ты в нем запускаешь тесты классов, основанных на общей библиотеке с синглтонами. Сами-то классы ходят например к разным БД, используют разные языковые настройки и у них конфиги разные. Ну и все -- приехали. В одном скрипте не запустишь и то и другое.

Выход, понятное дело в фабриках, а еще лучше в DI (IoC).

Однако при таком подходе теряется простота и изящность классов Peer из active record.

Ну вот удобно же написать в любом месте:

$car=carPeer::find(5);

Но чтобы такое работало нужен синглтон с коннектом к БД, к которому обратится статический метод класса, чтобы достать коннекшен. Несколько баз не беда, конечно -- синглтон может несколько коннекшенов хранить и выдвать по нужному ключу.

Но такая архитектура очень негибкая. Мы сразу прилипаеам к этому синглтону. И нам очень трудно будет добавлять чужие классы и отпускать свои классы в общественное пользование.

Как выход, видится свойство $context, передаваемое по цепочке вызываемых контроллеров. Это свойство -- IoC контейнер, и тогда в любом контроллере можно будет делать так:

$car=$context->create('carPeer')->find(5);

Не так изящно, но жить можно. Контейнер нужно создавать в точке входа и потом его передавать дальше. В случае Phemto контейнер создается на базе простого конфига:

$injector=require('injector_config.php');
$car=$injector->create('carPeer')->find(5);

В injector_config будет что-то вроде такого:

<?php
require_once('phemto/phemto.php');

$injector = new Phemto();
$injector->willUse(new Reused('dbConn'))->fill('dbConfig') ->with(array(...my config here ...)) ;
return $injector;
?>


при этом условный класс коннекшена будет иметь такой конструктор:


class dbConn
{
function __construct($dbConfig)()
{
....
}
}


Также объект Peer можно создать и без инжектора:

$peer=new carPeer($dbConn);

Просто инжектор позволяет создать инфраструктуру для создания классов на основе локальной конфигурации.


Comments

Уже несколько раз присматривался к DI и каждый раз нахожу в нем некоторое подобие искусственного интеллекта, но не удобство создания классов. Это интересно, когда оно само определяет что нужно, но когда требуются конфиги в виде кода, все волшебство куда-то пропадает. На мой взгляд, надо либо делать свою интеллектуальную систему, которая полностью будет автоматизирована, определяя разные состояния система и анализируя доступные компоненты, пусть даже к определенным конфигам будет привязана, но они должны правиться ручками как настройки, а не как управляющие конструкции. А если логика конфигурирования размазана по проекту, это уже не красиво и фабрики выглядят гораздо более логичным решением.
Ты мне можешь подсказать: а что есть сейчас в мире PHP типа рельс? Я глянул и чего-то нигде миграций даже не видать.
Симфони вроде, как по-моему ближе всех.

Только у нее полный раздрай в документациях к разным версиям что-то.

Миграции разные у двух ОРМов

У Пропела:
http://www.symfony-project.org/plugins/sfPropelMigrationsLightPlugin

там кликнуть ридми для справки.

У доктрины:
http://www.symfony-project.org/doctrine/1_2/en/07-Migrations

И собственный раздел Доктрины про миграции:
http://www.doctrine-project.org/projects/orm/1.2/docs/manual/migrations/en#migrations


Edited at 2010-05-24 04:55 pm (UTC)