Это - копия документа, находившегося на http://dz.ru. Авторские права, если не указано иначе, принадлежат Дмитрию Завалишину и/или Евгении Завалишиной. Все изменения, внесенные мной, находятся в этой рамочке.Пожалуйста, прочитайте disclaimer. |
Критика бывает несправедливая, справедливая и интересная. Интересная - та, что дает повод поразмышлять на тему. Пример последней.
Рассмторенные тобой варианты возврата значений: 1) int x, y; и 2) printf("pos is %d-%d", thing.x(), thing.y() ); К сожалению, вариант (2) не годится для многопоточных приложений, для приложений, в которых измененение объекта thing происхидит по прерыванию или по событию, поскольку вероятна ситуация, в которой последовательные вызовы thing.x() и thing.y() могут относится к разным состояниям объекта ( во временном смысле ). Поэтому в таких случаях обязательно надо возврашать одновременоо два значения ( ну или инкапсулировать их в один объект :) ). --
|
Хорошее замечание. И очень кстати.
Я, безусловно, согласен - вопрос атомарности существует и требует решения. Но решением в ОО является само ОО, а не костыли в виде возврата пар значений!
(Еще раз для функционально неграмотных: тут НЕ сказано, что ОО лучше всего на свете. Тут сказано, что ЕСЛИ ты пишешь ОО-но, то задача решается не так, а вот так.)
Инфантильный взгляд на ОО (я не приписываю его кому-либо, просто говорю о феномене как таковом) выглядит примерно так: ОО - это когда у структуры закрыт внешний доступ к полям и к ней пришпандорены какие-то функции, у которых первый параметр указывается не в скобках, а слева через точку.
Этот взгляд порождает ОО программы, в которых чёрт ногу сломит. Нет, даже чорт ногу сломит. Они, в частности, регулярно нуждаются в рантайм-декомпозиции объектов "не по делу".
Возврат пары значений из функции - динамическое порождение класса, не так ли. Порождение класса - признание того факта, что данные значения имеют смысл НЕ по отдельности, а именно вместе. То есть являются кандидатом на выделение в полноценный класс. Таким образом если тебе приспичило вернуть пару значений именно вместе (по любому поводу), значит, ты плохо сдизайнил структуру классов.
Теперь о возврате по отдельности. Если ты правильно сдизайнил структуру классов, то масса вещей автоматически танцует в правильном направлении, безо всякого усилия со стороны программера. Код из рук льется, чистенький такой, нежный и ласковый.
Вот берём те же координаты. Если атрибутом объекта является координата, то ее нужно выдавать на улицу отдельным методом саму по себе и нужно брать из объекта как win_pos.x(). При этом если необходима гарантия атомарности, то делаем тупое pos copy = win_pos; printf( ..., copy.x(), copy.y() );, и нет проблем. Обращаю внимание - скопировать придется только то, что реально является единым целым, не больше и не меньше. Если при копировании объекта класса pos скопировалось лишнее, очень велика вероятность того, что оно там действительно лишнее и должно быть не в этом классе. Возврата двух значений не нужно.
Если же атрибутом объекта являются координаты, то они выражаются через объект класса pos и возвращаются только как единое целое. При этом, конечно, никаких проблем с возвратом двух значений не может быть - это одно значение. Хотя никто не мешает написать win.pos().x(). Опять же, обращаю внимание - если код писать правильно и инлайнить всю эту шушеру, то эффективность такого кода тождественно равна win.pos.x.
Итого - я показал два корректных с точки зрения ОО варианта, и в обоих понятие "возврат двух значений" не танцует. Итого - если ты возвращаешь два значения из функции, значит программа плохо сдизайнена с точки зрения ОО. Еще раз для тех, кто комплексует - ЗДЕСЬ НЕ СКАЗАНО, ЧТО ОО - ЭТО ЛУЧШЕ, ЧЕМ САМОЕ ВКУСНОЕ МОРОЖЕНОЕ.
Заодно обращаю внимание тех, кто напрягается на design patterns - это всё проистекает не от умничанья, а от того, что эклектика обходится в конкретные деньги, а стиль оборачивается конкретным выигрышем. Писать можно как угодно, но критиковать методики хорошо только после того, как в них въедешь. На примере эдак тысяч двадцати строк кода.
Увы, ОО - одна из тех вещей, которые нельзя использовать наполовину. То есть можно, но это вызывает одну тошноту. Думаю, от того оно и вызывает отторжение у массы даже весьма опытных программеров. Если не сделать всех шагов до конца, то ОО программа запросто обернется ночным кошмаром. А сделать их трудно. Для этого нужно сильно перенести упор на проектирование и не писать кода, пока не напишешь почти всех хедеров (в случае с ++). Это зачастую крайне непривычно и напрягает. Мало того, писать код нужно, глядя на него с довольно специфических позиций, использовать инструменты нужно вкупе, а не по одному.
К примеру, множественное наследование у меня удачно применилось только после того, как я перешел на exceptions (долго рассказывать, почему так:), а exceptions потребовали переработать стиль кодирования чуть ли не от пола. Лично я потратил на въезжание в это всё несколько лет, это при том, что у меня никогда не было и тени сомнения в правильности подхода. Была куча сомнений в правильности применений конкретных инструментов.
Тупой пример. Те же исключения требуют врапперов на все "плоские" ресурсы. Нельзя написать
semaphore s; my_func() { .... s.lock(); ... работаем с ресурсами ... s.unlock(); .... }
застрелишься за ним бегать и отпирать, в каждой функции будешь ловить все исключения и возненавидишь их, как рыбий жир. А заодно и всё ОО. Что, собственно, и наблюдается в форуме. :-) А надо всего лишь написать простой враппер. Одна строка.
class key { semaphore s; public: key( sema ) {s = sema; sema.lock();} ~key() { s.unlock(); } }
semaphore s; my_func() { .... { key k( s ); ... работаем с ресурсами ... } // Вот тут семафор отопрётся сам .... }
Что важно. Семафор отопрётся сам, когда управление любым образом покинет блок. В частности, когда в блоке или вызванных ими методах случится exception, его не придется особо обрабатывать в данном месте. Но!! Решение чудесно тем, что не завязано на exceptions, и семафор будет освобождён при любом выходе из блока. Лично меня более всего волнует return, конечно, но есть и goto, break, continue.
Это - всего лишь одна небольшая иллюстрация одного частного аспекта. Призванная, не дай Бог, не показать, как именно что нужно делать, а показать, что поговорка "умный в гору не пойдет" весьма и весьма справедлива. Правильный подход правилен не потому, что написан в книгах, а потому, что облегчает жизнь. Сильно облегчает.
Это не значит, что на свете нет плохих книг, идиотов-методистов, задвигов на принципах ради принципов. Есть. Но пока что я чаще встречаю людей, критикующих ОО только за то, что они в нём не разобрались толком. Да, это сложно. Существенно сложнее, чем прочесть спецификацию языка, двух языков или пяти языков.
Меня тут спрашивали, что случилось с Уголком Дурева Соловьева. Жив ли, мёртв ли.
Отвечаю. Сольвьев с утра всё искал логотип Pentium III. Как только нашёл - сразу с ним набезобразничал. :-) Резюме: безобразничает - значит, жив. :-)
Вопрос из почты: "Насколько много в мире людей, желающих одновременно смотреть изображение на двух мониторах?".
При условии дешевизны решения - много. Один из вариантов описан в материале про G400 - когда человек купил себе монитор в 17", но старый 15"-ик никуда не девался и стоит в углу. Второй - подключение телевизора. Кроме того, существует масса профессий, для которых площадь монитора - расходный материал. Одна из них - программист. Отладчик, приложение, документация, исходники библиотек - нет проблем использовать пару мониторов по 17", уж не говорю о меньшем.
Кстати. Площадь экрана 15"-монитора - примерно 108 кв. дюймов. Цена - порядка $180 (можно найти и дешевле, но возьмем разумную). Это - 0,6 квадратного дюйма на бакс. Для 17" площадь - 138, цена - порядка 350 (это относительно недорогая модель), дюймов на тот же бакс получаем чуть менее 0,4. Это значит, что купив вместо 17" пару по 15 мы получаем примерно в 1.5 раза большую площадь экрана на ту же цену.
Это означает, что при наличии надёжного решения, которое позволяет подключать два монитора спрос на два монитора будет существенным даже в среде программеров. Я уж молчу про дизайнеров, которые пользуются двухмониторными системами на базе макинтоша скоро, наверное, с десятилетие и ждут - не дождутся, когда это станет возможно и на писи. Ибо картинку хорошо корёжить на большом и дорогом мониторе, а инструменты и фолдера держать на маленьком и плохом.
Так что спрос на двухмониторность практически гарантирован. Причем во всех слоях потребителей.
Кстати, для смеху - на цену дешевого 21" ($850) можно купить пять мониторов по 15, что даст площадь экранов, в 2,5 раза превышающую площадь экрана в 21". :-)
Мы давно мечтали и все никак не могли лаконично и в то же время емко сформулировать - что такое dz online? В одно предложение? Женька предложила спросить читателя. Спрашиваем. Как вам думается - что мы такое? Напишите!
Реклама, однако.
Юные и зрелые таланты из России! |
---|
|