Форум программистов, компьютерный форум, киберфорум
ООП и паттерны
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
Результаты опроса: используете ли вы ооп
да 238 86.55%
нет 37 13.45%
Голосовавшие: 275. Вы ещё не голосовали в этом опросе

 
 
Рейтинг 4.76/461: Рейтинг темы: голосов - 461, средняя оценка - 4.76
81 / 39 / 3
Регистрация: 29.01.2010
Сообщений: 386

Стоит ли использовать ООП?

09.02.2010, 13:44. Показов 103122. Ответов 793
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте.
Возник такой вопрос: стоит ли использовать ооп. Даже не так, когда использовать ооп?
Иногда (даже чаще всего) легче написать простые функции, а не мутить с классами обектами и методами.
Раздражает инкапсуляция - какой вообще ее смысл? Чтобы получить переменную класса по правилам ооп нужно создавать метод для ее чтения? когда такой подход оправдан - ведь затрачивается куча лишнего времени.
5
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
09.02.2010, 13:44
Ответы с готовыми решениями:

Стоит ли использовать ООП -- часть вторая
У людей задающих подобные вопросы не все в порядке с пониманием ООП. Например, в параллельной теме человек интересуется: На самом...

Какие РЕАЛЬНО есть причины НЕ использовать ООП?
Появился такой вопрос. Все мы знаем о шумихе вокруг ООП, спорной идее наследования, других невнятных идей которых можно добиться...

Где стоит использовать bootstrap и стоит ли вообще использовать CSS фреймворки?
Здравствуйте. Лично я ужасаюсь ковырять стили, когда к сайту подключен bootstrap и мало понимаю, чем он хорош вообще. В данной теме я бы...

793
1977 / 833 / 115
Регистрация: 01.10.2012
Сообщений: 5,119
Записей в блоге: 2
02.01.2014, 16:34
Студворк — интернет-сервис помощи студентам
Анти-пример (из уважаемых исходников). Не дословно, суть
C++
1
2
3
4
5
6
7
8
9
10
class QPoint {
 public:
   int x( void ) const { return x; }
   int y( void ) const { return y; }
   int & rx( void ) { return x; }
   int & ry( void ) { return y; }
   void setX( int x ) { this->x = x; }
   void setY( int y ) { this->y = y; }
//.... и.т.д
};
Вот здесь IMO как раз public был бы "в жилу" т.к. ни один из аргументов в пользу геттеров/сеттеров не срабатывает. Вряд ли разработчики этого не понимали, вероятно просто была директива сверху типа "сделайте по канонам чтобы не возникало глупых квешнов"

Цитата Сообщение от Evg Посмотреть сообщение
В том числе. В отладчике можно поставить брейкпоинт на метод SetValue (или просто поставить printf) и оттрассировать все модификации
Для классов типа "точка", "вектор" подавляющее большинство операций (часто все) делаются операторами, поэтому трассирование сеттера ничего не дает.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
02.01.2014, 17:44
Цитата Сообщение от Nameless One Посмотреть сообщение
Что значит в данном случае «усложнённый доступ»?
Видимо, в том, что много букв надо писать. Т.е. вместо "a.x+=5", надо писать "a.set (a.get() + 5)"

Добавлено через 1 минуту
Цитата Сообщение от Igor3D Посмотреть сообщение
Для классов типа "точка", "вектор" подавляющее большинство операций (часто все) делаются операторами, поэтому трассирование сеттера ничего не дает.
А что, использование классов ограничивается точками и векторами?
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
02.01.2014, 17:48
Evg, я тоже так подумал, просто решил уточнить.

Большинство ОО-языков предоставляет в том или ином виде «сахар», который скрывает различие между доступом к обычному полю и к свойству. То, что в C++ такого нет (и в Java, из мейнстрима), на общую картину никак не влияет.

Также для большинства языков упрощена генерация тривиальных свойств (для языков, которые не имеют специального синтаксиса свойств, это задача обычно ложится на IDE).
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
02.01.2014, 18:00
Цитата Сообщение от @KOT@ Посмотреть сообщение
Чтобы получить переменную класса по правилам ооп нужно создавать метод для ее чтения?
По правилам ООП вообще нет такое понятия.

Добавлено через 18 секунд
Цитата Сообщение от @KOT@ Посмотреть сообщение
когда такой подход оправдан - ведь затрачивается куча лишнего времени.
Экономится.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
02.01.2014, 18:02
Nameless One, просто на начальном уровне людям зачастую кажется, что увеличение количества букв при написании программы - это плохо. И только поработав с реально большими проектами появляется понимание, что количество букв - это мелочи, по сравнению с тем геморроем, который зачастую возникает при реализации больших проектов
1
10 / 10 / 4
Регистрация: 12.10.2013
Сообщений: 249
02.01.2014, 19:54
Цитата Сообщение от Nameless One Посмотреть сообщение
Что значит в данном случае «усложнённый доступ»?
Если мне нужно использовать данные класса вне его, то вместо A.Value приходится использовать A.GetValue(). Речь конечно же не о количестве букв, а о "стоимости" операции. Если мне нужно в программе выполнить 100 000 запросов Value, то какой доступ будет эффективнее с точки зрения производительности?
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
02.01.2014, 20:06
Цитата Сообщение от Нитонисе Посмотреть сообщение
Если мне нужно в программе выполнить 100 000 запросов Value, то какой доступ будет эффективнее с точки зрения производительности?
А ты проверь.

PS. «Premature optimization is the root of all evil» © DonaldKnuth

PPS. Если ты беспокоишься, что такие тривиальные операции станут узким местом в твоей программе, то посмотри в сторону C.
0
10 / 10 / 4
Регистрация: 12.10.2013
Сообщений: 249
02.01.2014, 22:36
Цитата Сообщение от Nameless One Посмотреть сообщение
А ты проверь.
А что там проверять. Не зря же есть оператор inline, который "встраивает" функцию в место ее использования. Это значит, что вызов функции связан с затратами. Стало быть с точки зрения быстродействия лучшим будет тот код, где меньше вызывается функций.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
02.01.2014, 23:01
Цитата Сообщение от Нитонисе Посмотреть сообщение
А что там проверять. Не зря же есть оператор inline, который "встраивает" функцию в место ее использования. Это значит, что вызов функции связан с затратами. Стало быть с точки зрения быстродействия лучшим будет тот код, где меньше вызывается функций.
А Вы думаете, без inline компилятор не сможет выполнить встраивание ?
inline, auto (C++98/03) и register для современных компиляторов играют примерно
такую же роль, как расстановка скобок или комментарии. Компиляторы давно
уже сами в состоянии решать, где нужно встраивание, а где от него нет толку.
0
10 / 10 / 4
Регистрация: 12.10.2013
Сообщений: 249
02.01.2014, 23:48
Цитата Сообщение от Убежденный Посмотреть сообщение
А Вы думаете, без inline компилятор не сможет выполнить встраивание ?
Ну насколько я понимаю сам компилятор ничего не делает. Если у функции нет спецификатора inline, то никакого встраивания не будет. И решение на это дано на откуп программисту. У него выбор - либо использовать inline функции при этом получить быстродействие в режиме выполнения программы, но более длительное компилирование, либо не использовать inline и получить более медленный код, но который будет быстрее компилироваться. Уж не знаю как тут компилятор может сам решить, что лучше программисту. Это все равно как если я не буду указывать типы переменных, а компилятор будет сам решать - "ага, здесь double, здесь int"
0
1977 / 833 / 115
Регистрация: 01.10.2012
Сообщений: 5,119
Записей в блоге: 2
03.01.2014, 12:19
Цитата Сообщение от Evg Посмотреть сообщение
Видимо, в том, что много букв надо писать. Т.е. вместо "a.x+=5", надо писать "a.set (a.get() + 5)"
Ну вообще-то это довольно веский аргумент, бестолковые геттеры/сеттеры нередко путаются под ногами, раздражают и засоряют текст. Вот напр нормальное вычисление векторного произведения
C++
1
2
3
c.x = a.y * b.z + a.z * b.y; 
c.y = a.z * b.х + a.x * b.z; 
c.z = a.x * b.y + a.y * b.x;
Такой текст легко просматривается и контролируется. А вот с использованием get/set написать то же почему-то не тянет
Цитата Сообщение от Evg Посмотреть сообщение
А что, использование классов ограничивается точками и векторами?
Конечно нет, просто на всякое правило есть исключения. Заметим что библия не отрицает/осуждает использование public членов

Цитата Сообщение от Нитонисе Посмотреть сообщение
Ну насколько я понимаю сам компилятор ничего не делает. Если у функции нет спецификатора inline, то никакого встраивания не будет. И решение на это дано на откуп программисту. У него выбор - либо использовать inline функции при этом получить быстродействие в режиме выполнения программы, но более длительное компилирование, либо не использовать inline и получить более медленный код, но который будет быстрее компилироваться. Уж не знаю как тут компилятор может сам решить, что лучше программисту. Это все равно как если я не буду указывать типы переменных, а компилятор будет сам решать - "ага, здесь double, здесь int"
Это мнение по меньшей мере "основательно устарело". Код может быть встроен даже если находится в др единице трансляции. Использование get/set не вызывает замедления дотягивающегося хотя бы до 0.5%. Как компилятор решает: "в принципе" просто (в деталях сложно) - макс эффективно задействовать все имеющиеся регистры.

Возвращаясь к теме, возможно хороший пример private - портирование приложения с одной платформы на другую. Объявив переменную типа HWND public мы допускаем растекание нативного кода по всему приложению, и вычистить его весь будет непросто. Вообще вещь непростая, требует осмысления, сравнения неск вариантов на практике. Однако ТС торопится получить "немедленную пользу"
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
03.01.2014, 12:25
Цитата Сообщение от Нитонисе Посмотреть сообщение
Ну насколько я понимаю сам компилятор ничего не делает.
Делает. В многопоточном коде, например, вообще приходится прикладывать дополнительные усилия,
чтобы исключить побочные эффекты оптимизации. Компиляторы сейчас шибко умные.

Цитата Сообщение от Нитонисе Посмотреть сообщение
Если у функции нет спецификатора inline, то никакого встраивания не будет.
Последнее слово о встраивании остается за компилятором в любом случае. Небольшие функции обычно
встраиваются по месту вызова, независимо от наличия inline, если только это не отладочная
сборка или встраивание запрещено через опции компилятора или прагмы. Не верите - проверьте.

Цитата Сообщение от Нитонисе Посмотреть сообщение
У него (программиста) выбор - либо использовать inline функции при
этом получить быстродействие в режиме выполнения программы, но более длительное компилирование,
либо не использовать inline и получить более медленный код, но который будет быстрее
компилироваться.
Не могу не вспомнить такую тему: реализация класса в .h файле хорошо или плохо?
Там есть пример, когда компилятор встроил тело функции по месту вызова без всяких inline,
причем функция была определена в одной единице компоновки (obj-файл), а вызвана - в другой,
что, по идее, вообще не должно было привести к ее встраиванию. По стандарту (например,
C++03 7.1.2.2), inline является лишь подсказкой компилятору, что встраивание в данном случае
желательно, но последнее слово все равно за ним - он может как встроить функцию, так и нет.
Обратное также справедливо.

Поэтому не стоит экономить на геттерах-сеттерах в надежде, что это сделает код более быстрым.
Это есть "premature optimization", о чем Nameless One писал выше. Вызовы геттеров и
сеттеров обычно не являются узким местом.

На счет целесообразности использования геттеров-сеттеров там, где можно обойтись public.
Тут я полностью согласен, что нет смысла городить огород. Ну какие accessor-ы нужны для
таких тривиальных вещей, как rectangle, например ? Единственное, что приходит в голову -
это проверка инвариантов (чтобы, например, левый верхний угол прямоугольника не был ниже
или правее других, а тогда можно выбросить исключение), или в многопоточной среде, для
атомарного изменения или считывание всех четырех полей, но такое требуется редко.
1
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
03.01.2014, 14:25
Цитата Сообщение от Igor3D Посмотреть сообщение
Вот напр нормальное вычисление векторного произведения
Тут же не холивар, я всего лишь попытался понять, чего не нравится человеку.

Вообще понять, зачем нужен private - не так просто, как кажется тем, кто уже понял. Объяснения на уровне книжных (типа надо чего-то зачем-то спрятать) обычно не прокатывают, т.к. реальное понимание появится только после множественного наступления на грабли. Т.е. тратить время на написание кучи "лишнего" кода, чтобы сэкономить в будущем время на разгребание ошибок - это не так-то просто понять

Я, например, хорошо понимаю недоумевание тех, кто Set/Get и private считает мусором. Но затрудняюсь объяснить, что в большинстве случаев это реально нужно
2
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
03.01.2014, 20:56
Цитата Сообщение от Убежденный Посмотреть сообщение
На счет целесообразности использования геттеров-сеттеров там, где можно обойтись public.
Тут я полностью согласен, что нет смысла городить огород. Ну какие accessor-ы нужны для
таких тривиальных вещей, как rectangle, например ? Единственное, что приходит в голову -
это проверка инвариантов (чтобы, например, левый верхний угол прямоугольника не был ниже
или правее других, а тогда можно выбросить исключение), или в многопоточной среде, для
атомарного изменения или считывание всех четырех полей, но такое требуется редко.
А если прямоугольник вдруг резко становится Издателем, который генерирует события для своих Подписчиков, и события эти должны происходить при изменении ширины или высоты, причём требование это появляется, когда изменение этих свойств упоминается в вашей программе в 2405 местах? Обычно в этих случаях проектировщик класса отпрашивается с работы из-за внезапного приступа икоты ;-)

И на счёт inline. Это лишь одна из возможностей одного из языков, не более, и к ООП как таковому имеет весьма сомнительное отношение.
1
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
04.01.2014, 01:25
Цитата Сообщение от Igor3D Посмотреть сообщение
Вот напр нормальное вычисление векторного произведения
Цитата Сообщение от Igor3D Посмотреть сообщение
Такой текст легко просматривается и контролируется.
1. Формула векторного произведения записано с ошибкой(см. расчет через определитель)
2. Засунь все это в operator*, тогда запись выглядеть будет еще лучше.
0
1977 / 833 / 115
Регистрация: 01.10.2012
Сообщений: 5,119
Записей в блоге: 2
04.01.2014, 10:30
Цитата Сообщение от talis Посмотреть сообщение
А если прямоугольник вдруг резко становится Издателем, который генерирует ...
Такие резкие смены ролей классов подвластны только паттернистам Не должен простой утилитарный/конкретный класс быть ни "издателем" ни "подписчиком", вероятно он будет их членом. Этот аргумент "а вдруг чего случится, а у меня уже написано правильно!" столь же мало убедителен сколь часто он приводится. Если "чего случается" то весь класс "прямоугольник" оказывается недостаточным, т.е. требуется уже новая сущность.
1
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
04.01.2014, 13:59
Цитата Сообщение от Igor3D Посмотреть сообщение
Такие резкие смены ролей классов подвластны только паттернистам Не должен простой утилитарный/конкретный класс быть ни "издателем" ни "подписчиком", вероятно он будет их членом.
Это зависит от задачи. Сперва появляется обычный прямоугольник, потом наследуешься и добавляешь функции рисования на сцене и получаешь какой-нибудь "графический прямоугольник", еще раз наследуешься и добавляешь физический движок и делаешь оповещение о соприкосновении с этим прямоугольником. Добавляешь птичек и логику и получаешь angry birds.
1
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
04.01.2014, 23:21
Цитата Сообщение от Igor3D Посмотреть сообщение
Не должен простой утилитарный/конкретный класс быть ни "издателем" ни "подписчиком", вероятно он будет их членом.
Ну хорошо. Тогда как на счёт инкапсуляции прямоугольника в декоратор, который с одной стороны "навешивает" функционал генерации событий на тот же старый нетронутый девственно-утилитарый класс, а с другой стороны имплементирует его интерфейс, выполняя генерацию события после отработки соответствующего метода прямоугольника? Тогда, с одной стороны, и код, использующий прямоугольник, переписывать не нужно будет, а с другой стороны утилитарный класс останется утилитарным и не будет содержать "левого" функционала :-) Ну или не декоратор сделать, а банального наследника, как сказал Dmitriy_M. Не важно.

Декорировать, переопределять или как-то ещё расширять функционал можно у метода (аксессора, например), но никак не у операции присвоения члену класса.

Цитата Сообщение от Igor3D Посмотреть сообщение
Этот аргумент "а вдруг чего случится, а у меня уже написано правильно!" столь же мало убедителен сколь часто он приводится.
Да, действительно, аргумент "чёрт с ним, делай как будет быстрее и пошли пить пиво (пить чай/кофе, смотреть футбол, играть в снежки); надо будет - разберёмся", более убедителен.
0
1977 / 833 / 115
Регистрация: 01.10.2012
Сообщений: 5,119
Записей в блоге: 2
05.01.2014, 12:08
Цитата Сообщение от talis Посмотреть сообщение
Ну хорошо. Тогда как на счёт инкапсуляции прямоугольника в декоратор, который с одной стороны "навешивает" функционал генерации событий на тот же старый нетронутый девственно-утилитарый класс, а с другой стороны имплементирует его интерфейс, выполняя генерацию события после отработки соответствующего метода прямоугольника?
Проще и лучше вернуть простой прямоугольник по значению (что очень типично для таких классов).

Не подходит "прямоугольник" чтобы его куда-то развивать. Хотя сам класс может быть обширным (операторы пересечения, объединения и.т.п.)
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
05.01.2014, 13:18
Во всем должна быть какая-то середина.

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

С другой стороны, особенность проектирования в том, что нельзя наверняка сказать,
где и в какой форме компонент будет нужен завтра. Поэтому бросать все силы на то,
чтобы делать его максимально универсальным и расширяемым - как минимум нерационально.
Тот же rectangle можно снабдить accessor-ами, подсчетом ссылок, сделать его
наследником какого-нибудь CObject, получив поддержку боксинга и сериализации,
добавить возможность атомарного доступа к членам, затем еще параметризировать его
стратегиями исключений. Казалось бы, универсальнее некуда... Но вот однажды потребуется
обеспечить для этого класса совместимый с другими языками (например, с С) интерфейс, и
вдруг окажется, что все усилия по универсализации пошли даром.

Ну то есть, всем этим я хотел выразить мысль, что искать разумные границы между
простотой и гибкостью нужно отталкиваясь от каких-то конкретных требований самого
проекта, а не просто лепить как попало, чтобы поскорее доделать и "чтобы отстали" или
создавать архитектуры на ровном месте с заделом на будущее, которые потом все
равно не "выстреливают". Поэтому спор о том, нужны ли accessor-ы для элементарных
классов, в отрыве от конкретного контекста не имеет смысла.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
05.01.2014, 13:18

Стоит ли учить ООП в одно время с Яп
Добрый день! Начал активно изучать c#. Читаю Шилдта в свободное от учебы время и стараюсь практиковаться и всё выходит пока нормально. Но...

Как использовать ООП в WinAvr
Класс я создал. А вот объект класса создать не получается! Полазив по интернету выяснил что оператор new не поддерживается компилятором! ...

Js class как правильно использовать ООП
Накидал вот такой простенький код, авторизация проходит, data.Access_token существует, но в this.Access_token почему то не сохраняется, не...

Когда следует использовать ООП в РНР?
Когда стоит учить ооп в РНР, если новичок в РНР? Стоит ли писать весь код в стиле ооп ?

WITH AS стоит ли использовать
Использую СУБД Postgresql, есть запрос SELECT * FROM Table1 WHERE Filed1 IN (SELECT Fileld1 FROM Table2 WHERE Fileld2='A' AND...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
440
Ответ Создать тему
Новые блоги и статьи
Доктрина интенционального знания - Доктрина для портала "Срез".
Hrethgir 25.07.2026
Может найдётся кто захочет оценить доктрину. . . Написания правил участия для меня роскошь, требующая лимита времени, поэтому все сообщения не прошедшие модерацию будут видны только участникам портала,. . .
сукцессия 44. Решил подать на припринт в межународные сервисы препринтов. Но нужно одобрение от ученых
anaschu 25.07.2026
Английский вариант. Пока кто то не одобрит мою личность, мне не получиться это опубликовать на препринте. Но заявку на публикацию статьи я сегодня подам.
сукцессия 43. Вторая научная статья за месяц- прайминг и гатгил
anaschu 25.07.2026
две стороны одной монеты
Более приземисто - Эстафету хвоста в .cdl (деревья эстафеты в сад).
Hrethgir 24.07.2026
В будущем, после написания блока инверсии обхода дерева (эстафеты хвоста), я планирую вернуться к нашему прошлому разговору о том, обладают ли знания целеполаганием. Тогда я пришел к выводу, что. . .
Вот представьте что вам дали бессмертие.
kumehtar 24.07.2026
Вот представьте что вам дали бессмертие, ничего более не меняя. Вообще ничего, только бессмертие в нынешнем виде. Рады были бы? Что бы вы тут делали всё это время? Никакой пенсии. Никакого нового. . .
сукцессия 41
anaschu 24.07.2026
Численная верификация бифуркации в агентной модели лесной сукцессии: от одного параметра к ансамблю Автор: пользователь @Shumilov_AS | Раздел: Прикладная математика / Численные методы Кратко. . .
сукцессия 40. Ансамблевая кластерная параметризаци, часть 1.
anaschu 24.07.2026
Пр# Сопровождение научной статьи ИИ-ассистентом: подготовка публикации и калибровка агентно-ориентированной модели сукцессии микоризных систем **Полевые заметки о двухнедельной совместной работе**. . .
Теория всего 12. ВГК на планете в стратегической игре "терра"
anaschu 21.07.2026
### Главные семантические изменения и дешифровка новой физики 1. **`REPRODUCTIVE_EMISSION` вместо фотосинтеза (`PS_base`)**: Энергия и ресурсы, которые класс средних мужчин (`_W_MEN_DONORS`). . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru