Архитектурные вопросы в приложении (лог, настройки)

jixstes

Новичок
Здравствуйте. Столкнулся с архитектурными проблемами при разработке - опыта сборки вообще нет.
Система абстрактно: главный класс - гл. контроллер - гл. контроллер вида - конкр модель - классы-транзакции.
Вопросы:
1. Залогировать действий в транзакциях можно иньецируя туда объект логгера. Модель может это сделать, но тогда объект логгера пропускать через всю цепочку выше, например, передавая вообще объект с глобальными настройками и с логом? Или на нижних звеньях лучше выбрасывать исключения illegalargument и null и т.п., а логировать только в ключевых местах? Но тогда нет дебажной информации...Зато можно потестировать и просто переносить в другое приложение и зависимости от логгера нет. Или использовать встроенный в php наблюдатель?

2. Допустим, есть тот же уровень лога. Хранится в файле настроек. Настройки читает конвертер. Вопрос, кто должен приводить текст к формату уровня логгера т.к. нужно же точно ограничить возможные - значит нужна сущность с этими ограничениями. Допустим такой механизм. в зависимости от типов настроек конвертер читает их и по ключу рефлексией вызывает сеттеры объекта который будет хранить значение ключей. Значение сразу переводить к формату логгера наверное неправильно - формат может поменяться. Где тогда это делать? Помещать настройки еще в один объект, который из текстовых переводит в формат приложения и который гуляет дальше? Но если объект настраивается кем-то как гарантировать, что он в неизменном состоянии дойдет до последнего сегмента? непонятно.

3. Например, два класса работают с разными файлами настроек. Методы чтения и записи можно реализовать в них, но можно передать объект для этой задачи. Насколько самостоятелен должен быть класс? Метод чтения из файла входит в обязанность класса или это обязанность сущности работы с файлами. Так можно бесконечно же расслаивать. Наверное, все же другой класс более гибок т.к. может , например, понадобиться конверсия абсолютный\относительный путь.

4. Например, контроллер для получения по апи инфы о пользователях требует модели регистратора и класса для работы с апи. Кто приведет контроллер в валидное состояние? создать "экземпляр" приложения на основе конфигуратора, который уже запускает контроллеры?

5. вид логирует действия модели. Модель к виду обратиться не может и просто прикрепить слушатель между ними нельзя. тогда в модели сделать поле, которое обновляется, связать это поле и контроллер, а он уже обновляет вид? это, наверное, для десктопа больше.
сорри на большой текст.
спасибо.
 
Последнее редактирование:

Вурдалак

Продвинутый новичок
Ты пишешь очень сложно и понять тебя очень трудно. Ты используешь какие-то термины, понятные только тебе в данном контексте, используешь неудачные речевые обороты и т.д.

1. Такое впечатление, что тебе нужно познакомиться с DI и DIC. Pimple неплохо подходит для понимания концепции. Инжектишь только туда, куда нужно. Никаких «всех цепочек выше».
2. Этот «вопрос» читать невозможно.
3. Этот «вопрос» читать невозможно.
4. http://symfony.com/doc/current/cookbook/controller/service.html — так это решается в Symfony.
5. «вид логирует действия модели» — почему модель что-то «делает» во View? Этот «вопрос» читать невозможно.
 

fixxxer

К.О.
Партнер клуба
jixstes, поясни свои вопросы примерами кода. Честно пытался понять, не смог.
 

HraKK

Мудак
Команда форума
Инжектишь только туда, куда нужно. Никаких «всех цепочек выше».
Я бы убивал и расстреливал за такое.

Как меня за:?*:%!"*(?ли PHP программисты которые вечно норовят заюзать глобал для передачи объектов. В твоем случаи DI превращается в один большой глобал.
 

fixxxer

К.О.
Партнер клуба
Я бы убивал и расстреливал за такое.

Как меня за:?*:%!"*(?ли PHP программисты которые вечно норовят заюзать глобал для передачи объектов. В твоем случаи DI превращается в один большой глобал.
Не, ну для логгера/дебаггера то оно нормально. Задолбаешься их передавать по цепочке. А в целом, да.
 

Вурдалак

Продвинутый новичок
Я бы убивал и расстреливал за такое.

Как меня за:?*:%!"*(?ли PHP программисты которые вечно норовят заюзать глобал для передачи объектов. В твоем случаи DI превращается в один большой глобал.
Я имею в виду, что если у тебя есть сервис класса A, который зависит от сервиса класса B и тебе нужен логгер в сервисе B, то сервису A про логгер знать ничего не нужно, т.е. не
PHP:
class A {
    public function __construct(LoggerInterface $logger) {
        $this->b = new B($logger);
    }
}
, а
PHP:
class A {
    public function __construct(B $b) {
        $this->b = $b;
    }
}
Когда нужно будет заинжектить что-то новое, то никакой «цепочки» затрагивать не придётся. Инжектишь туда, куда нужно.
 
Последнее редактирование:

stalxed

Новичок
Для записи лога использую диспетчер Symfony EventDispatcher .
Т.е. оповещаю Symfony EventDispatcher о событих в классах реализующих бизнес логику.
И отдельными EventListener-ами отлавливаю события и пишу в лог.
Удобно. Проблема форматирования лога(о чём ТС судя по всему и интересовался во втором вопросе) ложится в EventListener-ы.
По мне куда лучше передавать в классы реализующие бизнес логику EventDispatcher нежели лог.
Даже просто звучит как:
1) Ну ка класс бизнес логики получи объект лога, и давай-ка, пиши в него логи, и да, форматируй их же, об уровнях логирования заботься, и об отлове исключений, которые могут произойти при вызове метода записи лога. - НЕ ОЧЕНЬ
2) Ну ка класс бизнес логики получи объект диспетчера и оповещай о событиях, которые творишь - КУДА ЛУЧШЕ.
Т.е. архитектура сама говорит с нами.
 

jixstes

Новичок
почему модель что-то «делает» во View
немного не так выразился. Но если бы выразился и так - есть, например, Supervising Controller

Такое впечатление, что тебе нужно познакомиться с DI и DIC
-
- чего??????? ты походу думаешь, что если заюзать его ты пишешь супер код и больше ничего не нужно. А что ты инжектишь, в каком оно состоянии, что на него влияет, думать не нужно, да. я тоже так хочу жить, так легче.

Вурдалак, я хочу тя огорчить. Например, есть у тя программа, она принимает данные в неизвестном, пусть "хреновом" с твоей т.з. формате. Как ты её напишешь? Наверное, если есть уверенность в формате,содержании - дать обработать, если нет или частично - исключение, запросить данные или все в этом духе т.к. частичная обработка - это ошибка. если перенести прогу на человека. Вот смотри, половину вопросов ты не понял, часть что понял - получились через жопу. Поэтому, дорогой мой фреймворкодер голова работает у тя в духе типичного, конечно утрирую любителя php: ничего не проверяется и не контролится - анунахер, динамические типы же, как-то сделать абы работало, даже не задуматься как это может работать. И тебя нужно отрефакторить! Сравни свою "activity diagram" с ответом fixxer, чувствуешь, он пошел по второму варианту? Была какая-то тема, где WMix запросил данные с гугла по профилю юзера и получил т.н. "говнорейтинг". Место в топе подтверждает. Короче, сделай выводы, попиши десктоп, стань добрее.

fixxxer, спасибо, что откликнулся. Но писать теперь смысла нет, все что я описал и представлял так или иначе теперь говнокод. ну да, я не фаулер, я не могу выражаться как он, как понимаю "жизнь" (как не глупо это звучит) объекта так и писал. Я попытался пойти от деталей, а нужно от архитектурного стиля, короче затупил, мне стыдно. задрачиваю любезно подкинутые книги по архитектуре, все там есть.

Тему можно закрывать, смысла задавать такие бессмысленные вопросы нет, только позориться. Спасибо. Я ушел.
 

HraKK

Мудак
Команда форума
точно точно. Просто пхпышники юзают ди как SL :D
 

HraKK

Мудак
Команда форума
Например, на моей предыдущей работе прямое обращение к контейнеру из пользовательского кода было запрещено.
Ну это уже хорошо. Но даже если контейнеру назначить что он ожидает логгер, это ничем по большому счету не отличается от $this->logger = $_GLOBAL['logger']; Поэтому, злоупотреблять DI не надо. Потом начинается диай головного мозга с криками что инъекция это зависимость, мы будем через ДИ все пробрасывать)
 

Absinthe

жожо
Ну это уже хорошо. Но даже если контейнеру назначить что он ожидает логгер, это ничем по большому счету не отличается от $this->logger = $_GLOBAL['logger'];
Отличается.

Поэтому, злоупотреблять DI не надо. Потом начинается диай головного мозга с криками что инъекция это зависимость, мы будем через ДИ все пробрасывать)
То ли я тебя не понял, то ли какую-то фигню в твоем посте прочитал.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Думаю, HraKK имел ввиду, что запрет обращаться к DI-контейнеру напрямую через суперглобал или через статику типа yii::app() :) - недостаточно, этот глобальный контейнер засирается так, что листаешь страницы конфига в поисках нужного сервиса.
 

HraKK

Мудак
Команда форума
Какую проблему вечно пытаются решить ПХПшники глобалами - звездный доступ. Наговнял архитектурно? Не знаешь как получить компонент в той заднице где ты оказался? Твой выход - глобал и его семейство регистр, синглтон, контейнер etc.
И... DI. Потому что так же позволяет получить в любой жопе, любой компонент. И понеслось говно по трубам)
PHP:
$_GLOBAL['SomeModel_someComponent'] = new SomeComponent();

class SomeModel
{
function fire()
{
$_GLOBAL[__CLASS__.'_someComponent']->fire();
}
}
ничем не отличается по сути от
PHP:
SomeModel
    setInjection/
        SetSomeComponent = new SomeComponent();


class SomeModel
{
function fire()
{
$this->someComponent::getInstance()->fire();
}
}
только зависимость сменило место с одного на другое.
 
Последнее редактирование:

HraKK

Мудак
Команда форума
Декомпозиция, инъекции, правильное взаимодействие. Нет, серебрянной пули, но практически все описано у Фаулера или в банде 4. Ничего особо не поменялось за это время.
 
Сверху