Это я привел пример САМОЙ ПРИЕМЛЕМОЙ модели. По факту вообще не надо делать никакой гавкающей собаки, так как ее невозможно смоделировать сколько-нибудь приближенно к реальному миру. А раз уж очень хочется, то пусть это будет что-то, что создают ее голосовые связки контактируя с воздухом среды и больше ни с чем. :) Условная вибрация воздуха, спектрограмма. Такая себе jailed-dog. Но если нам ничего не нужно будет кроме самого звука от этой собаки, то не фантазировать лишних абстракций, а реализовать именно генерацию аудио и на этом остановиться.
Я бы для более ясного примера предложил вариант, что "сферическая собака в вакууме" должна вернуть WAV файл. Но по неймингу я согласен с комментом выше. :) Например (не идеально), audio = dog.createBarkingWAV() А дальше это audio уже используй, накладывай куда угодно, проигрывай...
Почему не просто глагол bark()? Просто глагол подразумевает выполнение действия, команда. Но мы ж не делегируем собаке таких полномочий (хоть многие этим и излишне увлекаются, запутывая всю логику).
Правильным применением ООП печатание на консоль из собаки все равно не становится. Как и rectangle.draw(), когда фигура сама себя рисует на экране.
Отож. А потом сидят и думают ... "кто нам ком стоял" (с). :) И не могут эту связанность потом распутать.
Я так понимаю, главная причина появления этой каши в том, что многие пытаются моделировать объекты реального мира. Хотя им чаще всего нужно всего лишь разделить зоны ответственности кода (функционал) и продумать интерфейс взаимодействия этих функциональных модулей.
Та это все понятно. Мы ж про другое беседуем. Я про то, что не нужно именованные классы вводить там, где их не существует по смыслу. Но, конечно, это не касается языков, где по-другому ты просто не можешь сделать (Java/C#). :) Если язык позволяет создавать модуль -- его логичней всего и создавать в такой ситуации.
Нет, я про юнит-тесты своего кода. Интеграционные это если бы я на реальный диск писал.
Ну тут вопрос в терминологии. :) Для меня юнит-тест (тест модуля) -- это чистый тест функции обработчик_сценария_когда_диск_заполнен() без "дергания" другого юнита (модуля file_worker). Если его "дергаем", то это уже интеграция двух наших модулей (главный и "файловый").
Ну да не важно.
Ну и зачем нужны эти сложности, если можно просто использовать объекты? Судя по этой записи, file_worker это самый настоящий объект. Ну так о том и речь, что их удобно использовать.
Конечно можно назвать его объектом. Только классов тут никаких нет. :) Никакого мусорного лишнего кода и ненужных абстракций. Ни в главном коде, ни в модуле file_worker.
Или вообще реализация отладочного функционала в модуле file_worker. Мало ли, вдруг хочется имитировать различные сценарии дисковых ошибок. Тогда вот так одной строчкой "включаем" необходимый сценарий для тестирования, не засоряя наш основной код "чужим функционалом", не смешивая логику.
передаю отдельный "привет" питонщикам с ихним бл$дь self через слово)
:) Так и питонщики сами тихо офигевают, когда видят чей-то код, загаженный классами там, где реально нет никаких классов. Прочитай тут статью "Перестаньте писать классы", например.
Все так. Классы нужно/можно использовать только там, где есть реально динамическое число объектов одного рода, имеющих свои данные. Если это разделение функционала, то это банальный отдельный модуль (без всяких классов).
Так в том и смысл, чтобы минимизировать связанность. Тестировать нужно отдельно сам модуль.
А про текст ниже -- не понял вопрос. У нас тут никаких объектов нет, есть использование функционала из внешнего модуля. Импортируем модуль, вызываем file_worker.save_all(_данные_нашего_компонента), где ошибку получаем через res/err = file_worker.save_all, либо try cach, в зависимости от языка и реализации.
Да, но с каждым проектом набираешь же опыт и становишься более эффективным, не теряя время на размышление/проектирование странных, ненужных и неуместных вещей, которые не привносят ничего полезного. Либо наоборот, заранее понимая, куда нужно подстилать соломку.
Я могу сравнивать только время и усилия, которые были затрачены, не думаю что это показатель чего-либо.
Почему не показатель? Вполне себе показатель. Не все могут реально сравнивать подходы. Делают лишь "потому что так надо". Или не умеют по-другому. Или язык "заставляет".
А ты (как заказчик и разработчик в одном лице) можешь оценить и время разработки, и ментальную нагрузку на проектирование, написание и сопровождение кода.
споры про класс собаки и то как именно работать с её лаем и очень хорошо видно что даже те кто пользуется ООП (или так думает) не имеют консенсуса.
Именно. :)
Если я хочу вывести на экран "bark", то я это делаю, мне не нужен класс или метод для этого.
Эх, а мог бы создать бригаду строителей, приставил бы к ним наблюдателя. Они бы построили абстрактную фабрику по производству различных прототипов собачек, которые умеют разное. Лаять, прыгать, кусать, писать код. Написал бы адаптер для собачек, чтобы они умели лаять на экран.
В общем, вот это вот все делать... Лишь бы не работать. :)
Это уже модульная архитектура. Функционал сгруппирован по отдельным модулям. Не нужен никакой "один объект" какого-то там класса.
Второй повод применения ООП
Да, я бы чуть упростил формулировку до "при написании UI интерфейсов". Вот там все по полной программе раскрывается.
Третий способ (который так и не понял)
... Если это "записи" без поведения, вопросов нет.
Для работы с данными вообще лучше функциональный подход. На входе "запись" и на выходе "запись". И ряд функций, работающих с этими данными, которые можно группировать как угодно в конвейеры.
Если данные с поведением, не представляю как это сделать не усложнив все неимоверно. Если кто-то умеет, можете описать.
А часто -- никак, просто потому, что это не имеет никакого смысла. :) Начинаются фантазии на тему -- это комната добавляет в себя собаку, или собака добавляется сама в комнату. И потом никогда не разберешься "кто нам ком стоял", и почему хвост виляет собакой.
По факту мы имеем замаскированное под ООП обычное процедурное программирование с модулями
Ха. :) То же самое как раз выше написал. :)
А вот что реально дает другой экспириенс, так это частичное использование функционального подхода (как же приятно читается потом что-то типа res -> func1 func2 func3, если у нас есть объект (в виде данных) и серия операций над этим объектом).
Да нет, все ты правильно понимаешь. :) Когда ты пишешь для себя, сам же и поддерживаешь, то лучше замечаешь все плюсы и минусы подходов. И тебе сложнее голову задурить, если ты сам попробовал и так, и сяк, и можешь сравнивать.
Просто часто ООП используется как способ упаковки обычного процедурного кода в дикую лапшу, где ненужные абстракция на абстракции и абстракцией погоняет. А в нейтральных случаях это просто имитация модульного разделения функционала. :)
К счастью, не все языки заставляют такое упаковывать в классы. :) Для подавляющего числа случаев тут логичнее выделять функционал в МОДУЛЬ, а не чесать левое ухо правой рукой (статические классы / синглтоны).
А вот если по смыслу у нас есть реальные объекты (множественное число), тогда и классы использовать.
О да! :) После Х лет на Питоне возвращался к Си, чтобы прошивку написать для esp8266. Ох как я плевался первые дни, снова "перекладывая байтики/строки". Такое ощущение траты времени... Как будто пришлось тонны текста набирать на экране телефона одним пальцем.
Ха. А я думал тут будет про то, как надо плавно менять подход к обучению и тренировкам с возрастом, где 25 -- это примерный ориентир, после которого старые схемы работают не эффективно. Andrew Huberman очень интересно рассказывает про нейропластичность, alertness, фокусировку и все остальное. Можно искать его подкасты по наличию слова SKILLS, насколько я помню. Хотя там большинство очень полезных.
С чего ему садиться? :) Там наоборот глаза работают, фокусное расстояние всегда меняется. А при мониторе/книжке/телефоне -- наоборот, фиксируется на одной дистанции.
Ха! У меня тоже такие рекламки есть. Я в те времена из газеты вырезал и в блокнотик себе клеил. :)
Это я привел пример САМОЙ ПРИЕМЛЕМОЙ модели. По факту вообще не надо делать никакой гавкающей собаки, так как ее невозможно смоделировать сколько-нибудь приближенно к реальному миру. А раз уж очень хочется, то пусть это будет что-то, что создают ее голосовые связки контактируя с воздухом среды и больше ни с чем. :) Условная вибрация воздуха, спектрограмма. Такая себе jailed-dog. Но если нам ничего не нужно будет кроме самого звука от этой собаки, то не фантазировать лишних абстракций, а реализовать именно генерацию аудио и на этом остановиться.
Я бы для более ясного примера предложил вариант, что "сферическая собака в вакууме" должна вернуть WAV файл. Но по неймингу я согласен с комментом выше. :) Например (не идеально), audio = dog.createBarkingWAV() А дальше это audio уже используй, накладывай куда угодно, проигрывай...
Почему не просто глагол bark()? Просто глагол подразумевает выполнение действия, команда. Но мы ж не делегируем собаке таких полномочий (хоть многие этим и излишне увлекаются, запутывая всю логику).
Отож. А потом сидят и думают ... "кто нам ком стоял" (с). :) И не могут эту связанность потом распутать.
Я так понимаю, главная причина появления этой каши в том, что многие пытаются моделировать объекты реального мира. Хотя им чаще всего нужно всего лишь разделить зоны ответственности кода (функционал) и продумать интерфейс взаимодействия этих функциональных модулей.
Та это все понятно. Мы ж про другое беседуем. Я про то, что не нужно именованные классы вводить там, где их не существует по смыслу. Но, конечно, это не касается языков, где по-другому ты просто не можешь сделать (Java/C#). :) Если язык позволяет создавать модуль -- его логичней всего и создавать в такой ситуации.
Ну тут вопрос в терминологии. :) Для меня юнит-тест (тест модуля) -- это чистый тест функции обработчик_сценария_когда_диск_заполнен() без "дергания" другого юнита (модуля file_worker). Если его "дергаем", то это уже интеграция двух наших модулей (главный и "файловый").
Ну да не важно.
Конечно можно назвать его объектом. Только классов тут никаких нет. :) Никакого мусорного лишнего кода и ненужных абстракций. Ни в главном коде, ни в модуле file_worker.
Аааа, вот ты про что. Ты про интеграционные тесты. Допустим, твой основной код выглядит как-то так:
И, как я понял, тебе мало модульных тестов (тестирования конкретного вызова "обработчик_этого_сценария() ").
Тогда тут уже зависит от желаемой глубины этой интеграции. Или простая строчка для подмены функции:
Или вообще реализация отладочного функционала в модуле file_worker. Мало ли, вдруг хочется имитировать различные сценарии дисковых ошибок. Тогда вот так одной строчкой "включаем" необходимый сценарий для тестирования, не засоряя наш основной код "чужим функционалом", не смешивая логику.
:) Так и питонщики сами тихо офигевают, когда видят чей-то код, загаженный классами там, где реально нет никаких классов. Прочитай тут статью "Перестаньте писать классы", например.
Все так. Классы нужно/можно использовать только там, где есть реально динамическое число объектов одного рода, имеющих свои данные. Если это разделение функционала, то это банальный отдельный модуль (без всяких классов).
Так в том и смысл, чтобы минимизировать связанность. Тестировать нужно отдельно сам модуль.
А про текст ниже -- не понял вопрос. У нас тут никаких объектов нет, есть использование функционала из внешнего модуля. Импортируем модуль, вызываем file_worker.save_all(_данные_нашего_компонента), где ошибку получаем через res/err = file_worker.save_all, либо try cach, в зависимости от языка и реализации.
Да, но с каждым проектом набираешь же опыт и становишься более эффективным, не теряя время на размышление/проектирование странных, ненужных и неуместных вещей, которые не привносят ничего полезного. Либо наоборот, заранее понимая, куда нужно подстилать соломку.
Почему не показатель? Вполне себе показатель. Не все могут реально сравнивать подходы. Делают лишь "потому что так надо". Или не умеют по-другому. Или язык "заставляет".
А ты (как заказчик и разработчик в одном лице) можешь оценить и время разработки, и ментальную нагрузку на проектирование, написание и сопровождение кода.
Именно. :)
Эх, а мог бы создать бригаду строителей, приставил бы к ним наблюдателя. Они бы построили абстрактную фабрику по производству различных прототипов собачек, которые умеют разное. Лаять, прыгать, кусать, писать код. Написал бы адаптер для собачек, чтобы они умели лаять на экран.
В общем, вот это вот все делать... Лишь бы не работать. :)
Это уже модульная архитектура. Функционал сгруппирован по отдельным модулям. Не нужен никакой "один объект" какого-то там класса.
Да, я бы чуть упростил формулировку до "при написании UI интерфейсов". Вот там все по полной программе раскрывается.
Для работы с данными вообще лучше функциональный подход. На входе "запись" и на выходе "запись". И ряд функций, работающих с этими данными, которые можно группировать как угодно в конвейеры.
А часто -- никак, просто потому, что это не имеет никакого смысла. :) Начинаются фантазии на тему -- это комната добавляет в себя собаку, или собака добавляется сама в комнату. И потом никогда не разберешься "кто нам ком стоял", и почему хвост виляет собакой.
Ха. :) То же самое как раз выше написал. :)
А вот что реально дает другой экспириенс, так это частичное использование функционального подхода (как же приятно читается потом что-то типа res -> func1 func2 func3, если у нас есть объект (в виде данных) и серия операций над этим объектом).
Или closure (~LISP). Прогонять данные через цепочку функций для мозга тоже намного логичней. https://habr.com/ru/articles/761326/comments/#comment_25970952
Да нет, все ты правильно понимаешь. :) Когда ты пишешь для себя, сам же и поддерживаешь, то лучше замечаешь все плюсы и минусы подходов. И тебе сложнее голову задурить, если ты сам попробовал и так, и сяк, и можешь сравнивать.
Просто часто ООП используется как способ упаковки обычного процедурного кода в дикую лапшу, где ненужные абстракция на абстракции и абстракцией погоняет. А в нейтральных случаях это просто имитация модульного разделения функционала. :)
К счастью, не все языки заставляют такое упаковывать в классы. :) Для подавляющего числа случаев тут логичнее выделять функционал в МОДУЛЬ, а не чесать левое ухо правой рукой (статические классы / синглтоны).
А вот если по смыслу у нас есть реальные объекты (множественное число), тогда и классы использовать.
О да! :) После Х лет на Питоне возвращался к Си, чтобы прошивку написать для esp8266. Ох как я плевался первые дни, снова "перекладывая байтики/строки". Такое ощущение траты времени... Как будто пришлось тонны текста набирать на экране телефона одним пальцем.
Вот, кстати, NIM как раз хорош тем, что можно записать и так и так:
len(L)
L.len()
и даже:
len L
Выбираешь тот вариант, который лучше с точки зрения читаемости кода именно в данном контексте.
Ха. А я думал тут будет про то, как надо плавно менять подход к обучению и тренировкам с возрастом, где 25 -- это примерный ориентир, после которого старые схемы работают не эффективно. Andrew Huberman очень интересно рассказывает про нейропластичность, alertness, фокусировку и все остальное. Можно искать его подкасты по наличию слова SKILLS, насколько я помню. Хотя там большинство очень полезных.
С чего ему садиться? :) Там наоборот глаза работают, фокусное расстояние всегда меняется. А при мониторе/книжке/телефоне -- наоборот, фиксируется на одной дистанции.