LINUX.ORG.RU

Ответ на: комментарий от t184256

От неявности задания интерфейса никуда не деться, извини. Столько лещей в мире нет, сколько неявных ожиданий таится в интерфейсах.

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

Dudraug ★★★★★
()
Ответ на: комментарий от Dudraug

А все почему? Потому что были еще и неявные ожидания от коммунизма, которые на предыдущих этапах не записали и не соблюли.

Можно ли класть на знание паттернов? Естественно, если хочешь пройтись по хоженым граблям сам и устраивает не знать их названий. Можно ли забивать на общепринятые практики? Конечно, если устраивает ходить с несмываемым позором, как @Goury. Можно ли забить на принцип подстановки Лисковой? Да, и всегда будет шанс, что он укусит тебя в зад, и будет шанс, что тебя волшебным образом пронесет. Можно ли ни разу на нем не обжечься? Тоже вряд ли.

Жестких принципов в программировании вообще негусто, строго определенных - тем более. Но ты возбух почему-то как раз против такого.

t184256 ★★★★★
()
Ответ на: комментарий от t184256

Но ты возбух почему-то как раз против такого.

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

Dudraug ★★★★★
()
Ответ на: комментарий от no-such-file

И как же он будет обеспечивать такой инвариант? Сеттеры ширины/высоты обязаны обеспечивать независимость a/b что для квадрата невозможно

Поэтому это и называется нарушением. А как это технически сделать любой говнокодер придумает десяток вариантов.

slovazap ★★★★★
()
Ответ на: комментарий от no-such-file

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

Как же все-таки хорошо, что программы имеют конечный размер, а интерфейс нифига не равен множеству методов trollface.

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

t184256 ★★★★★
()
Ответ на: комментарий от Dudraug

Мне трудно представить случай нарушения этого принципа во благо.

Quick-and-dirty способ копирования реализации? Я бы там, где важна архитектура, вообще бы неявное наследование реализации запретил.

t184256 ★★★★★
()
Ответ на: комментарий от t184256

давай называть интерфейс ожиданиями

Зачем? В каждом языке есть вполне определённое понятие интерфейса, или равнозначное ему.

уйдешь уже молча чинить свою терминологию

Зачем мне что-то чинить? Тут пол-треда у народа бомбит от того, что у меня (внезапно) есть своё мнение. Но вместо того, чтобы обсудить конкретные недостатки моих убеждений (вероятно они есть), я вижу только 100500 раз повторение цитат из вики (или где они там набрались). Смешно, ей-богу, наблюдать это отрицание реальности и повторение мантр для того чтобы полегчало. Как можно после этого воспринимать таких мамкиных «специалистов» всерьёз?

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

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

t184256 ★★★★★
()
Ответ на: комментарий от t184256

удалюсь, раз вынимать голову ты в упор не хочешь

Разумеется, ведь ты уже сделал то, зачем пришёл — девальвировал угрозу. Надеюсь, что тебя отпустило.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от no-such-file

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

Да нет, это грустно, когда кто-то застревает в своей собственной реальности, в которой он живет один.

anonymous
()
Ответ на: комментарий от anonymous

это грустно

Грустно, это то что нам всем придётся сдохнуть. Всё остальное — это просто мелочи жизни.

no-such-file ★★★★★
()
Ответ на: комментарий от anonymous

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

Еще один ничего не понял в подстановке Лисков. Отлично, добро пожаловать в клуб.

byko3y ★★★★
()
Ответ на: комментарий от no-such-file

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

Тогда это плохие алгоритмы, которые полагались на неявно заданный интерфейс. За неявность интерфейса тоже нужно выдавать леща.

Я хочу напомнить, что просто коммент в коде с описанием применения - это уже «интерфейс». Вывод: комментируйте неочевидные моменты в вашем коде.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

хочу напомнить, что просто коммент в коде с описанием применения - это уже «интерфейс»

Если только это аннотация. Всё остальное — заявление о намерениях без каких либо обязательств и гарантий (и вообще говнокод). Хочешь интерфейс — делай интерфейс, а не на заборе пиши.

no-such-file ★★★★★
()
Ответ на: комментарий от t184256

Можно ли класть на знание паттернов? Естественно, если хочешь пройтись по хоженым граблям сам и устраивает не знать их названий. Можно ли забивать на общепринятые практики?

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

byko3y ★★★★
()
Ответ на: комментарий от no-such-file

Если только это аннотация. Всё остальное — заявление о намерениях без каких либо обязательств и гарантий (и вообще говнокод). Хочешь интерфейс — делай интерфейс, а не на заборе пиши.

Кто-то запретит костылить в обход формальных объявлений интерфейсов? Нет. В этом, например, заключается провал идеи видимости атрибутов класса (private/public/etc) - индусы все равно будут неправильно пользоваться интерфейсами, а адекватный кодер из-за этих дурацких ограничений страдает, потому никогда не получится угадать, какой атрибут понадобится для доступа извне, а какой - нет. В итоге лично я уже потерял счет, какое число сторонних модулей мне приходилось копипастить с минимальными правками, потому что мамкин архитектор решил, что будет хорошей идеей назначить полю видимость private.

Для чего действительно нужны формальные описания - так это для машинной обработки во время компиляции или просто статической проверки. Ну, или для тестов. То есть, реальная задача, реальная ощущаемая задача, а не какая-то фантазию про «эъ, вот бы всё на свете засунуть в интерфейсы».

byko3y ★★★★
()
Ответ на: комментарий от t184256

Я тебе только что написал, что можно.

Твоя фраза не была интерпретирована мной, как «можно». Для хорошего кодера в конечном итоге важно понимать разницу в используемых приемах и уметь делать выбор. Знание или незнание паттернов здесь не дают никакой разницы - это просто одна из многих форм передачи знаний.

byko3y ★★★★
()
Ответ на: комментарий от t184256

Я агитирую за знание, мой собеседник агитирует против. Может с ним продуктивнее поспоришь?

А я пытаюсь в уже третьем посте объяснить разницу между механическим знанием слов и практическим навыком. И тьвой собеседник, между прочим, то же самое пытается сказать:

Принцип есть принцип. Практика - это уже совсем другое. Идеальный комунизм, да идеальный рынок(капитализм) - это прям рай на земле. А на практике оказывается, что это лишь утопии и на деле все не так радужно.

byko3y ★★★★
()

Потомки могут иметь,уметь больше или равно то что родитель, но не меньше. Любой потомок может быть представлен и использован как родитель. Всё.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от LINUX-ORG-RU

Потомки могут иметь,уметь больше или равно то что родитель, но не меньше. Любой потомок может быть представлен и использован как родитель. Всё.

Давайте вы уже будете сначала предъявлять свои определения потомка-родителя, а потом уже писать свои выводы. Как я понимаю, речь идет про наследование, но проблема в том, что отношение наследования и отношение тип-подтип по Лисковой - это разные и пересекающиеся множества.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

Еще один ничего не понял в подстановке Лисков

Индеец не может заблудиться, это вигвам может заблудиться %)

Nervous ★★★★★
()
Ответ на: комментарий от byko3y

проблема в том, что отношение наследования и отношение тип-подтип по Лисковой - это разные и пересекающиеся множества.

Если бы они были одним и тем же, LSP бы не понадобился, не так ли? Его цель — помочь тебе понять, правильно ли ты используешь наследование, получаются у тебя правильные подтипы или нет.

Nervous ★★★★★
()
Ответ на: комментарий от Nervous

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

Если говорить про SOLID в целом, то можно прийти к простому выводу: если ты используешь наследование, то ты делаешь что-то неправильно. Не бывает правильного наследования. К сожалению, этого вывода нельзя сделать из LSP или любого другого отдельно взятого пункта SOLID.

Но жертвы ООП, как жертвы насилия, на кого не глянут - видят маньяков. То есть, наследование. И упорно продолжают пытаться натянуть сову на глобус: якобы соблюдать/знать SOLID, при этом вопиюще противоречить ему в проектировании софта. К сожалению, в нашем мире есть довольно большое число людей, которые крутятся в вопиющих противоречиях, но это их нисколько не смущает.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

Не бывает правильного наследования

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

Что, конечно, не означает, что его нужно непременно везде использовать просто потому, что можешь %)

Nervous ★★★★★
()
Ответ на: комментарий от Nervous

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

Раз в жизни бывает, в качестве исключения. Но мы же про правила говорим, правильно? Присмотрись: SRP ограничивает возможности расширения класса в наследнике, OCP запрещает изменять методы и поля предка, подстановка Лисков вообще запрещает менять поведение класса в наследнике, а ISP и DIP как бы намекают «зачем ты делал наследование, если с ним ты не можешь нам следовать?».

byko3y ★★★★
()
Ответ на: комментарий от byko3y

Кто-то запретит костылить в обход формальных объявлений интерфейсов? Нет. В этом, например, заключается провал идеи

Кто-то запретит говнокодить? Нет. В этом заключается провал SOLID.

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Кто-то запретит говнокодить? Нет. В этом заключается провал SOLID.

Кто-то запретит прищемлять яйца дверью? Нет. В этом заключается провал дверей. Или яиц.

Nervous ★★★★★
()
Последнее исправление: Nervous (всего исправлений: 1)
Ответ на: комментарий от no-such-file

Кто-то запретит говнокодить? Нет. В этом заключается провал SOLID.

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

byko3y ★★★★
()
Ответ на: комментарий от Nervous

Раз в жизни бывает

Значит, кому-нибудь пригодится.

Ага, и 95% плохого софта написаны в стиле «вот, судя по всему, пригодилось».

byko3y ★★★★
()
Ответ на: комментарий от byko3y

не могут какие-то там принципы сделать из бездарного индуса хорошего кодера.

Разве кто-то утверждал, что одного знания теории достаточно? Разумеется, нужна практика. Но практика+теория ведь лучше, чем только практика?

Nervous ★★★★★
()
Последнее исправление: Nervous (всего исправлений: 1)
Ответ на: комментарий от byko3y

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

Обычно люди говорящие про SOLID не являются практикующими программистами.

/fixed

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

Обычно люди говорящие про SOLID не являются практикующими программистами.

Кто не умеет работать - учит других. Они бы писали, если бы умели.

byko3y ★★★★
()
Ответ на: комментарий от no-such-file

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

потому что не может быть «рыть» применено к «животные»

example_cat
()
#include <cstdio>

struct iface {
  virtual ~iface() {}
  virtual void action() = 0;
};

void f(iface &obj) {obj.action();}

template <typename T>
struct impl1 : iface {
  void action() override {
    static_cast <T *> (this) -> action_pre();
    printf("wake up, ");
    static_cast <T *> (this) -> action_post();
  }
};

struct impl2 : impl1<impl2> {
  void action_pre() {puts("knock, knock");}
  void action_post() {puts("neo");}
};

int main() {
  impl2 obj;
  f(obj);
}

и хотел я срать на ваших лисков и пр.

anonymous
()
Ответ на: комментарий от byko3y

Раз в жизни бывает, в качестве исключения. Но мы же про правила говорим, правильно?

Ещё один «теоретик» с засраным мозгом, правда немного вылезший из бездумного наследования, в отличие от no-such-file! Вы что, сектанты что ли?

SRP ограничивает возможности расширения класса в наследнике,

Враньё! Оно всего лишь не поощряет навешивание дополнительных ответственностей в рамках расширения путём наследования.

OCP запрещает изменять методы и поля предка

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

подстановка Лисков вообще запрещает менять поведение класса в наследнике

Подстановка Лисков говорит только о поведении в рамках контракта предка его наследниками, да они должны его соблюдать, другое дело что если предок декларирует абстрактные(виртуальные) методы, то он явно перекладывает поведение на потомков, с этой позиции потомкам надо всего лишь соблюдать формальный контракт, и никакого противоречия тут нет, просто от потомка требуется реализация того, на что предок был не способен!

а ISP и DIP как бы намекают «зачем ты делал наследование, если с ним ты не можешь нам следовать?»

ISP - не о наследовании, а о реализации интерфейсов, вообще можешь отнаследоваться до поноса, а потом навесить на все открытое интерфейсов, заприватить всё конструирование и возращать одни интерфейсы из фабрик и/или компоновщиков.

DIP - о слоистости и организации зависимостей через интерфейсы и абстракции, а не завязки на конкретные реализации, как ты привык.

anonymous
()
Ответ на: комментарий от anonymous

SRP ограничивает возможности расширения класса в наследнике,

Враньё! Оно всего лишь не поощряет навешивание дополнительных ответственностей в рамках расширения путём наследования.

Да? И чем же ты собрался расширять класс в рамках наследования, соблюдая все принципы SOLID? Новыми геттерами/сеттерами? Это можно сделать отдельным классом/функцией, наследование здесь теряет смысл.

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

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

ISP - не о наследовании, а о реализации интерфейсов, вообще можешь отнаследоваться до поноса, а потом навесить на все открытое интерфейсов, заприватить всё конструирование и возращать одни интерфейсы из фабрик и/или компоновщиков.

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

DIP - о слоистости и организации зависимостей через интерфейсы и абстракции, а не завязки на конкретные реализации, как ты привык.

Здрасти, а наследование у нас чем является? Зависимостью на реализации. Или это принципы типа «давайте сюда не смотреть, а смотреть сюда»?

byko3y ★★★★
()
Ответ на: комментарий от byko3y

Начну с середины, потому что там жалкая и смешная попытка предъявить что-то.

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

Какого ещё черного ящика, «чёрный ящик» он только для интеграции, и да, там наружу торчит интерфейс или протокол. Для меня «ящик» прозрачный, как и для всех остальных разработчиков, и это не «ящик», а «ящики», и где надо, они так же обращаются через интерфейс/протокол/контракт или вообще сообщения.

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

[long_penis_mode=on] Если бы ты писал систему, хоть на 0.1% размера моей самой маленькой системы за последние 18 лет, то научился бы как раз интегрировать так, что сцепленность только уменьшалась бы. А там где интегрированность нужна, не делается разделение на части, а делается одна часть. И да, с говном встречался, пока переписывал проекты начатые до меня, и после этого они раз в десятки раз выросли по кодовой базе и в тысячи по нагрузке. [long_penis_mode=off] Но всё это не имеет никакого отношения к тому исповедую я принципы SOLID, следую я им в разработке, или наоборот яростно отрицаю, а в том, что ты вываливаешь заблуждения и неверную интерпретацию теории, прикрываясь практикой.

И чем же ты собрался расширять класс в рамках наследования, соблюдая все принципы SOLID? Новыми геттерами/сеттерами?

Очень смешно, «геттер/сеттер» редко когда требуется в расширении объекта, только если явная иерархия тупых дтошных «осьминожек». Вот у меня перед глазами отнаследованный код разных классов, с другими неведомыми тебе методами addAAA, parseBBB, handleCCC, doSomething123, checkZZZ, и многими другими, о которых основной код не знает, которые описаны в интерфейсах специфичных для соответствующих подсистемы, а общий код работает в соответствии с принципом, как это не странно Лисков, ему вообще по барабану, что там сверху навесили на наследника, он дёргает только известные ему ручки, а наследник, открытые ему.

Для этого есть интерфейсы,

Когда я программировал на приплюснутых, там не было интерфейсов, интерфейсы годятся только для декларации, хм, собственно контракта только, для совместного кода они не подойдут. И ладно ещё бы ты был знаком с понятиями «стратегий» и «посетителей», но вам кроме того же сложно держать больше одной иерархии, а когда у вас ещё пойдут параллельно иерархии стратегий посреди иерархий объектов, вы вообще в осадок выпадете.

ибо накладывает неоправданные ограничения,

которые ты сам себе выдумал.

ровно как и дает лишний соблазн.

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

Здрасти, а наследование у нас чем является? Зависимостью на реализации.

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

Или это принципы типа «давайте сюда не смотреть, а смотреть сюда»?

Можно было бы сказать «принципы на то и придуманы, чтоб их нарушать», или «на принципы ссылаются глупые люди, чтоб при любом удобном случае их нарушать», но я просто скажу SOLID никакая не панацея, и в определённых ситуациях чем-то можно пожертвовать, не сильно в ущерб, и уж тем более полностью забивать не стоит, просто мозг надо включать. К тебе единственная претензия — неверная интерпретация, ладно бы ты у себя в проектах это разводил, но ты(и тебе подобные) вываливают это непереработанную кашу на неокрепшие умы лорчан, которые только начинают свой путь в программирование.

anonymous
()
Ответ на: комментарий от WitcherGeralt

а если нужен будет класс РоетНору ?

anonymous
()
Ответ на: комментарий от anonymous

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

Для меня «ящик» прозрачный, как и для всех остальных разработчиков, и это не «ящик», а «ящики», и где надо, они так же обращаются через интерфейс/протокол/контракт или вообще сообщения.

Варианты "принципы SOLID не универсальны и должны быть избирательно применяемы" или даже "принципы SOLID мало где применимы и о них нужно просто иногда вспоминать" меня вполне устраивают - я не против такого подхода. Просто здесь есть люди, которые готовы себя бить в грудь и кричать «только SOLID и ничего другого».

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

Не я неверно интерпретирую теорию, а те, кто декларируют, что якобы используют принципы SOLID.

общий код работает в соответствии с принципом, как это не странно Лисков, ему вообще по барабану, что там сверху навесили на наследника, он дёргает только известные ему ручки, а наследник, открытые ему.

Еще один человек не понимает разницы между наследованием и подтипизацией по Лисков. А ведь солидную часть треда именно об этом тёрли.

И ладно ещё бы ты был знаком с понятиями «стратегий» и «посетителей», но вам кроме того же сложно держать больше одной иерархии, а когда у вас ещё пойдут параллельно иерархии стратегий посреди иерархий объектов, вы вообще в осадок выпадете.

То, что у здорового человека пишется в 10 строчек, у курильщика паттернов пишется в 10 классов. А потом курильщик хвастается, мол «смотрите, как я такую сложную систему сумел просто организовать благодаря паттерну „посетитель“». Я прямо сейчас с таким укурком работаю, который код детсадового уровня сложности, выполняющий единую функцию и умещающийся на одном экране, размазывает по десятку файлов так, что хрен прочитаешь это потом. А ведь если просто выкинуть из реализации понятие «класс» и оставить голые функции с данными, то описание структуры алгоримтов (без реализации) сократится эдак раза в три, таким образом при написании и поддержке этого кода экономя силы кодеров, которые не будут отвлечены бессмысленными абстракциями.

Классический посетитель выбирает функции под 2 полиморфных аргумента - удачи строить иерархии посетителя под 3-4 полиморфных аргумента.

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

Тогда зачем оно наследование, а не отдельные реализации? Если это наследование интерфейса, то тут всё чисто и по ISP+DIP, но это обычно не зовется наследованием. А наследованием зовется зависимость конкретных реализаций от общей базовой реализации, пусть и кто-то решил оправдать это, придумав «тот же слой абстракции».

в большинстве случаев иерархия объектов вообще существует и работает в одном и том же месте и потому они и обладают естественной зависимостью и связностью

И потому является единственным классом/функцией/модулем/единицанэймом.

я просто скажу SOLID никакая не панацея, и в определённых ситуациях чем-то можно пожертвовать, не сильно в ущерб, и уж тем более полностью забивать не стоит, просто мозг надо включать. К тебе единственная претензия — неверная интерпретация

И у меня к тебе претензия: ты утверждаешь, что есть какая-то единая интерпретация SOLID, хотя тут полтреда обсуждают, как вообще нужно интерпретировать подтипизацию Лисков, насколько жестко должно быть интерпретировано понятие корректности/желаемых функций. Это как Библия: кто-то что-то сказал 2000 лет назад, кто-то спустя 500 лет это записал, а теперь люди сидят и рассказывают, какое же должно быть единственное верное трактование священного писания. SOLID и стал этой самой библией для ООП, адово перевираемой каждым трактовальщиком, но на самом деле неточной в самих своих истоках, которые и вовсе не претендовали на статус заповедей, но были прогрейжены до таковых адептами культа ООП, которым нужно оправдать творение очередного насилия над кодом следованием принципам SOLID.

byko3y ★★★★
()
Ответ на: комментарий от byko3y

Варианты «принципы SOLID не универсальны и должны быть избирательно применяемы» или даже «принципы SOLID мало где применимы и о них нужно просто иногда вспоминать» меня вполне устраивают - я не против такого подхода.

Как ты понял, мы тоже за первое, но помнить надо всегда.

Просто здесь есть люди, которые готовы себя бить в грудь и кричать «только SOLID и ничего другого». Не я неверно интерпретирую теорию, а те, кто декларируют, что якобы используют принципы SOLID.

Такие люди просто плохо представляют, что такое SOLID, но ты ведь тоже?

Еще один человек не понимает разницы между наследованием и подтипизацией по Лисков.

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

Тогда зачем оно наследование, а не отдельные реализации?

Потому что это подтипы, общая часть ничего не знает о конкретных реализациях, а только об основном типе, а отдельные реализации будут представлять собой глупый и бессмысленный копипаст, особенно если будет реализован повторно в нескольких модулях, ради чего? Чтоб у тебя был чистый контракт? А если не копипаст, а отдельные реализации, так вы ещё и ошибки наделаете разные, которых бы не было в общем типе при нормальной разработке. И потом, когда общую часть модифицируете по каким-то, и тип изменится, в наследниках будет меньше работы.

Если это наследование интерфейса, то тут всё чисто и по ISP+DIP, но это обычно не зовется наследованием.

Интерфейс реализуется, применяется, используется, ну или расширяется, но не наследуется, поэтому наследованием и не зовётся.

А наследованием зовется зависимость конкретных реализаций от общей базовой реализации, пусть и кто-то решил оправдать это, придумав «тот же слой абстракции».

Это не оправдание, а то, чем является DIP, так как он запрещает наследование только между слоями(да и вообще зависимость от конкретной реализации, что зачастую перебор, конечно, но в целом дельно), учите матчасть, а не рассказывайте сказки.

anonymous
()
Ответ на: комментарий от byko3y

в большинстве случаев иерархия объектов вообще существует и работает в одном и том же месте и потому они и обладают естественной зависимостью и связностью

И потому является единственным классом/функцией/модулем/единицанэймом.

А вот и нет, или иерархия, или иерархии, или единственным типом/классом/функцией/модулем/единицанэймом

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

Не утверждал, что единая, только то, что твоя интерпретация не совсем верная, то есть, что «SOLID и невозможно» потому что накладывает кучу негибких ограничений, но на поверку ограничения вызваны только твоей излишне строгой интерпретацией принципов. То есть зависимость от абстракции у тебя превращается в строго в зависимость только от интерфейса. Наследование по-твоему SOLID нельзя, потому что это зависимость от реализации, хотя пока они рядом и на одном уровне абстракции SOLIDу до этого нет никакого дела, ну а зависимостью можно пренебречь, пока не захочешь разнести, и то, сам тогда введёшь абстракцию/интерфейс.

А кроме тебя, тут ещё у отдельных личностей хрень вместо понимания «подтипизации Лисков»

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

В данном треде ты тоже выступаешь также на стороне экстремально-радикальных адовых перевирателей-трактовальщиков и насильников, если это специально избранная позиция, чтоб довести SOLID до абсурда в глазах других «адептов», то ладно. Но ни «слепцов», ни «перевирателей» я оправдывать не собираюсь. Как и пытаться переубедить, я думал, что тут просто «недопонимание», а тут — «позиция».

anonymous
()
Ответ на: комментарий от byko3y

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

То что у курильщика пишется через 10 if под двойным циклом, у здорового и адекватного продвинутого, а главное грамотного разработчика решается через один цикл, а if вообще вне цикла, а то и далеко от цикла, ещё и работает быстрее раз в 10-100, сложность алгоритма падает, да, наглядность может пропасть, с другой стороны классы и даже замыкания зачастую улучшают понимание конкретного кода, выбор делаю в первую очередь, если это улучшает сопровождаемость, и читаемость, хоть потом никакой наркоман не накидает ещё ифов. Хотя признаюсь, что я грешу, и даже там ввожу, где это может просто уcкорить код.

А ведь если просто выкинуть из реализации понятие «класс» и оставить голые функции с данными, то описание структуры алгоримтов (без реализации) сократится эдак раза в три, таким образом при написании и поддержке этого кода экономя силы кодеров, которые не будут отвлечены бессмысленными абстракциями.

Добро пожаловать в функциональное программирование!

Классический посетитель выбирает функции под 2 полиморфных аргумента - удачи строить иерархии посетителя под 3-4 полиморфных аргумента.

Классический посетитель нужен для выноса алгоритма, который в самом типе привносит лишнею ответственность, а нужен в нескольких малосвязанных типах и/или коллекций типов, и в котором есть явный общий типонезависимый код, в некоторых случаях может срабатывать как антипаттерн, поскольку начинает сам зависеть от нескольких типов. Иерархия посетителей нужна при некоторых изменениях небольших изменения алгоритма, но основной код посетителей иерархии разделяем, а потому получаем подти.

anonymous
()
Ответ на: комментарий от anonymous

Такие люди просто плохо представляют, что такое SOLID, но ты ведь тоже?

Да. Я относительно слабо разбираюсь в этом священном писании, но очень хорошо разбираюсь в прикладном софтостроении. Почему-то хорошо в принципах SOLID обычно разбирается тот, кто софта не пишет, что есть весьма подозрительно, не находишь? А основные пользователи SOLID - это люди, которые не умеют писать код, но еду где-то нужно добывать, и вот на вопрос о том, почему результата до сих пор нет, отвечать «вот же ж, у нас всё по SOLID, всё безупречно по статическим анализаторам - просто дайте нам еще совсем чуть-чуть времени». Но в очередной итерации это уже не прокатывает, и обмудка выгоняют мести двор - что соответствует его квалификации. Этот спектакль прямо сейчас передо мной разыгрывается - потому я так и горю. Просто пар выпускаю.

будем называть это системой подтипов с семантической точки зрения, только с точки зрения языка это остаётся реализованным через наследование

Интерфейс, реализованный двумя независимыми классами, которые оба соблюдают требования клиента - вот пример двух классов, которые станут типом-подтипом по Лисков, если один из классов будет написан до клиента, а другой - после. Экземпляр объекта с разными сокрытыми значениями полей будет опять-таки давать тип-подтип при условии соблюдения корректности работы программы до и после.

В хороших языках программирования типом-подтипом может выступать банальная функция. В ублюдочных же языках, вроде Java/C#, программист для вынужден для построения аналогичной конструкции делать интерфейс и реализовывать его в двух классах - в итоге получаем 3 файла вместо трех строк.

общая часть ничего не знает о конкретных реализациях, а только об основном типе

Потому что это подтипы, общая часть ничего не знает о конкретных реализациях, а только об основном типе, а отдельные реализации будут представлять собой глупый и бессмысленный копипаст, особенно если будет реализован повторно в нескольких модулях, ради чего? Чтоб у тебя был чистый контракт? А если не копипаст, а отдельные реализации, так вы ещё и ошибки наделаете разные, которых бы не было в общем типе при нормальной разработке. И потом, когда общую часть модифицируете по каким-то, и тип изменится, в наследниках будет меньше работы.

Классическая проблема наследования: изменили что-то в базовом классе - отвалился наследник. Такие ошибки тяжело ловить уже в средней сложности системе (10к+ строк). А проблема из-за того, что в абстракцию протекли куски реализации. А чистую абстракцию использовать нельзя, потому что Java/C#/C++ в классах ущербны и не предоставляют более эффективных механизмов ораганизации, и в итоге ты стоишь перед осознанием того, что если будешь безупречно следовать SOLID, то твой проект станет нечитаемым и неподдерживаемым.

Это не оправдание, а то, чем является DIP, так как он запрещает наследование только между слоями(да и вообще зависимость от конкретной реализации, что зачастую перебор, конечно, но в целом дельно), учите матчасть, а не рассказывайте сказки.

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

byko3y ★★★★
()
Ответ на: комментарий от anonymous

в большинстве случаев иерархия объектов вообще существует и работает в одном и том же месте и потому они и обладают естественной зависимостью и связностью

И потому является единственным классом/функцией/модулем/единицанэймом.

А вот и нет, или иерархия, или иерархии, или единственным типом/классом/функцией/модулем/единицанэймом
...
Наследование по-твоему SOLID нельзя, потому что это зависимость от реализации, хотя пока они рядом и на одном уровне абстракции SOLIDу до этого нет никакого дела, ну а зависимостью можно пренебречь

Еще раз: ты писал про то, что связанный функционал не подлежит подчинению принципам ISP и DIP, потому что он связан, един, потому ему не нужны интерфейсы и абстракции. К слову, некоторые относят SRP к модулям, потому докатывается до того, что функционал разбросан по нескольким модулям с тесными запутанными связями, но приводить к ISP/DIP не смей, даже если связанног офункционала оказалось много, потому что цельный функционал и подлежит избирательному применению SOLID, то есть: когда хочу, тогда и применяю.

но на поверку ограничения вызваны только твоей излишне строгой интерпретацией принципов.

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

То есть зависимость от абстракции у тебя превращается в строго в зависимость только от интерфейса

Ублюдочные языки просто не предоставляют других инструментов абстракции. Вообще, средств абстракции бывает много, на самом деле.

это специально избранная позиция, чтоб довести SOLID до абсурда в глазах других «адептов», то ладно

Бинго. Только принципы SOLID - это и есть абсурд, просто мало кто пытается их придерживаться.

byko3y ★★★★
()
Ответ на: комментарий от anonymous

То что у курильщика пишется через 10 if под двойным циклом, у здорового и адекватного продвинутого, а главное грамотного разработчика решается через один цикл, а if вообще вне цикла, а то и далеко от цикла, ещё и работает быстрее раз в 10-100

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

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

Добро пожаловать в функциональное программирование!

А мы отсюда никуда не уходили.

Классический посетитель нужен для выноса алгоритма, который в самом типе привносит лишнею ответственность, а нужен в нескольких малосвязанных типах и/или коллекций типов, и в котором есть явный общий типонезависимый код, в некоторых случаях может срабатывать как антипаттерн, поскольку начинает сам зависеть от нескольких типов. Иерархия посетителей нужна при некоторых изменениях небольших изменения алгоритма, но основной код посетителей иерархии разделяем

Всё, что ты нагородил, можно написать одной фразой: ad-hoc полиморфизм по двум аргументам. То есть, выбор конкретной функции по сочетанию конкретных двух типов, в данном случае тип-данные и тип-операция. Насколько проста задача, и в какой адовый кошмар ее превращает паттерн «посетитель»: «маслосвязанный код», «вынос алгоритма», «типонезависимый код», «основной код иерархии посетителей разделяем» - тьфу.

byko3y ★★★★
()
Ответ на: комментарий от WitcherGeralt

Ну вы упоротые, уже три недели срётесь на тему, которая выеденного яйца не стоит.

Так об этом и спорим же ж. Одни считают, что стоит, вторые - что нет.

byko3y ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.