Pull to refresh

Comments 11

весьма экзотический способ объяснения такой вещи как "сокрытие информации" (а так же принципов open/close и protected variations).


не хватает комментариев на тему temporal coupling и о том как это влияет на возможность безболезненного внесения изменений (а так же как с этим temporal coupling бороться), на тему ISP, о том что интерфейсы объектов надо проектировать с точки зрения клиетского кода (тот который ваш объект будет потреблять) и т.д.

Да, вот были бы в похапешечке модификаторы видимости классов

Это не сильно поможет изолировать изменения. Основная проблема то не с областью видимости, это было бы слишком просто. Ограничить область использования можно по всякому. хоть за счет @internal в докблоках + статический анализатор. Да и "магенту" очень плохой пример расширяемой системы. Ну то есть она то расширяема, но я не могу назвать это "удобным".

А "основная проблема", по-вашему — она в чем?

Это комплексная проблема. В основном из моих наблюдений:


  • у людей проблемы с декомпозицией
  • люди чаще проектируют снизу вверх, то есть не от клиентского кода отталкиваются когда проектируют интерфейс своего объекта (интерфейс в более общем смысле), а именно когда начинают писать классы и уже потом придумывать как их встроить в систему. Очень хорошо это описывает процесс проектирования сущностей — большинство сначала создает класс, потом поля, а потом только берется делать методы.

Потому например для некоторых людей так хорошо работает TDD. Оно просто заставляет всегда проектировать код с точки зрения клиентского кода, где намного более четко прослеживаются и границы, и роли объектов.


  • последнее чаще всего приводит к такой вещи как temporal coupling (когда нам надо дергать методы строго в определенном порядке). К этому же приводят и глобальные переменные, и анемичные модели и т.д. И вот это один из самых страшных врагов рефакторинга (на ряду с content coupling)

А "модификаторы видимости классов" — ну это как кастыль за неимением нормальной системы модулей. В целом это будет работать только если вы уже умеете грамотно выбирать границы между объектами и выделять их поведение. Если так, то не думаю что для вас это будет вообще такой уж большой проблемой.

у людей проблемы с декомпозицией

Мир несовершенен. Возможно, когда-нибудь появится "универсальный алгоритм правильной декомпозиции" и тогда влияние этого аспекта нивелируется, но пока так.


Очень хорошо это описывает процесс проектирования сущностей — большинство сначала создает класс, потом поля, а потом только берется делать методы.

Может быть это потому, что мы обрабатываем данные. Причем, вначале "данные", а уже потом — "обрабатываем"?


"Bad programmers worry about the code. Good programmers worry about data structures and their relationships." © L. Torvalds


ну это как кастыль за неимением нормальной системы модулей.

Какая, по-вашему, система модулей является нормальной?

Может быть это потому, что мы обрабатываем данные.

в том то и проблема, что не совсем так. Нас в первую очередь интересует "что" мы делаем а не "как". Бизнес не особо интересует какие данные мы храним, их интересует что мы с ними можем делать.


Good programmers worry about data structures and their relationships." © L. Torvalds

В моем случае о объектах и их взаимоотношениях. Напомню что то что внутри объектов в этом случае — второстепенно. Если у вас отношения объектов есть и вы определились что они делают — проперти добавить это не проблема. А если мы сначала выбрали что в объектах хранится а потом уже выбираем что мы будем с этим делать, то тут уже и проблемы с декомпозицией и общие проблемы с рефакторингами.


Какая, по-вашему, система модулей является нормальной?

  • декларативная, что бы можно было на этапе компиляции/парсинга знать что откуда грузить.
  • возможность переопределять откуда именно грузить модуль, для того что бы иметь возможность подменять на уровне конфигов (опять же что-то декларативное что бы все было известно в компайл тайме)
  • возможность объявлять сущности языка вне глобальной области видимости

Вот тогда вопросы с изоляцией кусков кода отпадут. Но я таких языков не знаю. По сути, из языков с которыми я работал наиболее комфортно работать с модулями в ecmascript последних редакций. Там есть небольшие проблемы со вторым пунктом но можно просто вводить промежуточные модули которые будут являться мостом для предоставления уже нужной реализации.

Бизнес не особо интересует какие данные мы храним, их интересует что мы с ними можем делать.

Обрабатывать != Хранить. Тем не менее, для того чтобы делать "что-то" или "как-то" нужны сами данные. Так что данные тут первичны. Не будет данных — бизнесу будет неинтересно ни "что" мы можем сделать с "ничем", ни "как".


Если у вас отношения объектов есть и вы определились что они делают — проперти добавить это не проблема.

Зачем добавлять что-то, если вы уже опеределились? Мне сложно вас понять, я обычно танцую от данных — есть структура (объект, класс), есть поля (атрибуты, свойства). Есть связи между ними. Наилучшая модель для описания всего этого, IMHO — реляционная. Угадал с отражением предметной области в реляционной модели — получил профит, не угадал — рефакторь, пока не угадаешь. Изменилась предметная область (а она всегда меняется) — рефакторь, даже если угадал на прошлом шаге. Рефакторинг неизбежен. А все эти "что" и "как" — всего лишь надстройка над самими данными.


По системе модулей понял.

Тем не менее, для того чтобы делать "что-то" или "как-то" нужны сами данные.

Я возможно вас не верно понял, но если мыслить "данными" мы придем к такому код смелу как primitive obsession. Если же мы будем пытаться выделять VO то опять же нам не особо важно какие поля у этих VO будут, нам будет важно только поведение которое от них требуется.


Так что данные тут первичны.

Когда вы мне дадите определение этому очень расплывчатому термину, что бы мы точно знали что именно мы обсуждаем. Данные как VO, как стэйт разрезанный на объекты? данные как модель данных? Данные как деталь реализации объектов?


Мне сложно вас понять

попробуйте ради эксперимента представить что у вас нет базы данных, приложение живет вечно и все данные хранятся в памяти в том виде, с которым вам удобно работать. Удобно не в плане "привыкли" а именно удобно. И да, это может порадить определенное дублирование данных так как одна структура данных может быть удобной для одной задачи, а для другой — уже лучше другую, хотя данные одинаковые.


Наилучшая модель для описания всего этого, IMHO — реляционная.

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


Рефакторинг неизбежен.

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

"primitive obsession" & "value objects" — это же все, связанное с ООП. Вы привязываете поведение к данным, создавая объекты. Перефразируя Фрейда можно сказать: "иногда данные — это просто данные". Без поведения.


Когда вы мне дадите определение этому очень расплывчатому термину

Под данными я подразумеваю то, что в очень известной формуле "y = f(x)" находится за символами "x" и "y".


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

Я надеюсь, вы не привязываете термин "база данных" к способу или формату хранения данных? In-memory DB для меня такое же хранилище, как и файловая система. А глиняные таблички по своим запоминающим свойствам ничуть не хуже "облака" (а с точки зрения энергопотребления — так еще и лучше). Дублирование данных в приложении — сплошь и рядом. Вызов функции — уже дублирование параметров, переданных по значению. ORM (отражение персистентных данных в программные объекты и обратно) и кэш любого уровня — первое, что приходит в голову, если говорить про "определенное дублирование". Я, наверное, еще раз упомяну здесь "хранение != обработка". Обрабатываю я в том виде, в котором мне удобно обрабатывать, а храню — в том виде, в котором удобно хранить.


Допустим вы выбрали реляционную модель. И нам пришло требование — надо иметь возможность отобразить полное дерево всех рефералов.

Это из той же оперы: "хранение != обработка"


Ну, по рефакторингу у нас консенсус :)

Неожиданный вывод, хотя и вполне логичный.

Sign up to leave a comment.

Articles