Pull to refresh

Comments 176

Еще можно дополнить про is/has/was/have в методах, которые возвращают булевское значение (истину или ложь).
Примеры: hasChildren(), isPrime() и т.д.
Спасибо что напомнили, сейчас дополню)
Можно еще добавить

* Не забывайте использовать классы, для этого ООП и был придуман
* Все, что потенциально может использоваться в нескольких местах должно быть вынесено в общее место,
это может быть и константа вынесенная в специальный класс и код вынесенный в метод или класс
* Большинство операций IF, FOR, FOREACH, функций и переменных должно иметь комментарии
* Если при написании кода используются материалы из Документации, то можно сослаться на соответствующую страницу.
* Не использовать сокращения в имена переменных и функций. Имена должны отражать назначение переменной. Например вместо «valRes» называть «validationResult».
Некоторые пункты мне кажутся спорными. Вы можете написать об этом статью — там и обсудим.
а я всегда считал, что ооп придуман для работы с объектами…
А я всегда считал, что ООП придуман для представления понятий в реальном мире. Классы без объектов и объекты без классов (кстати, виртуальный класс со всеми статическими элементами можно представить как и то, и то) могут быть, но это уже не ООП.
класс без инстансов — это неймспейс.
объект без класса — это по прежнему объект.
объекты реального мира — только в симуляционных программах, но и даже в них одними только «реальными объектами» дело не ограничивается. ооп — это всё-таки выделение обособленных слабо связанных с остальными сущностей, взаимодействующих друг с другом посредством небольшого числа простых интерфейсов.
В любом случае, это не ООП.
Потому что ООП включает в себя инкапсуляцию, наследование и полиморфизм. Иначе это объектно-основанное программирование.
нет, ооп включает в себя объекты, общающиеся друг с другом посредством посылки сообщений. из этого следует и инкапсуляция, и полиморфизм. наследоание же — это вообще антипаттерн, ибо нарушает инкапсулцию, давая возможность предку вмешиваться во внутренности потомков.

Не обязательно. Можно утверждать, что namespace — класс без реализаций, но не наоборот.
а что может быть в «классе без рализаций»? статические константы, статические переменные, статические методы. всё, чем они отличаются от своих глобальных собратьев — префиксом класса в имени. в этом — вся функция такого класса, который и классом-то назвать язык не поворачивается, ибо класс — это, по определению, множество объектов, объединённых общим признаком.
Статья про программирование? Такое ощущение, что пришёл на IT-ресурс.
Этому комменту надо дать приз в категории «Ирония месяца». Спасибо за то что продлили мою жизнь на 1 минутку. :))
Хм, +94 за комментарий, может быть, полезный? Нет, тупая шутка.
Побольше бы таких статей.
Соблюдение code standarts еще никому не вредило.
Да тут даже не о code-standard идет речь, а об элементарных правилах уважения к себе и другим разработчикам. ИМХО, учиться писать читаемый код нужно вне зависимости от языка и стандартов кодирования. Стандарты кодирования могут (и должны) задавать, например, какое именование использовать — PascalCase или camelCase.

Вообще, таких статей действительно нужно больше! Такого рода ликбез полезен разработчикам на любом языке.
Если рассматривать PHP, то этот «разнобой» в именовании функций, пошел еще с времен его зарождения его как открытого языка. В основном это относится модулям расширений.
UFO just landed and posted this here
Взгляните на ООП в Python. Мне такая организация кажется усложняющей жизнь.
А вот Ruby хоть и не использую, но считаю что там все сделано изящно, тот же ООП заложен с самого начала. Т.е. у Ruby сразу была цельная концепция разработки.
UFO just landed and posted this here
расскажите-ка об ООП в питоне поподробнее.
Ну например у «1» (в смысле числа) можно переопределить какой-либо метод (да, они есть).

У питона на самом деле не меньший хаос, если заглянуть в библиотеки.
Тьфу, запостил и понял о чём именно ваш комментарий, прошу прощения, я — дурак.
Когда я начал изучать PHP, мне было непривычно отсутствие точечной нотации.
Думаю, что с введением namespaces ситуация начнет меняться, и базовые функции будут приводиться к единому виду.
Хотя, все сразу все равно не сделяют, потому что это равносильно созданию нового языка.
думал предложите решение для преодоления данной неприятной особенности php, a так за пыху стало ещё обиднее…
жаль что разработчики не продумали это :(
Тоже сожалею. Но все равно люблю его и пишу на нем.
string( 'blah-blah' )->split( 'foo' )->join( 'bar' )->raw

все это пошло изза того что на начальных этапах в разработке языка принимало участие много народу, каждый писал как ему привычно. поэтому и вышли функции с подчеркиваниями и без
через время это прошло, выработали таки стиль для языка, хоть и поздно
Дело, как всегда, в плохом моделировании, на этом этапе должны вырабатывать руководства, в которых будут правила.
"
Неочевидность аргументов и их порядка в функциях. Например, искомая строка идет в функции str_replace на последнем месте, а в функции strpos. Если бы искомая строка, например, всегда занимала первую позицию — было бы более удобно.
"

4 раза перечитал…
Я там пару слов забыл) Обновил)
Спасибо за очень полезную статью. Для себя отменил некоторые моменты.
«Дорогая, я отменяю наш поход в ресторан. Мне нужно переименовать несколько методов.»
:)
Похоже что про agile development и паттерн инверсии зависимостей автор статьи никогда не слышал

Dependency Inversion я имею ввиду не в прямом смысле, а концепция.

> cars.getByMonthAndYear(month, year).
какой ужас =)

Может лучше так: cars.byDate(int $iMonth, int $iYear);
При хайлайте сразу будет всё ясно.

А вообще предлагаю не городить огород из ненужных функций:
$aSInfo['month']='нулябрь'; // or 0
$aSInfo['year'] = 3108;

cars.search($aSInfo);
понеслась, обрабатываем входящий массив и все.
Ну как бы не культурно обижать людей. Слышал… не слышал…
Я так же могу сказать, что вы ничего не слышали про литерал массива, без которого ваш код унылое говно.

cars.search(array(
  'month' => 'ноябрь',
  'year' => 3108));


Да, в таком виде подход имеет право на жизнь, но эта тема отдельной статьи: там не все так хорошо как кажется.

А насчет «хайлайта» я упоминал в статье.
ну… надо же задавать потенциал. даже новайсам

посмотрю я на вас, когда в search надо будет передать хотя бы 7 условий. так же будете массив клепать прямо в вызове функции? дак че париться, давайте сразу sql запрос передавать готовый :D
а можно еще юзеру на страничке сделать textarea и кнопочку execute — пусть сам sql пишет и парсит вывод =)
Тут как бэ все зависит от архитектуры. Если у нас что-то выбирается только по дате, то какой смысл городить функцию search, которая принимает массив хрен знает чего, простите, с первого взгляда? А если мы какую-то сущность можем вытащить по каким-то критериям, и они могут сочетатся то тут уже и Criteria, нам в помощь будет. А поиск по массиву значений — это где-то промежуточный вариант, который следует использовать очень осторожно. Один недочет и будем переписывать все заново или в сторону методов или в сторону критерий.
Правильно, надо написать 10 методов для поиска по дням, часам, цвету, году выпуска и так далее, и получится у нас класс из трех тысяч строчек, да ещё по двадцать проверок для каждой переменной делать, чтобы сервер захлебывался, пока парсит файл.

А тех, кто «делают один недочет», надо линчевать сразу, и не будет никаких проблем.

p/s вместо того, чтобы гуглить, хомячки минусуют. всегда не любил местных идитотов =)
Правильно, надо написать 10 методов для поиска по дням, часам, цвету, году выпуска и так далее, и получится у нас класс из трех тысяч строчек, да ещё по двадцать проверок для каждой переменной делать, чтобы сервер захлебывался, пока парсит файл.

Второе предложение в моем комменте.

А тех, кто «делают один недочет», надо линчевать сразу, и не будет никаких проблем.
Тогда бы у нас вообще не осталось ни архитекторов ни программеров. Потому как требования, как это очень часто бывают, изменяются.
я бы добрую половину ПэХоПэ программистов лично бы расстрелял, была бы лицензия.

и честно говоря хоть и пишу на нем 5 лет, все больше хочу уйти в пайтон
главное при этом быть в «злой» половине ПэХоПэ программистов ;)
да хоть в какой. себя же не убьешь :)

не, ну правда, зачем вот писать 4 почти одинаковых метода, когда можно грамотно использовать один?

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

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

А по поводу проекта — немного не уловил смысл. Вы хотите сказать, что 2 фукнции по 150 строк гораздо лучше нежели теже 2 функции, по 10 строк, которые цепляют в себе еще с десяток функций, строк по 20-30?
и чтобы весь этот «десяток» тоже работал с базой/мемкешем? ну и что выйдет? ))
а какое отличие 150 строк кода, которые работают с базой и мемкешом, от 220 строк (вместе с заголовками функции, комментами и прочим), так же работающие с базой и мемкешом?

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

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

вот там какраз да. одна функция маленькая, а в ней создается 3 модели и из каждой делается getRec($id)…

вот за такое я руки и буду отрывать очень скоро :)

в одной моей большой функции я сделаю подгтовыку данных и запрос к БД
а если ваша функция будет состоять из кусочков других функций, то запросов точно будет больше.
Эм, как бы это помягче объяснить… конечно хорошо бы показать на примере, но…

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

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

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

все. пора домой. хватит работать =)

Возможно я не очень ясно выразился, или контекст не тот:
cars.search($aSInfo), flowers.search($aSInfo)

и

users.search($aSInfo), comments.search($aSInfo)

чуешь разницу, %username%? )))
Не вижу, по мне как первая строчка, так и последняя — довольно хреновые архитектурные решения :) Какого вообще хрена инстанс сущности должен вытаскивать другой инстанс самого этой же сущности по каким-то критериям (Хотя даже Users.search() — тоже не очень правильно)?
с тех пор я уверен, что лучше написать 2 умные функции, чем 4 «красивых и понятных»

Это вы проецируете недостатки языка/платформы/фреймворка на всю культуру программирования? Может, стоит задуматься о выборе средства, которое помогает в решении проблем, а не создает их?
стараюсь избегать подобных конструкций, так как отстутствует возможность нормального автокомплита и хинтинга, очепятался и лови баг.
с Becoming_Insane согласен, за исключением, если использовать __call, то очень удобно разбирать getByMonthAndYear, а затем func_get_arg и поехала магия.
функции-перегрузки — вообще очень полезная штука, но, имхо, злоупотреблять ими не стоит, ибо как раз от них код становится нечитабельным.

Или же, напротив, если использовать их основательно, то надо писать мануал по разработке на своем фреймворке.
как это в зенде :)

согласен, магия затрудняет читаемость и на скорость влияет, потому и поддерживаю cars.byDate, а длинные с указанием параметров нужно оставь только для магии. а здесь нормальный ide подскажет параметры
Если есть проблемы с автокомплитом и памятью, то вместо массива можно завести класс для аргумента, в котором за одном можно провести проверку вводимых аргументов, как вариант!
причём здесь память, я могу и вовсе не знать как реализован данный метод, мне главное знать входние параметры и их тип.
/**
* @param integer $iMonth
* @param integer $iYear
* @return Cars_Collection
*/
public function byDate($iMonth, $iYear) {}
человек стоящую вещь предлогал, а его заминусовали по самые помидоры. вот и поучи людей грамотному стилю :(
Я вообще речь вел о литеральных массивах в качестве аргумента метода, ни одна ide вам не подскажет какие должны быть ключи в массиве, и вам каждый раз придется лезть и вспоминать какие ключи должны быть в массиве! Чтобы избежать этой проблемы, можно вместо массива передавать в качестве аргумента объект класса… Например есть метод

search($arg);

Возможные варианты входного параметра:

$arg = array('year' => 2000, 'month' => 9, 'limit' => 10); // Аргумент ввиде массива, автокомлит не поможет!

$arg = new SearchArg(); // Аргумент ввиде класса, автокомплит работает
$arg->year = 2000;
$arg->month = 9;
$arg->limit = 10;

Кроме того в классе можно проверять входные данные и разгрузить тем самым целевой метод!

Надеюсь теперь вы поняли о чем я вел речь!
да, из-за тупой иде у тебя вызов метода занимает не 1 строчку кода, а 5.
зато нам не придется писать функции типа

searchByYear($year) {...};
searchByYearAndMonth($year, month) {...};
searchByYearLimit($year, $limit) {...};
searchByYearAndMonthLimit($year, $month, $limit) {...};
searchByMotherFuckerWhat($mother, $fucker, $what, ..., ..., $whatever) {...};

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

проверки можно вынести в отдельный метод, если что…

пользоваться идеей для написания пхп-кода — это тот ещё изврат ;-)
Хм, а что вы тогда делаете здесь?
а пачиму ви спрашиваете?
Ветка явно пхпэшная… PHP ничем не хуже и не лучше других языков программирования, не спорю он конечно уступает в гибкости Ruby, но не будем об этом. Почему тогда как вы выражаетесь «пользоваться идеей для написания пхп-кода — это тот ещё изврат»?
потому, как монструозная идея ориентирована на яву чуть менее чем полностью, тем самым побуждая программиста писать программы в явном стиле, в результате чего получается не простая и понятная программа, а монструозная, но с автокомплитом…
я всего лишь класс один добавил, типизировал аргумент так сказать и что здесь сложного?! А вы до этого предлагали реализовать полиморфную функцию…
у тебя получилось многа букав. и это не предел, если зацикливаться на автокомплите…
Хех, сразу вспомнился ROR, где средствами фреймворка у модели сделаны методы find и find_by_smth. Переводя это в синтаксис PHP можно написать:
cars->find(array('month' => '0', 'year' => 3108));
А можно и через имя:
cars->find_by_month_and_year(0, 3108)

Жаль что на PHP это приходится делать самому.
Не обязательно самому :-) В PHP5 много интересных нововведений, которые могут вам понравиться.
Из-за передачи массива в качестве параметра в коде возникают неясности.
чувак, код вообще штука непонятная =)))))))))

да надо и в БД сделать одно поле и хранить в нем сериализированные данные :DDD
я вообще за компактность :D

foreach ($aData as $sKeyName=> & $sValue) $sValue = контрацептив($sValue);

выглядит куда приятнее чем
$sName = контрацептив($sName);

куда-то схавалось.

короче чем 5 параметров в строку и к каждому вызов нужной нам функции.

cars.byDate(new Date(1964, 3, 9));

хотя конечно я не PHP-программер, а Java.

P.S. никаких холиваров. просто немного иная точка зрения.
Тут имхо есть значимая разница, передавать аргументом объект — это одно, объект это некоторая структурированная сущность, а вот передавать массив — это уже совершенно другое, так как в массиве могут храниться абсолютно любые данные, которые получив в методе еще нужно трижды перепроверить.
Что такое 3? Что такое 9? Месяц и день или день и месяц? Это ничуть не очевиднее, чем описанная в статье ситуация со строковыми функциями.
Вообще, да. Действительно. Если просто посмотреть на код, то однозначно сказать где и какие тут параметры нельзя. Но с другой стороны, класс Date — это стандартный способ представления дат и времени в Java. Т.е. у Java-разработчика вопросов не возникнет.
очрекомендую iso 8601 — таких вопросов возникать не будет и даты проще передавать будет…
groups.remove({ name: name }).remove({ status: 'deleted' }).remove( function( item ){ return item.cost > 53 } )

cars.get({ month: 'april', year: '2008' })

$string( 'blahblah' ).split( 'foo' ).join( 'bar' ).spit( 5 ).trim( /[\s,]+/ ).$

методы возвращающие булины — это предикаты
Мне тоже нравится JavaScript :)
Частичный пересказ Java Coding Standards в вольной форме? Хм. ;_)
Ну я в конце статьи указал свою любимую книгу, откуда я черпаю знания)
Да-да, я заметил. Я как бы просто прозрачно намекаю, что в Coding Standards к любому языку программирования изложено все это, причем в гораздо более полной форме. А отклонения от такого «стандарта» чаще всего как раз обусловлены историей развития языка, о чем уже справедливо заметили.

Ни в коем случае не принижаю образовательную ценность топика. :)
Первое желание было в комментарии как раз написать «Пишите на Java». Например проблема передачи непонятного массива в метод поднятая в треде выше решается просто — передаем Date. %)

На самом деле Полностью вас поддержу. Coding Standarts есть для каждого языка… Их следовать и надо. А не пытаться изобрести что-то общее.
3. Порядок и список аргументов в функциях/методах были составлены по одному принципу и сочетались с именем.

Не уверен в этом пункте, как вы. Современные IDE, тот же Zend Studio, говорит в каком порядке и какие аргументы у функции (при достаточном комментировании конечно же). Для стандартных функций это тем более доступно. Поэтому вопрос: зачем засорять имя функции такой информацией?
Странно, что это был не первый коммент. В PHP от разнобоя в стандартных функциях спасает IntelliSense. А за getByMonthAndYear() я бы, наверное, руки отрывал.
Вообще, статья, имхо, не претендует на добавление в букмарки, но на прочтение МакКоннелла и мануала(раздела «Соглашение о именовании...») наталкивает, что уже хорошо:)
Возможно, подобное написание — не самый лучший вариант. Тем не менее, опираться на IDE не стоит — ведь код нужно не только писать, но и читать. Возможно, через год. Возможно, в обычном текстовом редакторе.
Насчет читать — я уже написал свое мнение ниже, если интересно — habrahabr.ru/blogs/development/44748/#comment_1125759, описание в названии функции ее параметров — ну никак чтению не поможет.

$a = 4;
$b = get_by_a($a);
echo $b;

Есть догадки что будет в $b? :)

$a = 4;
$b = get_square_root($a);
echo $b;

А так? :)
Я не об именовании переменных говорил, как и та цитата, которую Вы привели изначально. Речь шла в первую очередь о порядке аргументов. По поводу именования — согласен только отчасти
result = $object->getDateObject($date, $time);
$someobject->someaction($result);

Хорошо, если аргументы будут передаваться переменными с очевидными именами. А если нет?
result = $object->getDateObject(123, 456);
Что такое 123 и 456? В варианте
$result = $object->getByDateAndTime(123, 456);
все более-менее понятно.
А если следовать логике, то запись getByDateAndTime, конечно, неочевидна и должна быть расширена до getIdByDateAndTime, чтоб все стало ясно.
Так вот оно, вот! :P
Не может в правильно написанной программе из ниоткуда возникнуть 123 и 456, а что содержится в переменных $date и $time можно отследить по предшествующему данному куску коду, а-ля

$date = $beforeobject->getDate(); // Здесь мы узнаем что приходит в переменную $date;
$time = $beforeobject->getTime(); // Здесь мы узнаем что приходит в переменную $time;
$result = $object->getDateObject($date, $time); // А здесь собсно сабж :)

А уж если уж 123 и 456 ни при каких условия в программе не изменятся, и должны придти в функцию в первозданном виде — нужно объявить их константами, а-ля

define('SOMEDATE', 123);
define('SOMETIME', 456);
$result = $object->getDateObject(SOMEDATE, SOMETIME);

Собсно для этого константы и предназначены, ибо взявшихся с потолка цифр в коде впринципе быть не должно.
Уговорили :)
А константы в пхп, имхо, сделаны очень неудачно, поэтому использую их редко. Привычка )
Хм, и что же в них неудобного?
Сравните
const a = 1
и
define('a', 1)
Как из слова define можно понять, что это именно определение константы, а не вызов какой-то функции? Почему имя константы берется в кавычки, а потом в коде используется без них? Разумеется, привыкнуть можно ко всему, но первое впечатление от подобного объявления констант — негативное.
Наверное это от того, что PHP язык весьма динамический.
Не знаю, когда я вижу define, сразу голова к константе готовится. Константа в кавычках для того, чтобы точно знать имя новой константы. В противном случае, если константа a уже определена, то новая константа будет называться по её значению.
Вообще, константы в PHP не так полезны, как в компилируемых языках, имхо. Ведь там вместо константы подставляется значение прямо в код, а здесь при вызове константы идёт взятие её значения откуда-то. К тому же, многие настройки принято где-то отдельно хранить, обычно в чём-то вроде объекта Config, чтобы не загромождать глобальное пространство имён. В любом случае, культура констант в PHP развита слабо.

PS. ru2.php.net/manual/en/language.oop5.constants.php
Видимо в связи с этим, в PHP'шном ООП константы применяются почаще, чем в функциональном программировании:)
Очень правильным мне кажется решение проблемы названия функций в Objective-C, где сигнатура метода выглядит подобным образом:
— (id)initWithTitle:(NSString *)title style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action

То есть при использовании:
[[UIBarButtonItem alloc] initWithTitle:@«GetAll» style:UIBarButtonItemStyleBordered target:self action:@selector(downloadAll)];

мы сразу видим какой аргумент что обозначает.
Жуть какая. Зачем столько визуального шума? Люди на строковых литералах экономят чтобы кавычки глаза не мозолили, а тут вся ASCII-таблица напоказ.
Код читабельный. А то, что получается после экономии можно посмотреть на примере перла.
Код малочитабельный. А экономия — это не Перл. Настоящая экономия — это MUMPS:

%DTC
%DTC ; SF/XAK - DATE/TIME OPERATIONS ;1/16/92  11:36 AM
     ;;19.0;VA FileMan;;Jul 14, 1992
     D    I 'X1!'X2 S X="" Q
     S X=X1 D H S X1=%H,X=X2,X2=%Y+1 D H S X=X1-%H,%Y=%Y+1&X2
     K %H,X1,X2 Q
     ;
C    S X=X1 Q:'X  D H S %H=%H+X2 D YMD S:$P(X1,".",2) X=X_"."_$P(X1,".",2) K X1,X2 Q
S    S %=%#60/100+(%#3600\60)/100+(%\3600)/100 Q
     ;
H    I X<1410000 S %H=0,%Y=-1 Q
     S %Y=$E(X,1,3),%M=$E(X,4,5),%D=$E(X,6,7)
     S %T=$E(X_0,9,10)*60+$E(X_"000",11,12)*60+$E(X_"00000",13,14)
TOH  S %H=%M>2&'(%Y#4)+$P("^31^59^90^120^151^181^212^243^273^304^334","^",%M)+%D
     S %='%M!'%D,%Y=%Y-141,%H=%H+(%Y*365)+(%Y\4)-(%Y>59)+%,%Y=$S(%:-1,1:%H+4#7)
     K %M,%D,% Q
Если для вас ObjC — малочитабельный… я даже не знаю :).

Касательно приведенного куска кода — это ппц. Видимо, сделано только для того, чтобы разобраться было сложно :).
И еще и так:
[[UIBarButtonItem alloc] initWithTitle:@«GetAll» 
                                 style:UIBarButtonItemStyleBordered 
                                target:self 
                                action:@selector(downloadAll)];

Интересно было бы использовать в PHP концепцию селекторов, как в jQuery. Попытка такое реализовать есть в atomikframework.com.
Кто-нибудь подобные решения знает?
Думаю, что это поможет более прозрачную структуру приложений
Интересно было бы использовать в PHP концепцию селекторов, как в jQuery. Попытка такое реализовать есть в atomikframework.com.
Кто-нибудь подобные решения знает?
Интересно было бы использовать в PHP концепцию селекторов, как в jQuery. Попытка такое реализовать есть в atomikframework.com.
Кто-нибудь подобные решения знает?
Интересно было бы использовать в PHP концепцию селекторов, как в jQuery. Попытка такое реализовать есть в atomikframework.com.
Кто-нибудь подобные решения знает?
Ответьте ему уже кто-нибудь! =))
Извините, увлекся F5
Честно говоря, непонятно за что заминусовали топики. Вполне понятно, что сделано это не специально, а есть какая-то проблема с добавлением комментария.
Возможно, чтобы скрыть лишние комменты?
Но тогда кто-то невинно пострадает…
а для чего вам «Обновать комментарии» сделали ))
Я не хочу кидать очередной камень в огород автора, но есть такой вопрос, точней комментарий. Он относится ко многим авторам статей.

Почему нельзя избавиться от мании предупреждать, что статья может быть «паршивой»? Если автор сомневается в своих знаниях, то не вижу смысла существования статьи вообще, а если боится комментариев и критиков, то последнее надо воспринимать адекватно и с чувством достоинства (ну и юмора). Статья на то и статья, чтобы научить чему-нибудь, качественно передать проанализированную информацию читателю.

А книжка Стива Макконнелла обязательна к прочтению каждому себя уважающему программисту, менеджеру и т, д.
Ну менеждеру думаю вся книга и не нужна, только пара глав.
Тяжелое наследие С… А если еще вспомнить частое использование венгерской_нотации, то становится вообще грустно. У дотнета и джавы с этим делом как-то получше, а уж если методы описаны XML-комментариями (в дотнете), то написание кода превращается в легкую непринужденную работу (читать как «вместо того, чтоб отвлекаться на заглядывание в МСДН можно думать об архитектуре и алгоритмах»). Впрочем, у нас в компании политика партии гласит, что код должен быть понятен без комментариев и я с ней согласен.
в своем коде тоже стараюсь именовать функции более понятным образом, но в вашем примере getUsersBy… мне кажется очень громоздким названием…
Код на картинке — приведен совсем не как хороший)
спасибо, все встало на свои места
>>Нам нужна замена подстроки в строке. Самым очевидным вариантом будет такой: string.replace(from, to).

from-to — это очевидно? o_O
имхо, имена $needle, $search и $replace яснее выражают смысл, хотя needle и search здесь, в сущности, одно и то же. from может обозначать источник, например, при копировании.

>>Например, искомая строка в функции str_replace идет на последнем месте, а в функции strpos — на первом (str_replace($search, $replace, $subject[, $&count]) vs strpos($haystack, $needle[, $offset])).

По-моему, искомая строка в функции str_replace идёт как раз на первом месте, а в функции strpos — на втором, но это не важно, так как в общем вы правы.
Ну вы как выражаетесь: «Пойди поменяй штуковину на хреновину» (from-to) или «Пойди хреновиной замени штуковину» (to-from)?
Мне кажется, первая последовательность логичнее по крайней мере с точки зрения русского языка. Да в английском такая последовательность вроде бы естественнее.
Спасибо за ссылку, смешной, не видел его еще.
чего только одна функция mktime в php стоит, со своим необычным чередованием аргументов… порядок которых [цензура] запомнишь…
В этой книге автор ещё пишет
что вполне уместны методы типа
geheDorthinSelbstIchWeissNichtWohinUndBringeDasIchWeissNichtWas()
//Ну и поганенько выглядит.
главное в том чтобы такой метод
действительно делал то что от него
ждут, и его название это поведение
максимально объясняло.

А дальше автор говорит о том что
просто разработчик не должен
создавать еб… ые методы.
В PHP же многие объясняют «разнобой»
т.н. «лёгкостью вхождения» и простотой.
да в языке без сторогой типизации не
было необходимости в code convention

Да и на последок методы и функции
в PHP не надо путать.

З.Ы. заминусуйте мне это уже начинает
нравиться :)
Не понравилась манера написания… переборщили с «ага».
Немного не согласен с автором, функции (и методы, как современные потомки оных), должны указывать действие, которое они производят, и тип данных (имеется ввиду не тип ЯП, а-ля integer/string/float, а в общем), а уже какие аргументы они принимают — это доп.информация, в приведенном примере cars.getByMonthAndYear(month, year) совершенно непонятно что должен вернуть метод, объект cars? Но раз из него вызывается метод — он уже существует. Он не возвращает ничего, а воздействует на себя? Тогда он должен называться не get, а что-то вроде init.
Почему указание типа возвращаемых данных важнее указание параметров? Потому что при последующем чтении кода можно будет отследить логическую цепочку операций над данными

$result = $object->getByDateAndTime($date, $time);
$someobject->someaction($result);

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

$result = $object->getDateObject($date, $time);
$someobject->someaction($result);

А в данном случае из названия метода мы видим какие данных были получены в переменную $result, и соот-но можем понять какие данных были отправлены в последствии в метод someaction();
Мне кажется, что в этом случае целесообразнее не вносить дополнительную информацию в название метода, а понятнее назвать переменные:

$someDateObject = $dateObject->getByDateAndTime($date, $time);
$someobject->someaction($someDateObject);
Это тоже хорошая мысль.
У Макконелла главная мысль при именовании методов и переменных состоит в том, что если у вас есть методы вроде: «getEvensItemByIdAndSortThemByDateBeforeCallThisMethodCallDBPrepare», то не стоит их переименовывать, стоит их переписать.

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

Хотя это уже немного другой случай, и тут не какие правила именования не помогут…
и?
java convention
google code convention
В любой серьезной конторе, где бы вы ни работали, пользуются какими либо понятными и удобными правилами…
… можетм опять это камень в сторону… сами знаете когО?)
Вы предлагает выносить в имя метода все параметры, аргументируя это тем, что сложно запомнить порядок и назначение аргуменов.
Но что это нам дает? Ведь теперь просто нужно помнить другие вещи — имя метода

Например:

getByMonthAndYear

а не

getByYearAndMonth

Так что, имхо, проблему это не решает (да и проблема ли это). Такой подход делает имена методов более громоздкими (что с IntelliSense не проблема) и не несущими дополнительной полезной информации в своем имени (что плохо).
> Имена некоторых функций неочевидно передают назначение. Например, basename.

basename — это часть Open Group Base Specifications для Unix-команд, и она там достаточно давно.
То же самое и с touch, chmod, chown и прочими именами, «неочевидно передающими значение».
Вообще-то *nixы всегда отличались «удобочитаемыми» и «интуитивно понятными» командами — собственно так оно переехало в С (который был придуман именно для написания Юникса), а из С переехало уже в РНР и некоторых других потомков.
Да, но ведь это не просто традиция, это, можно сказать, неологизмы. :-)
Тогда это имело объективные причины — длина идентификатора на С была ограничена восемью (кажется) символами. К счастью те времена благополучно прошли, но вот сделать нормальные удобочитаемые алиасы для функций никто недодумался. Если серьезно, то я сам пишу на сях на олимпиадах и меня совсем не конфузят строки типа fprintf(f,"%s — %-5I64d", s.c_str(), MGC_CNST); но вот сталкиваться с таким во время комерческой разработки… Увольте, лучше я уж и дальше на C# буду писать, в дотнете с именованием все в порядке.
Если кто не понял, я имел ввиду древнюю 16-битную версию С, а не современный С/С++.
Скажите, а что за шрифт на скриншоте с кодом?..
Вообще можно посоветовать как можно больше читать чужого кода. Тогда со временем помими прочих полезных вещей, приходит понимание того как нужно и не нужно именовать функции и называть переменные.
Мне кажется зашивать информацию об аргументах в имя метода будет лишним.
Главное сами аргументы грамотно назвать.
Factory::getCar($year, $month)
Factory::getCar(DateTime $date)
Factory::getCar(Color $color, Model $model)

вместо
getCarByYearAndMonth
getCarByDate
getCarByColorAndModel

На помощь приходит автокомплит, когда печатаешь сразу видишь 3 варианта getCar, и по именам аргументов понятно что каждый делает.
Причина появления этой статьи на хабре кроется в отсутствии нормальных сред разработки для ПХП с развитым intellisense.

Мне трудно представить чтобы такое написали люди работающие с Visual Studio.
Да всего достаточно для разработки нормальной на пыхе. Нет, конечно же меньше нежели в других языках (как бэ динамическая типизация дает о себе знать), но и того что есть — хватает. Другое дело, что многие привыкли работать не в нормальной IDE, а в каком-нибудь текстовом редакторе с подсветкой кода.
PHPDoc и IDE редакторы вам помогут :) И само описываемый код МИФ
Что-то я не согласен. PHP не знаю, поэтому могу ошибаться. Как уже сказали basename — стандартная команда и с ней (и наверное многими другими) проблем нет. Читать имена типа AVeryFuckingLongButSurelyDamnDescriptiveItentifierPSIDontReallyLikeCamelCase конечно прикольно, но писать без подсказок со стороны IDE довольно грустно, а с подсказками лучше сразу аргументы видеть.
Согласен, вообще вроде считается что 5 слов (максимум, и то имхо много :)) для имени функции вполне достаточно, если недостаточно — значит, как уже писали выше, что-то не в порядке с самой функцией.
Незнаю как вы, а я привык чтобы имя функции отражало то ЧТО ОНА ДЕЛАЕТ а не то С КАКИМИ ПАРАМЕТРАМИ она работает. Причем это не только мое ИМХО.

Или вы собрались переписывать стандарты? :)
UFO just landed and posted this here
А как сказать что это не только мое ИМХО? о_О

Хотя… Пойдука я лутче спать. А то щас еще ни такого напишу :)))
In My And Some People I Know Humble Opinion -> ИМАСПИКХО
Пойду ка я тоже спать…
А масло — масляное.
Ну если вы оглядитесь вокруг, то сделаете удивительный вывод, что это далеко не моя идея. Указывать аргументы — не обязательно. Но в неочевидных ситуациях стоит намекнуть на них для простоты восприятия.
Нет я имею ввиду что в большинстве «стандартов» что я видел, черным по белому написано — «название методо должно отражать то что он делает» и все. Как вы будете бороться с «стандартами»? Ведь многие просто тупо пишут по «стандарту»… Вот к чему я клоню…
Помимо того, что он делает, нередко указать еще КАК он делает. Так как это может влиять на результат. Вот это КАК довольно часто и записывается в виде аргументов. Ну, короче, вы понимаете.
UFO just landed and posted this here
Да, в PHP это проблема, действительно, но изначальная задумка очень даже хороша.

в str_replace, кстати правильная последовательность. Объясняю. Вы заметили название аргументов $needle, $haystack? Это всем известная поговорка: „Искать иголку (needle) в стоге (haystack) сена“. Так расположены параметры во многих функциях массивов, (например, array_search).

Распологали бы везде в таком порядке: „ЧТО ГДЕ КОГДА и при каких ОБСТОЯТЕЛЬСТВАХ“, то не было бы никаких путаниц вобще.

такую последовательность я использую всегда в своём коде.
Пример нормальной архитектуры/именования:

Book.all(:created_on => (last_income_at..Time.today), :cost.gt => 500).destroy!

неа, делегаты рулят =)

Book.select{ |item| ( item.created > now )and( item.cost > 500 ) }.destroy!
Может быть это болезнь С, но все же там в пределах одной библиотеки нет таких разнобоев.
в PHP:
strpos — функция взята из С;
str_replace — функция придумана для PHP.
Отсюда разница в стиле написания и порядке параметров. ИМХО, это нормально, никакого противоречия я здесь не вижу. В PHP весьма четкий и достаточно давно сформировавшийся стиль именования функций, хотя вот огрехи с параметрами бывают, для примера:
mysql_query(запрос [, хендл коннекта]);
pg_query([хендл коннекта, ] запрос);
UFO just landed and posted this here
А я всегда забываю функцию substr, и найти ее довольно трудно, так как первое что приходит на ум — это искать функции на str и str_ по аналогии. :)
В последнее время (устал от работы, что ли?) меня стали очень раздражать императивные языки, в которых хочешь-не хочешь, а приходится заниматься такой вот словесной эквилибристикой. В какой-то мере ситуацию спасают метапрограммирование и DSL'и, но все равно это не то: они не всегда есть, уровень абстракции (на всех уровнях) не такой высокий, да и удобство использования страдает.

Ситуацию спасает правильный выбор языка: есть C# 3.0 со всеми функциональными плюшками и LINQ'ом; есть Boo:
rjCustomers = [customer.Name for customer in customers if customer.State == "RJ"]
есть, в конце концов, LISP (см. Десятое правила Гринспуна).

Используйте, в общем, подходящие языки программирования и помните про молоток и гвозди.
UFO just landed and posted this here
Сравнение с WinApi некорректно. WinApi имеет далеко не лучший подход: работает с объектами процедурным подходом.
UFO just landed and posted this here
Мне вот не сама статья понравилась, а комментарии. Автору можно даже сделать уже опрос на тему — «а какой метод в данном случае предпочтете Вы?» +1
Пошел заказывать книгу «Совершенный Код»
Честно говоря никогда не читал статьей на тему оформления, но как начал изучать MVC и тд и тп, само собой как то прибилось. Спасибо за статью, побольше теории!
Автору статьи несомненно понравится система именования функций, принятая в OpenGL :-)

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

www.rsdn.ru/article/opengl/ogltut2.xml#EBF

Фактически примерно так же реализуется перегрузка функций в C++ — в obj-файл они попадают с подобными суффиксами, невидимыми в коде на C++. Но программисту не приходится заморачиваться этим синтаксисом, подбор подходящей функции из набора одноименных реализаций происходит автоматически на этапе компиляции.

Что до меня — мне больше нравится, как это сделано в C++
1. Нам нужна замена подстроки в строке. Самым очевидным вариантом будет такой: string.replace(from, to). Жаль, что в PHP он не осуществим.
Ну, во-первых, «неосуществим» пишется слитно. А во-вторых, очень даже осуществим:
<?php
class Str
{
  public $value;

  public function __construct($value)
  {
    $this->value = $value;
  }

  public static function create($value)
  {
    return new self($value);
  }

  public function __toString()
  {
    return '' . $this->value;
  }

  public function replace($what, $with)
  {
    return self::create(str_replace($what, $with, $this->value));
  }
}

function S($value)
{
  return new Str($value);
}

$source = '1234567890';

$result1 = Str::create($source)->replace('456', 'xxx');

$result2 = S($source)->replace('89', 'ZZ');

echo "<pre>\n";
echo "source: '$source'\n";
echo "result1: '$result1'\n";
echo "result2: '$result2'\n";
echo "</pre>\n";
?>

Результат:
source: '1234567890'
result1: '123xxx7890'
result2: '1234567ZZ0'
Sign up to leave a comment.

Articles