LINUX.ORG.RU

Степень объектной ориентированности отрицательно коррелирует с легкостью тестирования

 , ,


0

2

Всегда когда пытался постичь ООП, натыкался на то, что фиг потестишь его. Везде какое-то дурацкое ненужное состояние, надо создавать объекты, и всё такое. То ли дело функции. И вот, какая-то случайная статейка из интернета со мной согласна http://osherove.com/blog/2007/2/25/why-you-should-think-about-toop-testable-o...

Можно ли писать ООП без таких недостатков?

В ООП хорошо не само ООП, а модульность, изоляция частей кода. Это можно получить и без ООП.

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

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

callbackhell
()

ООП с классами и наследованием — дурно продуманный язык. Есть единственное важное свойство — полиморфизм, а все остальное в ООП с классами является простым следствием глупости инженеришек: концепции дело не их, а математиков. Инженерный подход в построениях базовых понятий не работает, инженерам не хватает абстрактного мышления для этого.

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

все остальное в ООП с классами является простым следствием глупости инженеришек: концепции дело не их, а математиков

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

tailgunner ★★★★★
()

Где ты там нашёл про отрицательную корреляцию? Я бегло взглянул - там как раз про то, как именно ООП сделать тестируемым.

И я не так давно занимался ревизией спагетти-кода, где всё было свалено в mainwindow.cpp. После того, как я убедил автора порезать код на классы и примерно объяснил, на какие, код, ВНЕЗАПНО, стал тестируемым.

ООП - хороший способ держать большой код под контролем. Ну и есть задачи, которые сами по себе на него накладываются 1:1, то же оконное GUI, например.

А то, что ООП ради ООП никому не нужно (как, например, и ФП ради ФП) - так с этим никто не спорит.

Везде какое-то дурацкое ненужное состояние, надо создавать объекты, и всё такое. То ли дело функции.

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

ООП - это рабочий инструмент, не надо его ни обожествлять, ни демонизировать.

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

В ООП хорошо само ООП.

По-моему не нужно.

Порождение абстракций, DSL, короткий лаконичный код

Нужно, но возможно без ООП.

метаобъекты

Что это такое и зачем?

хорошее тестирование, быстрое прототипирование, абстракция состояния, поведения.

Можно без ООП

Но это только в ООП, не в жабе, не в плюсах, не в решетках, а именно в ООП.

Нет, из этого в ООП только объекты (и видимо метаобъекты), которые не нужны, а всё остальное можно реализовать без ООП.

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

После того, как я убедил автора порезать код на классы и примерно объяснил, на какие, код, ВНЕЗАПНО, стал тестируемым.

Чем хуже было порезать код на изолированные модули, которые вовсе не обязаны быть классами? Само ООП тут не причём. Это просто один из способов реализации модульности, и вероятно не самый лучший.

Пример из JavaScript: match — это метод регекспа, параметр которого строка, text, exec — методы строки, параметр которых — регексп. Уже сама возможность такой путаницы показывают, что объекты — весьма произвольная абстракция.

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

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

Замену ооп можно частично покрыть ФВП, или прости господи указателями на функции, иначе опаньки и поведение ты никак не передашь. Просто ООП пошел немного дальше и предложил сахарок для хранения стейта и привязку нескольких поведений (методов) к одной сущности. Принципиально ничего не поменялось. Противопоставлять ООП чему-то другому это тотальная глупость.

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

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

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

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

В ряде случаев этого действительно достаточно. И если я правильно понял пример с регэкспом, там бы хватило и функций, особенно если учесть, что отдельный регэксп - это, по сути, строка. С другой стороны, те же регэкспы иногда используются не только для проверки соответствия, а ещё и для вычленения из текста целой порции разнородных данных (в перле, например, я пишу m/, а потом считываю переменные $1, $2 и др.). И вот в этом случае запись в виде функции (не на перле, а на более традиционном языке) будет, вероятно, менее очевидна, чем в виде объекта.

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

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

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

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

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

что отдельный регэксп - это, по сути, строка.

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

A1
()

Мне практика показала, что нормально спроектированные классы легко тестить. А вот зашитые или очень большие сложно. А так обычно mock-mock и готово. Вообще мне кажется, что всё это нытьё вокруг ООП от неосиляторства.

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

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

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

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

ООП пошел немного дальше и предложил сахарок для хранения стейта и привязку нескольких поведений (методов) к одной сущности.

Это не классическое ООП, а,так сказать, OOP-lite, которое продвигается в языках вроде Rust (и Go?) - с трейтами/интерфейсами, но без наследования.

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

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

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

A1
()

Я тут много пишу на этой нашей жабке, со всякими Spring-ами и прочим DI и могу сказать, что в современном мире классический ООП не встречается, классы используются больше как способы группировки функций, namespace-ы, если угодно, обычно объект сервис - это Singleton (в Spring любой бин синглетон по-умолчанию). Плюс пачка DTO объектов, которые по сути тупо структуры.

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

Так вот. Есть язык, который реализует этот паттерн идекально - Go. Именно такой подход там с этими их package-ами, структурами и прочим добром. И никаким ООП тут не пахнет.

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

Это правда, не классическое, и слава богу.

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

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

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

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

Я и говорю что мода не СОКРЫТИЕ сильна. В жабке кстати сделали клевую вещь про видимость из пакета, там нет такого гимора с тестированием.

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

Это по сути конечный автомат, который еще надо из строки сделать.

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

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

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

Беда в том, что вы несете абсолютную ахинею. И вы не одиноки.

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

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

Singleton - это то, что в приличных языках называют «модуль» :)

идекально

Тонко.

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

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

По-моему чисто синтаксически более «объёмно» потом состояние везде гнать в качестве параметра. С инстансами лаконичнее выходит, IMHO.

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

Vit ★★★★★
()
Последнее исправление: Vit (всего исправлений: 2)
Ответ на: комментарий от eao197

Беда в том, что вы несете абсолютную ахинею. И вы не одиноки.

Беда в том что вы остались в 90х и думаете что методы тех времен позволяют делать рабочий софт сегодня. Да, остались ниши которые позволяют применять civil engineering, и вы можете свысока смотреть на оголтелую школоту, но основные деньги уже не там.

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

Это правда просто очепятка, щас пофикшу (а нет, уже не пофикшу).

Да, именно к этому я и веду, по сути современная разработка сошлась к модулям-наборам функций + структуры для переноски данных.

Иногда применяется AOP, то есть еще хотелось бы от языка поддержки чего-то похожего на делегаты для выполнения кода в стиле «а вот перед вызовом этой функции» или «а вот если вот это поле меняют». Мой поинт о том, что это далеко от ООП и как-то естественным образом уходит все дальше и дальше.

DiKeert ★★
()
Последнее исправление: DiKeert (всего исправлений: 2)
Ответ на: комментарий от A1

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

А вот то, что обсуждая ООП вы говорите об ООП ерунду — это печально. Т.к. не зная предмета обсуждения, вы не знаете, от чего отказываетесь.

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

Прибыльность той или иной прикладной ниши не имеет отношения к теме простоты тестирования написанного в соответствии с принципами ООП кода.

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

Тем более, что если говорить о деньгах, то основные деньги не в разработке софта и никогда там не были.

Вы лекарства делаете на ООП?

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

Мой 15-ти летний опыт позволяет отказываться от того что не решает текущих проблем. А у вас или проблемы остались старыми или вы слишком примерный утенок.

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

вы можете свысока смотреть на оголтелую школоту

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

и как после такого на эту «школоту» смотреть?

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

А это каким боком?

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

Вы лекарства делаете на ООП?

Опять какой-то феерический бред.

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

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

Простите мне мой французский, но 25 лет назад нам это объясняли чуть ли не на первом курсе ВУЗа. Еще до того, как про ООП узнали в наших Палестинах.

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

Ваши же высказывания об ООП говорят о том, что об ООП вы не знаете. Следовательно, ваши высказывания об ООП выглядят феерическим бредом.

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

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

Vit ★★★★★
()

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

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

Мне непонятно, зачем вы это сделали.

Помоему я дал исчерпывающее объяснение. Вы сегодня исключиельно хорошо прикидываетесь дурачком. Деньги ушли в облась где надо фичи выкатывать быстро и часто. Методика разработки другая и инструменты другие. Вот так даже anonimus поймет.

Опять какой-то феерический бред.

Разжую опять. Мы можем привлекать деньги как меру по отрасли. Аргумент «а вот у других дядь их больше» глупый и вам не к лицу.

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

Я дошел до этой мысли не в этом году, опять мимо.

Ваши же высказывания об ООП говорят о том, что об ООП вы не знаете.

Все мои высказывания об ООП даются исключительно в контексте сегодняшнего момента. То что у вас возникла обида за любимого идола не моя проблема.

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

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

Школоте глубоко насрать как на нее смотрят.

Дык, созерцая, как правило, обратной реакции ни кто и не ждёт... ;)

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

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

И вы можете это подтвердить чем-либо?

Мы можем привлекать деньги как меру по отрасли.

Как эта мера по отрасли может подтвердить или опровергнуть ваше высказывание «как-то так получилось что инкапсуляция и наследование стали отожествляться с private и иерархией классов и завертелось»?

То что у вас возникла обида за любимого идола не моя проблема.

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

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

Интересно, как в вашем миропредставлении соотносятся понятия модуля (module) и экземпляра (instance)?

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

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

Никаких инстансов.

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

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

Вообще, жду, когда в C++ наконец-то запилят поддержку нормальной модульности.

А зачем ждать, если уже есть OCaml или, на худой конец, D?

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

А зачем городить структуры? Просто импортировать модуль, в котором определены какие-то новые функции и типы данных.

С другой стороны, те же регэкспы иногда используются не только для проверки соответствия, а ещё и для вычленения из текста целой порции разнородных данных (в перле, например, я пишу m/, а потом считываю переменные $1, $2 и др.).

Просто возвращать список совпадений. Что в этом такого? Да, среди перечисленных мной такая есть.

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

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

Ну создаёшь списки ip-адресов, затем применяешь к ним списочные функции например. Что не понятно?

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

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

Ну создаёшь списки ip-адресов, затем применяешь к ним списочные функции например. Что не понятно?

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

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

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

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

типы данных

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

Насколько я понимаю, на примере с IP-адресами тебе пытались объяснить именно это. И IP-адреса явно не самый сложный случай.

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

на примере с IP-адресами тебе пытались объяснить именно это.

Именно.

Такое впечатление, что Xenius пытается пропагандировать подход из Modula-2 и Turbo Pascal (в который были добавлены unit-ы). Только там, ЕМИНП, структуры были полностью открыты и любой дятел мог влезть в экземпляр чужой структуры и поменять любое поле.

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

Тот же IP-адрес представляет из себя структуру из нескольких полей.

Ну сделать несколько функций, которые извлекают из ip-адреса его элементы, например.

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

и Turbo Pascal (в который были добавлены unit-ы)

Кстати, с unit-ами в Turbo Pascal очень даже неплохо получилось. Только потом всё равно появились object и class. Поскольку модули и классы - это не взаимоисключающие, а взаимодополняющие концепции. С первым лучше в объектном паскале (ну и в Модуле, разумеется), со вторым - в крестах.

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

Поскольку модули и классы - это не взаимоисключающие, а взаимодополняющие концепции.

Именно.

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

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

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