Highload fwdays — спікери зі Stackoverflow, Netflix, Google, AWS, Rovio | Київ, 5 жовтня
×Закрыть

Принцип SRP vs private class data design pattern. Хто правий?

Нещодавно, при виконанні тестового завдання я отримав критику, щодо архітектури проекту. Зокрема мова була про недотримання SRP.

На роботу мене не взяли і відразу після всього я взявся за теорію і вивчення всіх цих вищеназваних принципів. Почитав в декількох джерелах, розібрав, занотував в зошит, декілька разів зазубрив (бо ж на співбесідах питатимуть)....через тиждень з чистою совістю все забув.

Пройшов деякий час і я повернувся до SOLID. Вирішено було осягати все на практиці: з кодом, прикладами і IntellijIdea.
Загуглив перший з цієї санскріптної мантри принцип, ткнув в першу урлу з результатів, потрапив на вікі:

ru.wikipedia.org/...​нственной_ответственности

На цьому ресурсі нам намагаються втюхати пояснити цей, перший принцип, на наступному прикладі:

Маємо сутніть (геттери/сеттери відпускаю)

public class Report {
    private String date;
    private String header;
    private String content;
    private String footer;
}

Маємо дії які повинні вміти робити з цією сутністю:

toPrint();
toHtml();
toJson();

Спочатку нам говорять, що можна ці методи додати в класс Report і що це не правильно і я тут повністю погоджуюсь.

public class Report {
    private String date;
    private String header;
    private String content;
    private String footer;

    public void toPrint() {
        //print resport;
    }

    public void toHtml() {
        //generate to html;
    }

}

Далі слідує рішення:

public class Response {

    private Report report;

    public void toPrint() {
        //print resport;
    }

    public void toHtml() {
        //generate to html;
    }

}

Так, рішення не досконале і можна булоб додати реалізацію інтерфейсів і всяке таке, але логіка здавалось би вірна, але ні — на вікі кажуть, що

Вроде классы разделены по назначениям, но у Response есть признак нарушения SRP. Он зависим от Report. Изменяя Report, например, удалив метод получения заголовка, потребуются внести изменения в Response. А ведь изначально не подразумевалось изменять код формата отчёта. Код проекта не готов к быстрым и безболезненным изменениям.

і пропонується вирішити питання за допомогою паттернів проектування, зокрема

Выделение частного класса данных

ru.wikipedia.org/...​ие_частного_класса_данных

Переходимо за посиланням, і що ми бачимо у висновку?:

(приклад надається на C#)

    class CircleData
    {
        private double radius;
        private Color color;
        private Point origin;
    }

    class Circle
    {
        private CircleData circleData;
        
        public Circle(double radius, Color color, Point origin)
        {
            circleData = new CircleData(radius, color, origin);
        }
        public double Circumference
        {
            get { return 2 * Math.PI * this.circleData.Radius; }
        }
        public double Diameter
        {
            get { return 2 * this.circleData.Radius; }
        }
        public void Draw(Graphics graphics)
        {
            //...
        }

    }

А бачимо те, що замінивши класи CircleData на Report, а Circle на Response, і замінивши також методи Circumference, Diameter, Draw на toPrint(), toHtml(), toJson() - ми отримаєм в рішенні той шаблон, який називався «невірним рішенням».

На цьому місці хотілось би зупинитися і розібратися.

Як так виходить що патерни проектування суперечать принципам SOLID?

LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Класс, умеющий toPrint() и toHtml() - это нарушение СРП. Т.к. класс с единственной респонсибилити — умеет либо toPrint(), либо toHtml()

От цікаво, а абсолютизм сінгл респонсібліті не перетворює ооп в процедурне програмування врешті-решт ? Який сенс в стейтлес класі з одним публічним методом ? Просто зручніше іменувати шосьтам.ToHtml() з крапкою посередині ?

Вы не совсем правильно поняли, что авторы хотели показать той картинкой.
Я согласен, что в данном случае содержать в одном классе три алгоритма toXML(), toHtml(), toPrint() вывода плохо и правильней выделить интерфейс IFormmatter { string Format() } и три алгоритма class XmlFormatter : IFormatter{}, class HtmlFormatter: IFormatter {}, class PlainTextFormatter : IFormatter {}

Но автор статьи хотел показать не это, а именно нарушение принципа SRP. Принцип гласит, что у класса должна быть только одна ответсвенность и только одна причина для изменения.
В данном же случае класс Response имеет 2 причины для изменения
1) Когда меняется алгоритм форматирования — его придется редактировать. Первая причина.
2) Когда меняется структура класса Report от которого Response зависит. Убрав заголовок в Report, на придется поменять и класс Response, если он использует заголовок для форматирования. Это вторая причина.
Соответсвенно, чтобы избавиться от второй причины мы должны убрать зависимоть от Report, это решается внесением косвенной зависимости например от абстракции, которая предоставит нужные данные, например
interface IReportable {
string GetHeader();
string GetBody();
}

class Response {
IReportable reportable;

toXml(); toHtml(); toPrint();
}
Теперь класс Response защищен от модификаций Report и у него только одна причина поменяться.

Тобто підмінивши клас на інтерфейс ми нормалізуємо архітектуру щодо SRP? По суті ж нічого не змінюється — якщо клас Report перестане відповідати контракту, який він отримує від IReportable, ми повинні будемо змінювати IReportable також. Мені хотілось би остаточно розібратись і резюмувати моє питання широкою відповіддю. Буду вдячний за Вашу допомогу

Никто во всем мире не сможет тебе объяснить SRP.

IReportable

Вопрос. Зачем тебе интерфейс, если реализация будет всего одна?

Я зобов’язаний це заскринити

Здається це найрозумніша річ, яку я читав про SRP та увесь SOLID разом взятий

Затем что через 5 лет классы становятся млять по 5 тысяч строк и это далеко не предел, потому шо такие умники как ты, счетают что ничего не будет и ничего не надо и вообще книги пишут дураки, ога.

Никто во всем мире не сможет тебе объяснить SRP.

Ну если ты до сих пор не понимаешь то проблема скорее в тебе.

Смысл в том что у тебя теперь есть контракт который определяет взаимодействие классов, и ты отделяешься от конкретной реализации. Дело в том что твой Report может меняться как угодно если он все еще поддерживает контракт IReportable, а пользователю IReportable не важно кто там внутри ссылки типа интерфейс, так как все что ему нужно это некий класс который поддерживает этот контракт и он взаимодействует через этот контракт.

Самое главное — этот контракт и есть главное, така через него ты хочешь определить правила взаимодействия.

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

Якби ви перейшли на українську версію цієї сторінки у вікіпедії, то не прочитали б там фігні про те, що проблема класу, явне призначення якого друкувати header з reportу великим заголовочним шрифтом в тому, що він не готовий до того, що цей header може зникнути з репорту. Це явно видрано з контексту обговорення респонсібіліті самого Response, яка полягає точно не в розумінні структури репорту.

toPrint(); toHtml(); toJson();
Эти методы должны быть отдельно, и просто принимать Report как аргумент. Т.е. у вас останется 1 структура данных (Report) и 3 алгоритма для работы с ней.

Окремо всі в одному класі, чі кожен в різному? Мають приймати, як аргумент безпосередньо в метод? toPrint (Report report)?

Окремо всі в одному класі, чі кожен в різному?

Отдельно, вы же хотите SRP.
У вас может быть 100500 разных алгоритмов для одной структуры данных.
Это может стать темой следущего поста про ISP :)

Мають приймати, як аргумент безпосередньо в метод? toPrint (Report report)?

Могут принимать, как аргумент, могут быть как екстеншен методы

Отдельно, вы же хотите SRP.
У вас может быть 100500 разных алгоритмов для одной структуры данных.

Що Ви маєте на увазі? Що ми можемо не тількі Report друкувати/серіалізувати/виводити на сторінку? Тобто правильно буде робити класс, який буде приймати якусь сутність, що імлементує інтерфейс?

Он говорит о случае когда toHtml может выводить разные шаблоны, например рендерить шаблон для ангуляра или реакта, или рендерить текст с учетом локализации(английский, индусский...) или рендерить отчет учитывая уровень доступа к информации(досье манагеру имеет больше полей чем досье доступное обычному клерку) это все тот же toPrint/toHtml и все тот же Report. Но ты ты же не будешь лепить 10500 реализаций все в один класс, ведь в таком случае этот класс будет зависеть от этих 100500 разных случаев.

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

Возможно, дело в том, что можно было сделать интерфейсы
IToPrintable
IToHtmlable
IToJsonable
И накидать их имплементации, которые бы были бы отличны от базового класса Report.

В языках здорового человека есть такой конструкт как тайпкласс(en.wikipedia.org/wiki/Type_class, typelevel.org/cats/typeclasses.html, typelevel.org/...​ats/typeclasses/show.html), который позволяет делать нечто подобное:

ToPrint[Report](report),

При том сам report ничего не знает в принципе о ToPrint.
На самом деле там происходит вот что:

ToPrint[Report](report)(impl = reportToPrintConverter)

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

report.toPrint(),

и при этом сам report об этом ничего не знает кроме данных которые в нём лежат.

Как это у вас делать можно? Либо экстеншны, либо АОП(что есть костыльная реализация тайпкласса), либо подкладывать реализацию руками.

Вообще говоря, то что у вас есть(Report), это структура, или же элемент ADT(Algebraic data type). То что вас просили сделать- это кодеки в разные форматы (html, plaintext, json), при том все из них есть аппликативными схемами. Задача построения кодеков в аппликативную схему из ADT решена в общем случае. Например: github.com/danslapman/morphling.

Если делать так как вы предлагаете — то у вас и json codec, и html codec, и toPlaintext кодеки вшиты в класс.

Забей, почитай паттерны (банда четырех, Фаулер, POSA). Там куда больше толку и практики, чем в модных принципах. Почитай антипаттерны — там еще больше практики. Ходи по собесам, пока найдется контора, в которой будут спрашивать что-то полезное, иначе попадешь в сообщество ментальной камасутры и чесания ЧСВ.

Та вообще пример очень хороший и простой, как раз для собеса на практическое применение SOLID, только сами экзаменующие его не прошли, вот это самый ЛОЛ :-)

Лично я взял на заметку чтобы начать разговор о SOLID и ООП на собесе.
А сам SOLID очень хорошая вещь, как и паттерны, хотя для некоторых оказывается проблема — не применять их там где не надо и не так как надо.
Увы многим не доходит, что главная их задачу упрощать себе жизнь, а не на оборот :-)

ТС советую почитать вот эту книгу www.ozon.ru/...​ontext/detail/id/5800704
здесь теже паттерны и SOLID и все расписано на реальных примерах с проблемами и как эти самые проблемы решались благодаря паттернам.

Для меня это выглядит так:
А связано с Б, а Б связано с А
Обе эти связи можно назвать Связь АБ и Связь БА
Не всегда связьАБ это связьБА
Но вот что интересно: обе связи возникают в момент взаимодействия А с Б
Иногда инициатор А иногда Б иногда некий объект, который вмещает в себя и А и Б
Связи возникают в момент взаимодействия — это критически важно.
Что происходит когда взаимодействие прекращается?
Гипотетически связи исчезают. Остаются результаты.
Имеем объекты время существования которых мизерное. Сравнимое с миром квантовых взаимодействий.
Так респонс зависит от репорт или репорт от респонс?
Получили респонс, формируем репорт
Или репорт порождает уточняющий квери, который возвращает респонс.
Что в лоб что по лбу иногда. АБ или БА однхумственно.

А вот тут еще мысль пришла...
А что после взаимодействия?
Ведь А и Б до взаимодействия и А и Б после взаимодействия это вроде уже ЧЕТЫРЕ РАЗНЫХ объекта.
Тогда и связь между А штрих и Б штрих будет пятым объектом или структурой данных
Вот такую фигню городим, пытаясь отношения реального мира промоделировать.
Ибо между состояниями есть связи.
Причина и следствие соединяются вектором.
Потому что все критяне лжецы. Если это сказал не критянин это или истина или ложь.
Если это сказал критянин то «как заверте... так и понеслсь»
(тут мы отрицаем квантор всеобщности если кому интересно)
А вот мудрость народная:
Чем дальше в лес — тем больше дров.
Вот только чем дальше в лес — тем ближе к бабе-яге (людоеду вынужденному обществом жить в чаще по какой-либо остракизм причине)

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

Вроде классы разделены по назначениям, но у Response есть признак нарушения SRP. Он зависим от Report. Изменяя Report, например, удалив метод получения заголовка, потребуются внести изменения в Response. А ведь изначально не подразумевалось изменять код формата отчёта. Код проекта не готов к быстрым и безболезненным изменениям.

Ерунду написали, очевидно.
Тот факт, что Response зависит от Report, и при изменении Report не хотелось бы менять Response — тут нарушение не буквы S, а буквы D в слове SOLID. Т.е. чтобы исправить поведение нужно внести зависимость response от интерфейса и дело с концом.

Я теж це помітив. Говорять про SRP, а контраргументи через ін’єкцію залежності.

Я не сильно вникал если честно но если смотреть на код, то методы toPrint и toHtml вынести в один или даже два интерфейса, реализацию оторвать от модельки Report, в Response метод с параметром с типом интерфейса там дергать вызовы методов.

В итоге моделька вообще без логики, класс с функционалом вообще отдельно и реализует интерфейс, Response зависит только от этого интрефейса и может работать с чем угодно что реализует этот самый интерфейс.

Логика репортов и html отдельно, данные отдельно, метод возвращающий ответы отдельно, логика генрации легко кроется тестами, таких различных реализаций можно мульйон и тележку сделать, легко менять все по отдельности ибо нет прямой зависимости а значит легко расширить и дополнить,саму модельку Report можно буцать по каким угодно бизнесс лоджик объектам и там с делаю что хотят и не спотыкаются от методы каких-то toHtml и toPrint которые им могут быть не нужны или у них свои логики для генераций, збс короче.

А если не применять все эти паттерны, а просто написать самый лучший код на свете?
Тогда этот код станет новым улучшенным паттерном.
Ну что, если не подражать непонятно чему непонятно из-за чего, а подумать, какой именно код необходим и даже достаточен?
А на работу могли не взять по другой причине, просто отмазались так.
P.S. Сначала оно лепится как бог на душу положит, а вот потом из него берется структура. Если оно успешное оказывается и возникает необходимость его тиражировать...

Всё что ты можешь произнести, обсудить, или передать иным образом — есть паттерн. Зная это, очень глупо считать, что существует некий набор из супер-магических паттернов.

Дело-то было за малым. Умные люди написали книгу о наиболее применимых на то время паттернах — для создания СИСТЕМНОГО программного обеспечения, а именно, для фреймворков, IDE, языков, и прочих-прочих плюшек. Например, математики тоже создали огромные теории — о числовых рядах, о философии аксиом, об N-мерных пространствах. Только скажи — на кой хер, чтобы решать тривиальные задачи при помощи математики, ВСЕМ ПОГОЛОВНО учить эту херню? Да незачем. В математике. А в программировании в отдельно взятой Украине — стране конченого на всю голову мракобесия HR — вдруг понадобились «шаблоны проектирования».

Ещё бы заставили вызубрить литературных критиков прежде чем написать коммент на DOU — маразм с шаблонами в аккурат такой.

Ага, верно. Кстати, еще лирическое отступление про:
Есть колода карт. Карты могут быть там упорядочены, а могут быть неупорядочены.
Если карты неупорядочены — какой паттерн?
А кто упорядочивает? Когда упорядочивает? И лишь в самом конце наблюдатель делает оценку — ух ты — а порядок то можно назвать как-нибудь, правила записать и потом другую колоду сложить в таком же порядке. Паттерн.
Итого: в начале мы ищем повторного использования многажды, с тем чтобы он — абстракт — общность — обнаружился — затребованный — для тиражирования.
Кстати. в будущем полно неупорядоченных множеств. Порядок же настоящее в будущее протягивает (тычет) простирает. Смена состояний так происходит — выбором упорядоченности.
Но первичен — хаос. И в коде тоже. Отсюда — нет решения типа общая- все учитывающая схема.
А есть решение — деталь — атом — строго обозначенную функцию выполняющий — кирпич.
Имхо, от атома ведем разработку. Хаос друг на друга наслаиваем так, чтобы выполнялось ТЗ — тесты и авто тесты — а потом аккуратненько лишнее убираем, выявляя тем самым пред структуру, еще не порядок но уже некие упорядоченности.
И вот сколько времени такое творчество займет? Сколько времени заказчику выставлять?
Ведь когда оно будет готово — неизвестно. Или как только последний тест сработает как надо.
Но когда это? Это невозможно предсказать. Каждый раз по разному.
Так сколько стоит сделать сайт?

Там окрім «порушення принципу srp» було ще «не в тих пакєтах класи розташовані» і родзинка на торті — «занадто довгі назви деяких методів». Чому родзинка? — тому, що хтів як краще і писав код «який говорить сам про себе». Таку пораду, про заміну коду, який потребує коментарія на мєтод, що в назві розкриває сенс цього коду (фактично назва і є комєнт), я прочитав на хабрі від якогось гуру...іншому гуру це не сподобалось). Так, що да — мабудь причина не в чистоті мого коду була)

Сам на себя не хочешь? На фриланс — биржах ?

Пробую на upwork. Поки без успішних наймів

Тут главное денег им не давать ни на какие их разводы.

Есть предложения или вопросы?

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

Гарна ідея. Це так само, як на стековєрлоу — хто перший приєднався той і має високий рейтинг. Всі популярні і нескладні питання давно розібранні. Зараз маєш більше шансів отоимати діз за повторне питання, ніж щось путне)

Я вхожу в топ 3% по репутации на стеке, 0 вопросов, 500 ответов из которых половина не дала репутации и от остального процентов 70 дало 10 репутации, да пробиться в топ к Скиту под бок не получится, но не обязательно занимать первые страницы, даже номинальный вклад очень высоко тебя там ставит

Біда в тому, що коли декілька поспіль відповідей чі питаннь не дає репутації система блокує тебе як безкорисного користувача..довелось завести фейковий акк і декілька разів себе проапати, щоб отримати знов можливість коментувати щось. А якщо хтось дізлайк вліпить — рахуй ти вже на прицилі. Набрав під 400 рєпи на англомовному стековерлоу, потім через постійний страх, що заблокують за непроапану відповідь якось згидив.

Біда в тому, що коли декілька поспіль відповідей чі питаннь не дає репутації система блокує тебе як безкорисного користувача

неправда, ты скорее всего косячил и получал минусы за нарушение правил, без номинальной репутации тебя обделяют

довелось завести фейковий акк і декілька разів себе проапати, щоб отримати знов можливість коментувати щось

это фигня, если не будешь вторым акком пользоваться, то его удалят, а у тебя репутацию снимут

А якщо хтось дізлайк вліпить — рахуй ти вже на прицилі. Набрав під 400 рєпи на англомовному стековерлоу, потім через постійний страх, що заблокують за непроапану відповідь якось згидив.

ответы можно удалять всегда, вопросы надо писать по правилам и не будет минусов

неправда, ты скорее всего косячил и получал минусы за нарушение правил, без номинальной репутации тебя обделяют

Я саме обмеження і мав на увазі.

вопросы надо писать по правилам и не будет минусов

Неправда. Мінусують дуже часто і «правильні питання». Мінусують також і відредаговоні кимось. Одного разу намінусували багато тількі за те, що в коді було boolean gender = false; щодо жінок. Нажаль не можу знайти зараз питання, в якому мені вдалося відстояти правильність і актуальність мого питання — в суперечці вдалося переконати опонента прибрати дізлайк.

ответы можно удалять всегда

Зате запитання — ні. І тому я вже багато часу не користуюсь stekoverflow — кожне запитання може стати останнім, а публіка не спроможна на один єдиний ап при 2000+ переглядів)

Зате запитання — ні. І тому я вже багато часу не користуюсь stekoverflow — кожне запитання може стати останнім, а публіка не спроможна на один єдиний ап при 2000+ переглядів)

судя по всему от твоего вопроса нет вклада в комьюнити стека, а только твой личный интерес, конечно минусуют

В останній час робив так — якщо нема апу на протязі дня — видаляв поки комєнти не лишили, або відповідь на запитання (бо тоді вже не видалити)

Прежде чем ссылаться на википедию, проверяй источники.
В ru версии источники вообще не указаны, в английской аж один — sourcemaking.com/...​tterns/private_class_data (и куча ворнингов о качестве статьи).

Вывод 1: нет никакого «паттерна», нечего тут обсуждать.
Вывод 2: нефиг читать за программирование на русском, и особенно — википедию.

Будете вражені, але на курсах гоіт нам в якості учбових матеріалів часто давали посилання на вікі)). Тоді мені це було дико, а зараз і сам на ті самі граблі наступив)

До речі, за Responce в продакшені тебе висношають

Все просто: паттерном є взагалі все, що можна осмислити. Зокрема, будь-який мовний вираз є паттерном.
Те що бюрократи вчепилися за якусь кучку ОПИСАНИХ паттернів — не означає що до того програмування було чимось гіршим, чи взагалі чимось іншим. Всі ці так звані «патерни проектування» є виключно бюрократією. А бюрократія є найлютішим ворогом будь-яких бізнес-процесів, бо вона по суті є карго-культом: ідеально імітує будь-що, і виглядає манною небесною для тих хто не розуміється, в даному випадку на програмуванні. Але жертвою цієї заміни процесу на ритуал стає КОРИСТЬ результату. Бюрократам же користь для дупи, єдина мета — зробити самих себе потрібними.

ХТО завжди запитує патерни? Той, хто нічого не програмує сам. Або ж тільки що вивчив.

Хто НІКОЛИ не запитає про патерни? Той, хто змушений читати чужий код. Бо хороший код має зовсім інші патерни, а саме, він моделює реальний процес, та наслідує всі патерни реального процесу.

Тому моя порада для співбесіди: якщо бачиш перед собою дурне створіннячко, яке вивчило кілька слів, бреши багато та розумними словами.

Мат.частина: мозок має асоціативну пам′ять, тому жодних принципів окрім асоціативності взагалі не має бути. Найважливіший принцип — то імена. Якщо сутностям імена дані вірно, це вже 50% читабельності коду. Інші 50% — то все що працює разом та треба налаштовувати разом — треба складати в одне місце. То є ключовий принцип ООП: все разом. Так, для машини то зайва робота, але менше роботи людям, а менше роботи = менше помилок.

Те що можна виділити в окрему незалежну сутність та дати зрозуміле ім′я — треба винести окремо. Якщо ім′я дати не можна — не можна й відокремлювати сутність, навіть якщо це призведе до копіпасти 90% коду.

В твоєму випадку:
1) Порушення іменування. toPrint очікується що метод поверне якусь сутність типу Print, сконструйовану з твого Report, та найвірогідніше від нього незалежну. Чому так? Англійською to сприймається як применник, а не як частина дієслова. Імператив не має частки to, метод треба назвати print().
2) Порушення залежності. Що таке Responce {private Report report;...} — це є бредом з точки зору мовних патернів. Якщо це Responce, він очікується як носій ПРОТОКОЛУ обміну даними, з нього можна дізнатися наприклад код обробки, чи була якась помилка, інші нюанси. Responce є контейнером. І все що від нього очікують за логікою основного процесу — що в нього є метод на кшталт getData(), чи навіть прямий паблік доступ до byte[] rawData;
Responce за мовним патерном вважається Immutable класом — не фізично таке обмеження, а саме патерн, той хто читає код, вважає що екзкмпляр цього класу є присутнім тільки в нього, тільки в цьому місці коду, і після обробки цим кодом контейнер більше не потрібен, це щось типу розпаковки картонної коробки. Responce не має знати, що саме в його контейнері. Більше скажу, це не клас, це інтерфейс має так називатися.
Ніхто не очікує, що клас Responce має взагалі якусь логіку. Скоріше її очікують в класі Report чи його предку (наприклад PrintableDocument), якщо це саме ООП. Або ж, якщо це компонентний якийсь інтерпраз, створи якийсь окремий клас що має static-методи для того щоб щось робити із класом Report, наприклад назви його ReportTools, і матимеш визови типу ReportTools.print(report); чи якщо то JavaScript, навіть ReportTools.prototype.print(report);
3) Порушення іменування. В класі Circle очікується що це саме набір даних, параметрів. В ньому не має бути за логікою методу draw, якщо тільки цей Circle примусово не декларований як представник ІНТЕРФЕЙСУ що той метод декларує. І найвірогідніше, той метод має приймати якісь аргументи, наприклад представника інтерфейсу Canvas. Якщо ж це лише перетворення в масив пікселів, то метод треба назвати Render.

Бачиш про що я веду? Що саме ПРЕДМЕТНА ОБЛАСТЬ є постачальником патернів. І патерни дуже залежать від того, що саме ти пишеш. А от вся ота дурня з 30+ базвордів — то виключно для дурнів, заради того «щоб було що спитати», а насправді воно дає перевагу дурним зубрилам, проти професіоналів які дійсно пишуть якісний код.

PS. З тих же причин гетери та сетери — то є суцільне зло. Вони потрібні тільки там, де має бути автоматична їх обробка через таблицю імен [це досить некошерно], або ж за цими операціями стоїть реальна логіка. Колись їх замінять на прихований код, виключно щоб спростити читання. Колись це вже робилося в деяких мовах, де присвоювання чи отримання можна було перехопити та виконати логіку, проте з точки зору того хто її викликає ця логіка не є важливою. Левова доля НАЛАШТУВАНЬ працює саме так: користувач не бачить гетерів та сетерів, він вказує значення, а вже прихований код виконує все інше. Чому це неможливо для програмістів? Можливо. Просто дань традиціям писати гетери та сетери.

А как геттеры и сеттеры необходимы в многопоточном программировании?
Необходимы ли?

В Java и других языках для JVM — нахер не сдались, там на уровне JVM разруливается доступ, и кстати говоря с эпичнейшими тормозами, ибо вообще глупостью было давать поддержку контроля доступа базовому типу Object и соответственно вообще всем типам.

Самое вкусное лежит в Unsafe — но именно с ними вовсю стремится воевать Oracle, стремясь забрать весь HighLoad на свои очень недешёвые «новые» продукты, а рабочие старые просто заблочить палками в колёса.

Unsafe в Java в принципе считается жутким антипаттерном. Примерно как мат в русском языке. Но когда нужно что-то реально работать, и быстро — это основа языка.

Предположим, тебе нужна многопоточность. Какой язык возьмешь? Надо обрабатывать 2000×2000 пикселей. Потоков штук 100. В каждом потоке возможен рекурсивный вызов.

Жабу. Потому что я знаю жабу. А на кой тебе 100 потоков понятно не совсем. Мне-то конечно не жалко прописать 100 в параметры пула.

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

Слышен выстрел и крики «моя нога!» :-)

Потоков штук 100

Еще выстрелы, крик — «Моя вторая нога, о боже и рука, и вторая рука!»

Не понял шутки. Объясни смысл немедленно!

Присовывание многопоточности ради многопоточности это отличный способ отстрелить себе ногу.
100 потоков, чувак ты предстваляешь сколько будет они будут жрать памяти и колько будет уходить времени на переключение контекста? — Очень много, особенно когда тебе надо переколбасить жалких 4 млн пикселей.

Я не запоминаю или вспоминаю так медленно, что почти не пользуюсь памятью. Поэтому ответ нет, не представляю.Пока не протестирую.
Я так пытался ускорить распознавание голосового отпечатка. Но дело давно было. Еще когда был жив инвестор.

Подписаться на комментарии