Шаблон mixin и Open Close принцип

ivanov77

Новичок
Приветствую
Для примера возьмем следующий типовой код для Yii2:
PHP:
class ArticleSettings extends \yii\base\Model
{
    /**
     * @var boolean We set it for fields behaviors
     */   
    public $isNewRecord = false;

    /**
     * @inheritdoc
     */     
    public function behaviors()
    {
        return [
            'pathautotemplate' => [
                'class' => 'somenamespace1\PathAutoContentTypeSettingsBehavior',
                'tokengroup' => 'forpathauto'
            ],               
            'whichmenus' => [
                'class' => 'somenamespace2\menu\behaviors\WhichMenuBehavior',
            ], 
            'comments' => [
                'class' => 'somenamespace3\comments\behaviors\CommentContentTypeSettingsBehavior',
            ],
            'sitemaps' => [
                'class' => 'somenamespace4\behaviors\sitemap\SitemapContentTypeSettingsBehavior',
            ],                       
        ];
    }
    // ...
}
Вот этими поведениями расширяется функционал класса, как сказано в доках согласно шаблону "Примесь"(mixins).
Вроде все нормально, класс делегирует всякие доп. обязанности другим классам.
Но появляются следующие вопросы:
1) Как на UML отображать эти отношения? Как зависимость от того каждого конкретного класса? Или как композицию объектов поведения?
2) Вот тот набор поведений, определенный внутри behaviors() - это место как раз подверженное большим изменениям, и есть же принцип ООП - "Инкапсулировать то что меняется" ,но тут оно жестко хардкодиться в этом же классе
3) Что с методом Open Closed, нарушен же? Должны мол быть закрыты для модификации, но тут видно что для изменения дополнит. поведения класса ArticleSettings надо менять именно его код , метод behaviors().
4) Если в 3) ответ положительный, то что если в системе убрать жесткую зависимость от ArticleSettings, так что вместо нее всегда можно подставить подкласс, а в подклассе уже переопределять behaviors(), таким образом можно поправить ситуацию?
5) Если в 4) ответ положительный то уже другой звоночек начинает звенеть - Liskov substitution principle - про то насколько вроде тот же класс но с другим набором поведений, подставляемый для своего суперкласса. Ведь технически мы в ArticleSettings могли вызывать методы из его поведений.

Помогите разобраться в ситуации.
 

fixxxer

К.О.
Партнер клуба
Архитектура yii не имеет отношения к ООП. Ну там классы есть, да.
 

ivanov77

Новичок
мне интересно с этим конкретным случаем разобраться - узнать что не так и что можно сделать.
 

MiksIr

miksir@home:~$
1) Ну так композиция и есть.
2) Немного не понял про "Инкапсулировать то что меняется". Инкапсулировать нужно данные вместе с логикой.
3) Мне кажется, вы немного не понимаете этот принцип. Проектируйте так, что бы не менять. Композиция тут не мешает.
4) Ничто не мешает переопределять значение behavior в наследниках.
5) LSP ничего не говорит про поведение, оно к требованиям API класса. Не меняйте его, пред и пост условия, и ничего не нарушим
 

AmdY

Пью пиво
Команда форума
Когда проект заканчивается, он обычно закрывается. Гораздо больше ценится возможность поддерживать и развивать проект.
чем меньше кода, тем легче поддерживать. в прошлом году доделывал проект который разрабатывали 10 лет назад под php4, с говнокодом, без абстракций и без тестов. никаких проблем с поддержкой не испытывал, скорее даже наоборот, доработка на порядок быстрее, чем в проектах с попытками ddd-шничать.

Вон в соседней теме идёт война с мельницами, а для меня там серьёзная проблема - текучий интерфейс у билдера, он очень сильно усложняет отладку и на серьёзных проектах такой синтаксический сахар запрещают.
 
Последнее редактирование:

Вурдалак

Продвинутый новичок
чем меньше кода, тем легче поддерживать. в прошлом году доделывал проект который разрабатывали 10 лет назад под php4, с говнокодом, без абстракций и без тестов. никаких проблем с поддержкой не испытывал, скорее даже наоборот, доработка на порядок быстрее, чем в проектах с попытками ddd-шничать.
DDD — это красивое слово для ООП в моделях. ООП — это о простом. Если у тебя много кода, то, вероятно, ты просто делаешь что-то не так.
 

ivanov77

Новичок
1) Ну так композиция и есть.
2) Немного не понял про "Инкапсулировать то что меняется". Инкапсулировать нужно данные вместе с логикой.
3) Мне кажется, вы немного не понимаете этот принцип. Проектируйте так, что бы не менять. Композиция тут не мешает.
4) Ничто не мешает переопределять значение behavior в наследниках.
5) LSP ничего не говорит про поведение, оно к требованиям API класса. Не меняйте его, пред и пост условия, и ничего не нарушим
1) Просто интересно, не стану же я на UML диаграмме, ромбик и линию тащить просто к классу Behavior, когда налицо зависимости от кучи классов
2) Это я из этой книги - Head First Object-Oriented Analysis and Design - вычитал. Глава 8, начало, там про принципы дизайна. Под инкапсулировать они имеют ввиду - инкапсулировать в своем собственном классе, т.е. о дроблении класса на несколько.
3) Так в yii уже это так спроектировано, не я же это дополнительно спроектировал
4, 5) Так постусловия измениться то и могут. Например с оригинальным ArticleSettings, я или кто то из команды мог в вызывающем коде написать:
PHP:
$alias = $articleSettings->getAlias()
где getAlias, это метод не из типа ArticleSettings а из поведения - PathAutoContentTypeSettingsBehavior
Теперь взял переопределил behaviors(), уже другой набор поведений, и нет метода getAlias(), а клиентский код его ожидает.
 

fixxxer

К.О.
Партнер клуба
ага, а то на yii ты заканчиваешь проект быстрее, чем поклонники DDD решат одну лишь проблему автоинкремента.
Проблема автоинкремента решается точно так же - не пользоваться автоинкрементом. ;)
 

fixxxer

К.О.
Партнер клуба
На самом деле, я ничего не имею против Rails-подобного подхода, он отлично подходит для несложных контентных проектов, которых полно в вебе. Только не надо искать там принципы SOLID, они там нарушаются умышленно, ради скорости клепания.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
супер, вы сделали этот вечер нескучным!
@Вурдалак, ты уже написал книгу по DDD? или хотя бы серию статей?
назвать можно, например, "DDD для Д'Артаньяна"
 

AmdY

Пью пиво
Команда форума
DDD — это красивое слово для ООП в моделях. ООП — это о простом. Если у тебя много кода, то, вероятно, ты просто делаешь что-то не так.
в том и беда, что все делают не так, не понимаю ооп, ddd, soa

Проблема автоинкремента решается точно так же - не пользоваться автоинкрементом. ;)
Как по мне, так проблемы вообще нет, лепи как угодно, с современными IDE и кучей готового кода зарефакторишь быстрее, чем это обсуждается. Бесит меня перфекционистский подход. когда архитектуру обсуждают часами, а потом городят такой код..... Вот и ТС, обсуждает UML и SOLID, а по факту городит behaviors, как буд-то это обязательно и yii нельзя использовать без таких костылей.
 

grigori

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

Вурдалак

Продвинутый новичок
поведения нужны в 2 случаях:
* если используется сторонняя библиотека, которая написана как поведение
* если нужна параметризация наследования, или множественное наследование, когда трейтов не хватает, а фабрику для декоратора писать влом. случай очень редкий, конечно
«Behavior нужен, потому что так требует Yii. А так не нужен, конечно».
 
Сверху