Притча о программистах и кодерах

Давным давно, в далёкой предалёкой галактике, на одной провинциальной планетке жили разумные млекопитающие, у которых недавно начался век информационных технологий. В тот век многим приходилось писать программы на разных языках для различных программных платформ. И любой потомок обезьяны с этой планеты, написавший хотя бы пару строчек кода, который заставил тупую вычислительную машину сделать несколько разумных (с точки зрения автора) действий, уже считал себя просветлённым мудрецом, постигшим ДАО информационных технологий и назывался не иначе как джедаем программистом.

image

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

Абсолютное большинство людей считают, что совершенно не важно, как был достигнут результат, если задача, по всей видимости, решена. Начиная решать какую-либо задачу по разработке программного обеспечения (и не только), многие не задумываются о фундаментальных принципах проектирования, а просто копируют работающие блоки у предшественников. Кодеры, вооружившись справочником по синтаксису языка и интернет-поисковиком, создают свои «мегашедевры программирования». Быстренько заставив программу с помощью отладчика выполнять более или менее похожие на логичное поведение действия, разработчики сдают заказ. Клиент доволен, кодер при деньгах — все счастливы, на первый взгляд.

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

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

И тут возмущённые кодеры возроптали: «Мы знаем все эти фундаментальные принципы! Они все бесполезные и глупые!». А вселенная ответила им: «Возможно, это так, но, возможно, вы не понимаете их, а потому не умеете применять».

Возьмём простые примеры кода с использованием мега популярного на этой провинциальной планете языка веб-разработчиков PHP. Сам язык довольно хорош для его использования по прямому назначению, хотя мнения по этому вопросу обычно расходятся.

Часть 1: Простота кода


Пример 1:

if ($u->g) $u->reg($u->email, $u->nm);

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

$user->email = $email;
$user->name = $name;
if ($user->isGuest) $user->register();

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

Пример 2:

//…
$sql = 'SELECT * FROM usr LIMIT 10';
//…
/** view */
if ($n<10) echo ...;

Вроде бы код более или менее ясен, хотя магические константы вроде 10 настораживают, кроме того, код встречается в разных файлах и часто повторяется.
Как бы написал его программист? Да примерно так:

class User
{
	const MAX_VIEW_USERS_ON_PAGE = 10;
	... ... ...
	$sqlQuery = 'SELECT * FROM `User` LIMIT '.User::MAX_VIEW_USERS_ON_PAGE;
	…
/** view */
if (count($users) < User::MAX_VIEW_USERS_ON_PAGE) echo ...;

Читать код стало намного удобнее, а число выводимых на всех страницах пользователей (10) теперь легко изменить, так как оно используется через именованную константу, аналогичная ситуация и с наименованием таблицы в базе данных.

Пример 3:

if ((isset($user->online) || (time() - $user->lastVisit < User::LOGOUT_TIMEOUT)) && Post::getNumOfPostsForUser($user->id) > Post::ACTIVE_USER_MIN_POSTS) 
	$Raiting::addBonus($user->id, Rating::BONUS_RATING_POINTS);

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

$userOnline = (isset($user->online) || (time() - $user->lastVisit < User::LOGOUT_TIMEOUT));
$userIsActivePoster = Post::getNumOfPostsForUser($user->id) > Post::ACTIVE_USER_MIN_POSTS;

if ($userOnline && $userIsActivePoster) $Raiting::addBonus($user->id, Rating::BONUS_RATING_POINTS);

Ну вот теперь условие стало простым и ясным как день, а всего лишь введены дополнительные логические переменные для упрощения кода.

Пример 4:

Код повторяется в нескольких местах:

$hdr = explode(' ',trim($header));
$hdr[0] = '<span class="hdr-decor">'.$hdr[0].'</span>';
$header = implode(' ',$hdr);

Как сделать ситуацию лучше?

class StringHelper
{
	/**
	 * Return text header with CSS
	 * @param string $header
	 * @return string
	 */ 
	static public function getCSSDecoratedHeader($header)
	{
		$hdr = explode(' ',trim($header));
		$hdr[0] = '<span class="hdr-decor">'.$hdr[0].'</span>';
		return implode(' ',$hdr);
	}
...
$header = StringHelper::getCSSDecoratedHeader($header);

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

Часть 2: Объекты и классы


Кодеры недоумевают: «Зачем нам ООП, если всё можно написать функциями или даже просто операторами?».
Вселенная в ответ: «Да всё затем же — сделать большой или сложный код более простым, понятным и хорошо структурированным».
Инкапсуляция — это важнейшее свойство в управлении сложностью кода, логично пряча наши данные и алгоритмы внутри закрытых методов классов мы значительно упрощаем всю логику работы с классом, а также упрощаем все будущие операции по изменению поведения класса.
Наследование — отличный способ не писать повторяющегося кода в похожих классах и упростить все классы потомки.
Полиморфизм — мы легко меняем логику поведения класса потомка, изменив лишь один метод.

Пример 5:

Кодер научился извлекать данные из таблиц базы данных и теперь во всех файлах пишет заклинание:

$sqlQuery = "SELECT * FROM User WHERE id=:id";
$connection = $this->getDbConnection();
$command = $connection->createCommand($sqlQuery);
$user = $command->execute(array(':id'=>$id));
echo $user['name'];

Но благодаря ООП и специально подготовленному классу User можно написать значительно короче и понятнее:

$user = User::model()->findByPk($id);
echo $user->name;


Пример 6:

Кодер написал несколько классов для поддерживаемых его сайтом платёжных систем, в каждом есть несколько совершенно одинаковых методов и полей.

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

Часть 3: Модульность


Кодеры недоумевают: «Зачем в программе делать кучу файлов, да ещё и в разных папках? Можно сделать один-два файла и там будут все константы, классы и функции нашего проекта, а переменные все будут глобальными.»

Вселенная в ответ: «Да… но тогда ты сам и разбирай свои километровые Gовно файлы».

Пример 7:

Кодер научился писать в MVC фреймворке, но не познакомился с модульной структурой и пишет весь код в модели:

class Article extends CModel
{
	... ...
	public static function getDecoratedHeader($header)
	{
		$words = explode(' ', $header);
		$words[0] = '<span class="decorator">' . $words[0] . '</span>';
		return implode(' ', $words);
	}
	... ...
}

Программист знает, что в модели должен быть исключительно код для работы с данными этой модели и такой метод поместит в хелпер StringHelper::getDecoratedHeader(). Соответственно, каждая функция приложения имеет своё определённое назначение, которое определяется модулем в котором находится её реализация (модель, контроллер, компонент, виджет и т.п.) и программисты будут многое понимать о сути методов, написанных другими программистами, просто видя к какому модулю он принадлежит.

Часть 4: Паттерны


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

Пример 8:

Кодер использует в своём приложении внешний компонент Mailer и пишет в модулях системы вызовы его метода send().
Mailer::send($subject, $message);
Но вот беда, в новой версии этого компонента, исправляющей кучу багов и повышающей быстродействие, метод send() убрали и заменили на метод post() с другими обязательными параметрами. Кодеру придётся перелопатить весь код приложения, исправляя все вызовы компонента, а если бы он использовал один из самых простых паттернов — метод доступа:

class MailerWrap 
{
	public function send($params)
	{
		return Mailer::send($params);
	}
}

Программисту было бы достаточно изменить только один метод с вызовом в классе-обёртке компонента Mailer чтобы воспользоваться всеми преимуществами новой версии.

Часть 5: Фреймворки


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

Пример 9:

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

Часть 6: Оптимизация


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

Пример 10:

Кодер написал форум, но вот беда — через пару месяцев активной болтовни, странички сайта стали очень медленно открываться. Он зарылся в код и с большим трудом выяснил, что очень долго выполняется запрос к базе MySQL. Кодер начитался советов из поисковика и решил переписать весь форум с использованием noSQL базы, благо это займёт всего лишь месяц. Программист же в таком случае проанализировал бы план запроса и добавил пару индексов на таблицы за 3 минуты.

Пример 11:

Кодер занялся оптимизацией производительности своего кода, состоящего из 8 функций, по порядку оптимизируя каждую из них. Он потратил неделю на рефакторинг 5 функций, но прирост производительности составил всего лишь 10%. Кодер разочаровался в оптимизации и бросил это дело, смирившись с тормозами приложения. Программист бы проанализировал время выполнения каждой из 8 функций, после чего занялся бы оптимизацией самой долго выполняющейся функции. Другие функции, время выполнения которых значительно (на порядок) меньше основной, не стал оптимизировать совсем.

Часть 7: Безопасность


Кодер никогда особо не задумывался о безопасности кода. Зачем? Никто ведь никогда не будет взламывать его программы…

Пример 12:

у кодера множество запросов в приложении, где он просто подставляет переданные от пользователя данные (GET, POST, COOKIES, JSON, XML) напрямую в запрос:
$sqlQuery = 'SELECT `name`, `surname` FROM `User` WHERE `id`='.$_GET['id'];
$command->create($sqlQuery);
$result = $command->execute();
print_r($result);

А что будет, если «пользователь» передаст в параметре id следующую строку «0 UNION SELECT `email`, `password` FROM `User` LIMIT 10»? Наверное будет полный ай-ай-ай!
Программисты пишут такие запросы примерно так:
$sqlQuery = 'SELECT * FROM `User` WHERE `id`=:id';
$command->create($sqlQuery);
$result = $command->execute(array(':id'=>$_GET['id']));
print_r($result);

Да и про подстановку значений в функции типа eval() программисты тоже никогда не забывают, как и про клёвое слово «валидация».

Заключение


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

Да пребудет с тобой это великое знание, юный падаван!
Share post

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 119

  • UFO just landed and posted this here
      +5
      Макконел систематизировал базовые принципы десятки лет и выпускал свою книгу «Совершенный код» два раза, его сложно превзойти… Разве что постараться донести основные принципы не на 900 страницах, а в одной статье
        0
        Я понял — инициатива наказуема :)
      +2
      Да.
      Особенно про фреймворки.
      В нескольких компаниях наблюдал такую картину — для бэкенда сайта некто написал свой фреймворк для разбора URL (потому что у существующих есть, очевидно, фатальный недостаток). Но он уволился, после него ещё кто-то развивал систему, потом и он тоже уволился. Документации нет, комментариев нет, соглашений по стилю кода нет. Текущий программист и сам плохо разбирается, при этом у него нет времени тебе всё объяснять.
      Как по мне, в таких вещах разбираться вообще невозможно.
      А всё из-за нежелания «заточить топор». Видимо, психологически изучать чужое труднее — поэтому давайте напишем своё.
      А с опытом становится понятно, что своё писать не надо — чужое уже работает, и баги там отлавливает куча людей, и развивается, и другие люди тоже не идиоты и соображают, что нужно для подобных вещей, и уже их там сделали…
        +5
        В реальности у вас при разработке достаточно сложного приложения никогда не получится использовать только готовые фреймворки, т.к. у вас обязательно будут появляться специфичные задачи, из-за которых готовый фреймворк надо допиливать. В итоге, ваша кодовая база всегда превращается в «бизнес логика» + MyApplicationFramework. Но это и не проблема сама по себе, проблема в том, что зачастую они оказываются перемешаны и сложно понять, где у вас одно, а где другое.
          0
          Тут работает принцип модульности. Если Ваше приложение написано корректно и все классы и методы лежат на своих местах, то Вы никогда не запутаетесь в том, где у Вас framework, а где бизнес логика
            +1
            Только теоретически, когда есть анлимитед времени на разработку.
            На практике же граница периодически размывается, а иногда и нарушается насквозь каким-нибудь «грязным хаком».
            У того же макконела это описывается как присутствующее зло, когда он говорит о необходимости периодических рефакторингов.
              0
              У меня есть стойкое ощущение, что можно написать универсальное средство, которое можно законфигурить под любой проект, чтобы быстро находить в нем ошибки, связанные с нарушениями такого рода.
              Естественно, я говорю не по 100% случаев, но даже если 80% типичных ошибок нарушения уровней абстракции будет отлавливаться автоматически — это будет счастье. :-)
                0
                У меня есть стойкое ощущение, что можно написать универсальное средство, которое можно законфигурить под любой проект,

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

          А то, так заходишь в проект и смотришь, вроде те же модели, вью и контреллеры, а по сути ничего не понятно.
          +8
          Какие-нибудь плиточники тоже не всех коллег считают за истинных плиточников. По-моему, просто существуют программисты разной квалификации.
            +4
            В статье есть один абзац, за повторение которого и в стомиллиардный раз не может быть стыдно:
            … А всего лишь правильно и однозначно даны имена переменным и функциям.


            Всё остальное (про что в стомиллиардный раз написано в этой статье) очень сильно зависит от стека технологий (и, соответственно, парадигменного круга), жизненного цикла программного продукта, механики процесса разработки и т.д. В отрыве от этого рекомендовать некомпетентным людям принимать такие практики с целью повысить их компетентность — не самый лучший способ сделать мир лучше (да, я в курсе, что хорошие практики этой «притчи» специально ограничены PHP, его стеком и типичными веб-приложениями, но — нет, не самый лучший способ).

            За дровишки в костёр споров — спасибо.
              +11
              Пишите хорошо, плохо не пишите.
                0
                Спасибо, так и поступлю
                0
                По моему кодер — это быстрый программер. Конечно качество от этого страдает. Но часто чистых кодеров и чистых программеров не бывает.
                Глядя на застой в существующем техническом прогрессе понимаешь, что тех и других либо очень мало, либо они заняты не тем чем должны.
                Очень часто сейчас мы располагаем такими аппаратными возможностями, которые программно не используются никак.
                Нужно радоваться наличию тех и других и двигать прогресс, а не только свой кошелёк. Вот в чём главная ошибка.
                  +1
                  Думаю, у всего есть предназначение, даже если оно не очевидно… Скорость кодеров полезна на маленьких или одноразовых проектах, например, при создании прототипов. Программистов логично привлекать к созданию и поддержке крупных проектов.
                    0
                    а как насчёт способности кодеров связывать большие, готовые проекты в один?
                    Я думаю кодеры должны это делать быстрее, чем программисты. А это влияет на прогресс очень хорошо. Часто существует множество разных проектов, которые, если соединить, то получится очень интересная программа.
                    Если дать разрабатывать это программисту, то он посмотрит на вас, как на сумасшедшего и скажет, что надо ещё таких же как он человек 5 и времени пол года — год зарплату платить. Получается кодер эффективней программиста.

                    Даже, если в этом потом будет сложно разобраться, то цена приемлемая за хорошую идею. Просто надо сразу задачу ставить правильно кодеру… и не будет проблем.
                      +1
                      Интересная мысль, но кодеры не связывают большие проекты в один — это делают предприниматели, правда они тоже могут быть кодерами. Суть статьи проста — качество кода никогда не встретится со скоростью разработки и стоимостью
                        0
                        это вы про совсем большие, самостоятельные проекты, а я про модульные и не самостоятельные. Да взять туже CMS. CMS сама по себе не нужна никому и по большому счёту не сайт. Но кодер сделает из неё сайт быстро, а программер будет писать сайт сам, без CMS и конечно он не будет таким гибким и могучим, как CMS. Ну или кодер будет использовать готовые модули в CMS, а программер будет их писать сам. Оба примеры не очень удачны, но понять можно, что в каких-то моментах именно кодер — это тот человек, который нас вытащит из болота, когда все программы уже написаны, а мы до сих пор паримся над тем, как написать одностраничный сайт с картинкой)).
                    0
                    Кодер — тот, кто умеет писать код.
                    Программист — тот, кто умеет писать программы.

                    По-моему тут все понятно :-)
                    +11
                    Нужно просто решать задачу. Любая деятельность должна быть направлена на решение какой-то задачи. Нет хороших программистов, плохих программистов и кодеров. Нет плохих заказчиков, хороших заказчиков или чего-то еще. Есть задача, которую нужно решить, в заданных граничных условиях.

                    Граничными условиями для бизнеса, с моей точки зрения, в 90% случаев являются:
                    1. бюджет
                    2. сроки
                    3. приемлемое качество

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

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

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

                    И да, я тут не рассматриваю случай, когда все вот эти class User образуют систему столь сложную и сильносвязанную, что лучше уж бы копипаст. Оверинжинириг это тема отдельного большого холивара.
                      +2
                      По тексту статьи даже идти не хочу, но там половина — как минимум крайне сомнительна. Ну вот просто для примера:
                      class MailerWrap { public function send($params) { return Mailer::send($params); } }

                      Смотрите сами:
                      1. Что каждую подключаемую библиотеку во враппер оборачивать? У вас тогда проект превратится в кучу врапперов.
                      2. Наверное там кроме названия метода с send на post поменялось еще что-то, сигнатура например. Потому что смысл менять название метода, ломая обратную совместимость только ради названия? Так никто не делает, и значит ваш враппер будет беспозерен.
                        0
                        Это пример, а не призыв к действию. Цель — постараться объяснить аудитории смысл паттерна «метод доступа». Если в проекте есть внешний компонент с меняющимся интерфейсом, то для простоты и удобства изменения его можно «обернуть»
                          +6
                          Пример неудачный. Вы рассуждаете из будущего, «что вот если бы он знал, что изменится интерфейс, то надо было сделать враппер». Откуда было понятно, что именно этот внешний компонент «с меняющимся интерфейсом»? У него в документации написано, что каждый релиз меняется интерфейс? Классическое «знал бы прикуп жил бы в Сочи». Альтернатива — только писать врапперы на все, но это уже тупак какой-то.
                            0
                            А как еще писать юнит тест на код, который использует этот мейлер?

                            см. hexagonal architecture
                              +1
                              Да легко, если у вас мейлер изначально абстрагирован. А если не абстрагирован — то это беда, и лучше использовать другой.

                              А так получается абстракция ради абстракции.
                                0
                                Мы рассматриваем этот мейлер — каковой вызывается статическим методом. Это раз.
                                А два — ваш мейлер может оборачивать готовый с целью внести специфику приложения (например — добавляет стандартную для приложения подпись и т.д.)
                                  0
                                  подпись чего? письма? и для этого заворачивать мейлер? заворачивать мейлер вижу смысл когда его нужно приткнуть ко фреймворку, например, для использования вьюх для писем, а вот там уже инклудить стандартную подпись для приложения
                                    0
                                    Неважно. «Посылка почты в приложении X» может иметь свою специфику по сравнению с «посылкой почты вообще», каковую специфику полезно выделить в отдельный юнит.
                                      0
                                      … и этот юнит не является враппером вокруг мейлера, и не имеет никакого отношения к юнит-тестированию.
                                        0
                                        Не является но может быть нужным к юнит тестированию имеет отношение — позволит писать тесты более удобно
                                          0
                                          Нет, не позволит. Эта «специфика» — это тоже тестируемый код, поэтому вам нужно изолировать зависимость на шаг дальше.
                                            0
                                            Это уже будет другой код, а тот, исходный позволит.
                                              0
                                              А в «тот, исходный» нельзя вносить специфику вашего приложения.

                                              Говорю же, два разных куска кода с разными целями.
                                                0
                                                Можно в нем как раз она и есть. (Тот исходный это не мейлер, если чо, а код использующий мейлер — сам-то мейлер мы не тестируем)
                                                  0
                                                  Если она в нем есть, то ее надо тестировать. Значит, надо разрывать зависимость с используемым мейлером. Далее смотри выше.
                                                    0
                                                    Дык я не говорю, что это снимет полностью проблему тестирования — я говорю что облегчит. (см ваше «не имеет никакого отношения к юнит-тестированию»)
                                                      0
                                                      Наличие дополнительной функицональности не облегчает тестирование.
                                                        0
                                                        Существует такая дополнительная функциональность в X которая облегчает тестирование Y, использующее X так как позволяет не тестировать его внутри Y
                                                          0
                                                          Вы эту функциональность тестировать не собираетесь?
                                                              0
                                                              А вы считаете, что декомпозиция функциональности на два компонента всегда облегчает тестирование?
                                                                0
                                                                Я обычно не так категоричен — может облегчить.
                                                                  0
                                                                  А может и нет. Что возвращает нас к вопросу об осмысленности добавления врапперов в произвольных местах.
                                          0
                                          а почему не использоать заведомо рабочий враппер сугубо для тестирования почтового враппера?
                                            0
                                            Единственный способ получить заведомо рабочий враппер — это протестировать его. Далее см. сначала.
                                              0
                                              я имею в виду, что враппер для тестирования обернутого мейлера, который используется в приложении, сделать как только можно проще чтобы его не тестировать ибо там нечему валиться или взять заведомо протестированную простую обертку
                                              или нам все равно нужно тестировать и саму обертку?
                                                0
                                                Не надо тестировать мейлер (он сторонний). Надо тестировать код приложения, который с ним взаимодействует (например, что он посылает то, что нужно и тогда, когда нужно).

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

                                                Как только речь заходит о «а давайте этот враппер будет еще и что-то делать (добавлять подпись, шифровать, блаблабла)» — нарушается принцип единой ответственности.
                                                  0
                                                  Надо тестировать код приложения, который с ним взаимодействует

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

                                                  мы либо говорим о разном и не понимаем друг друга, либо говорим об одном и том же, но разными словами )
                                                    0
                                                    Речь изначально шла о том, нужен ли враппер для мейлера.
                                                0
                                                В динамическом языке враппер, наверное, не нужен, надо только абстрагировать создание.
                                                  0
                                                  Это, как уже говорилось, не единственный вариант.
                                        0
                                        Вот либо раз, либо два. Потому что оборачивание статического метода — это специфика используемого языка (где, судя по всему, нельзя мокать статические вызовы) и используемого мейлера (который лучше заменить на вызываемый по интерфейсу).

                                        А внесение специфики — это уже совершенно другой паттерн, который предполагает появление дополнительного отдельно тестируемого компонента.

                                        Иными словами, если у вас одновременно и раз, и два, то вам нужен и враппер для тестируемости, и прикладной компонент, добавляющий функциональность.
                              –1
                              С целью рещить задачу вы (не именно вы, а обобщенно) в итоге делаете настолько плохо, что забываете что такое хорошо. Вы облениваетесь, любые бюджеты начинаете считать маленькими и продолжаете говнокодить. И в итоге даже с большим бюджетом вы все продолжаете говнокодить. Вы никогда не вырастете, если будете просто решать задачу. Потому что любую задачу вы будете просто решать не пытаясь сделать лучше или применить какую-нибудь новую фичу. Вы просто остановитесь в развитии, как специалсит. Был где-то пост про то, что одни люди постоянно ищут поводы, чтобы что-то не делать. а другие ищут способы обойти ограничения. Над каждой задачей нужно работать и каждую задачу можно сделать хорошо за приемлимое время и бюджет. Просто нужно искать решения, а не говорить, что есть задача, бюджет маленький, времени мало и поэтому ловите ваш кусок сами понимаете чего.
                                +1
                                Возможно я выразился не совсем корректно. Естественно нужно пытаться сделать максимально хорошо, в рамках ограничений, но само по себе их наличие (в том числе ограничений существенно ухудшающих качество продукта) не является чем-то плохим, это объективная реальность.

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

                                Вот вам пример — я делаю сан узел. У меня в нем кривой пол — перекос около сантиметра. Мастер естественно предлагает заливать стяжку. Но стентиметр стяжки залить нельзя — она треснет, минимум 5 (в самом высоком месте) в низком соответственно — 6. Тогда будет идеально ровный пол и все круто.

                                Минусы — растет цена, растет срок, «опускается потолок», появляется ступенька на входе в санузел.

                                Альтернатива — положить плитку как есть.
                                Минусы — я буду знать что мой пол кривой (на глаз это не видно), чуть сложнее с установкой стиралки и мебели, но регулируемые ножки решают все проблемы, чуть расширяющийся стык между полом и стеной.

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

                                Кстати побывать заказчиком — очень позитивный опыт, я многое для себя переосмыслил. Рекомендую.
                                  0
                                  Это опять же с мастером что-то не так. Вот он как раз просто решал поставленную задачу. А когда мне нужно было выровнять пол на 40мм, то я использовал вот это — www.ivsil.ru/catalogue/div4/item14.html. И ничего не трескается. Для больше надежности он еще сетку положил туда металлическую, но думаю можно было и без нее.
                                    0
                                    Тонкая стяжка потеряет несущую способность после отслоения (очень вероятная ситуация для цементной стяжки). Даже на сайте указано, что минимальная толщина стяжки 10 мм, хотя честно говоря сомнительно что 10мм стяжка будет надежной. Но речь не об этом, а о том, что меня устраивает кривой пол, но без ступеньки на входе больше чем ровный, но поднятый (даже на 10мм). И если я заказчик, хочу за свои деньги плохо, то в этом нет ничего страшного :-)
                              +1
                              А потом приходит понимание, что нужно ипользовать декларативное программирование в виде внедрения ависимостей и контейнеров. И жить становится гораздо проще. Да, снала многие не понимают, зачем вся эта морока нужна, если все можно сделать гораздо проще и меньшим количеством кода (навеяло постом вы сломали javascript). Но, когда начинаешь писать, проходит время, добавляется функционала, рефакторится код и тогда уже приходит понимание. Но для многих уже становится поздо, что-то изменять.
                                +3
                                Второй пример, когда в константу выносится еще и имя таблицы — это иллюстрация того как делать не нужно, и называется оверинжиниринг. Таблица в селекте уже имеет осмысленное имя. Также, этот кусок кода находится в классе User, а не в каком-нибудь ValidationRules.
                                  0
                                  Да, возможно, пример с именем таблицы неудачный, но представьте себе, что вы решили изменить название таблицы в БД, а запросов с явным её указанием много по коду проекта, тогда вариант с именованной константой более удобен для рефакторинга
                                    +2
                                    А представьте себе, что вы решили запускать сервер приложения не на php, а в виде нативного приложения на айфоне. А клиент не в браузере, а в виде Windows Forms Application. Что тогда?

                                    Закладываться на сомнительные «потребности» и есть оверинжиниринг. Почитайте про YAGNI. Не то, что бы ему надо следовать на 100%, но вот для таких примеров как ваш, отлично подходит.
                                      0
                                      Конечно, умение корректно определять граничные условия и уместно использовать приёмы/инструменты — важнейшие навыки профессионального инженера. Я убрал именованную константу для таблицы из статьи, чтобы не создавать прецедент оверинжиниринга, хотя это был просто пример, а не кусок кода реального проекта. Думаю, прочитав комментарии, аудитория сможет лучше понять баланс между гибкостью кода и «переразработкой».
                                  +2
                                  На самом деле не хватает одного главного примера — ТЕСТов.
                                  Если бы ТС их писал, то увидел бы, что у нет особой разницы между обоими его подходами, всё тот же лапшакод с захардкоджеными зависимостями, неперегружаемыми статическими методами и глобальными переменными.
                                    +2
                                    Но благодаря ООП и специально подготовленному классу User можно написать значительно короче и понятнее:
                                    $user->loadById($id);
                                    echo $user->name;


                                    Плохой пример, если честно.

                                    Чем в данном случае является объект $user?
                                    Если это объект, связанный с записью в БД в соответствии с концепцией ORM, то он может либо находиться в синхронном состоянии с конкретной записью, либо быть рассинхронизирован (например, при создании нового объекта, который еще не имеет записи в таблице/-ах). В первом случае метод ->loadById() не нужен (мы уже в синхроне), во втором — невозможен (записи-то нет уже или еще).

                                    Правильнее или реализовать этот метод в виде статического метода класса
                                    $user = User::findById($id);
                                    

                                    или как в Doctrine — отдельной сущностью, EntityManager, управляющей персистентностью.

                                    А ваш код — это не ORM, это говнокод какой-то. Сначала создаем объект, а потом его заставляем найти себя же в БД?
                                      +2
                                      Благодарю за Ваши подсказки, поправил текст примера
                                        +2
                                        Не за что.
                                        Статья весьма жизненная.
                                      +1
                                      Прочитав этот пост я понял, что:

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

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

                                      Вот и всё.

                                      Сам я пишу говнокод и очень этим горжусь. Ибо 99.(9)% кода — пишется один раз. И повторно не используется. Если, разумеется, вы не архитектор. Но если вы архитектор — тогда такие посты вам совсем ни к чему.
                                        0
                                        Именно поэтому выбрал в качестве картинки к статье христоматийную сцену боя между ситхом и джедаем… Как и говаривал мастер Йода — «Тёмная стороне не сильнее, а быстрее». На закате жизни, Дарт Вейдер всё же вернулся на светлую сторону, с которой и начинал, потому что до него дошла простая истина, что светлая сторона — это путь к гармонии…
                                        П.С.: прошу не воспринимать пост буквально, отсылки к «Star wars» носят иносказательный характер
                                          +3
                                          Хороший, плохой… Главное, у кого ружьё!

                                          И на хабре есть адепты тёмной стороны Силы, и нельзя сказать, что они так уж неправы. Во всём важен баланс.

                                          Кстати, если очиститься от эмоционального отношения к вопросу, то получается, что Империя — оплот порядка — как раз и пишет в корпоративном стиле. Читаемый, поддерживаемый код со всеми шаблонами и красивостями. А джедаи, наоборот, пишут неподдерживаемый, хотя и гениальный говнокод, в котором кроме них никто разобраться не может. И только сами, джедаи, призвав на помощь силу (поллитру) могут с этим кодом что-то такое сотворить.

                                        +1
                                        Статья — оскорбление кодеров. ;) Кодер не является «плохим программистом», так же как хакер не является преступником.
                                          +1
                                          Статья ни в коем случае не попытка кого-то задеть или уязвить, как и писалось до хабраката — цель уяснить разницу
                                            +1
                                            Ну и не уяснили. Очередной слоовоонанизм, извините. Вёдра воды без конкретики. «Кодер», «программист», какая разница? Очередная попытка поклеить своих ярлыков. А точнее, рассказать о своих поклеенных ярлыках, используя для этого достаточно сомнительные примеры.
                                              0
                                              Да, для многих статья не откровение, но ещё одна возможность порефлексировать и переоценить все что делаешь и как делаешь — разминка для мозгов
                                          +2
                                          кому как, а мне вступление понравилось больше примеров
                                            +1
                                            Вот и думаю, может лучше научно-фантастический роман начать писать, а не CRM/ERP системы, как обычно :)
                                            0
                                            $user = User::model()->findByPk($id);
                                            Это так код стал «проще»? Это, наоборот, хороший пример, как ООП в руках кодера порождает страшный говнокод.
                                            Что это за model(), зачем оно здесь? (Я знаю про MVC, но к чему этот вызов здесь?)

                                            Код без ООП выглядел бы гораздо проще и понятнее:
                                            $user = user_load($id);

                                            Знаете, чем программист отличается от кодера?
                                            1. Программист пишет логи.
                                            2. Программист пишет тесты.
                                            3. Программист проверяет все коды возврата функций и исключения и корректно их обрабатывает.
                                            4. Программист не забывает расставить ассерты.
                                            5. Программист пишет грамотные комментарии к своему коду и своим коммитам.
                                              +1
                                              данный кусок кода взят из YiiFramework
                                              статический метод model — это некая статическая фабрика
                                              результате мы получим не просто данные из таблицы user, а AR-объект с другими плюшками, которые могут пригодиться далее: поиск по связанным таблицам, если такие есть, мы можем изменить данные и вызвать метод save объекта $user и сохранить запись в таблице, можем провести вализацию
                                              используя Ваш неООП подход, мы не сможем такого сделать, а будем городить костыли или писать велосипеды
                                                0
                                                Вообще-то это действительно так себе. И в Yii2 уже
                                                $post = Post::find($id);
                                                

                                                И кто мешает
                                                $user = user_load($id);
                                                $user->validate();
                                                

                                                ???
                                                  0
                                                  речь шла о конкретном примере и это в YiiFramework
                                                  да ничего не мешает. просто код читабельнее и я сомневаюсь, что в функцию user_load вы нормально воткнете все плюшка AR. ну разве что, использовав её как враппер, но мы же говорим о читабельности и поддерживаемости кода
                                                  +3
                                                  можем изменить данные и вызвать метод save объекта $user и сохранить запись в таблице, можем провести вализацию

                                                  user_save($user);
                                                  user_validate($user);
                                                  

                                                  В чем проблема? Где костыли?

                                                  Процедурный стиль, ООП стиль, функциональный стиль — это лишь инструменты. И не в выборе инструментов дело. А вот то, как эти инструменты используются и отличает программиста от кодера. Если вы не в курсе, то Линус пишет на С, а не на С++, и прекрасно обходится без статических фабрик.
                                                    0
                                                    >>В чем проблема? Где костыли?

                                                    Нет способа хорошо выделять общий код типа:

                                                    foreach($modifiedObjects as &$object)
                                                    {
                                                          if ($object -> validate())
                                                          {
                                                              $object -> save()
                                                          }
                                                          else
                                                          {
                                                              $objectsWithErrors -> add($object)
                                                          }
                                                    }
                                                    
                                                    


                                                    Процедурный стиль, ООП стиль, функциональный стиль — это лишь инструменты. И не в выборе инструментов дело.

                                                    Иногда в них. Я сомневаюсь, что PHP хороший язык для функционального программирования (ленивые вычисления, классы типов, функции как значения первого класса есть?), а ООП в нем уже общее место.
                                                      0
                                                      А вот это уже полиморфизм — и это сильная сторона ООП =)

                                                      Способ, конечно же, есть:
                                                      foreach($modifiedObjects as &$object)
                                                      {
                                                            if ($object['validate']($object))
                                                            {
                                                                $object['save']($object);
                                                            }
                                                            else
                                                            {
                                                                $objectsWithErrors []= $object;
                                                            }
                                                      }
                                                      

                                                      В таком подходе есть один серьезный плюс — легко менять методы «на лету», создавая объекты, не привязанные к классам.
                                                      Но, смотрится это плохо, да и IDE не сможет подхватить эти функции. Это магия Си, её не нужно использовать в языках с развитым ООП.
                                                        0
                                                        вот это уже полиморфизм — и это сильная сторона ООП =)

                                                        функциональщики говорят, что у них это тоже есть (type classes)

                                                        Способ, конечно же, есть

                                                        Итого: мы согласились с тем, что хорошего способа нет.
                                                          +1
                                                          Функциональщину я даже не рассматриваю — её преимущества не объяснить в комментариях, особенно ярым адептам ООП.
                                                          Хорошего способа — нет. Т.е. можно сделать ООП код без ООП конструкций языка (суть ООП не в ключевых словах, а в полиморфизме, наследовании), но с ними проще и понятнее. Там где действительно нужен полиморфизм — уходить в процедурщину я не советую.
                                                      0
                                                      костылей нет. я не говорю, что это какой-либо костыль
                                                      дело в том, что если дальше раширять приложение, то гораздо уробнее и приятнее расширять его если приложение было грамотно спроектировано
                                                      в моем опыте было два php-фреймвока (второй yii). даже два фремворка, реализующие MVC очень разнятся в удобстве работы сним. к примеру, в первом работа с БД реализована примерно так, как Вы описали выше:
                                                      load('user', $userId);
                                                      load('category', $categoryId);
                                                      load('foo', $fooId);
                                                      

                                                      тоесть, там есть один класс Модель, который в конструктор принимает имя таблицы и потом от него танцуем. Да, получить данные с таблицы мы можем, но мы не забываем о принципе «Fat model, skinny controller», следуя которому, бизнес-логику следует вкладывать в модель для повторного использования, а не в контроллер. чтобы это сделать я допилил следующим образом: я расширил этот базовый класс Model и имею классы UserModel, PostModel и т.д… в них же реализую бизнес-логику. если же подходить к вопросу в процедурном стиле, то я не представляю как реализовать это.
                                                        0
                                                        если дальше раширять приложение, то гораздо уробнее и приятнее расширять его если приложение было грамотно спроектировано

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

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

                                                        Не представляете? Наверное, мало работали в процедурном стиле?
                                                          0
                                                          да, плохие и хорошие проекты есть, но речь сейчас не об этом
                                                          Не представляете? Наверное, мало работали в процедурном стиле?

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

                                                          для чего тогда спорить? мы говорим об одном и том же
                                                    0
                                                    Это тяжелое наследие первого Yii, который ради обратной совместимости с PHP<5.3 не мог использовать метод __callStatic для статических методов класса-модели.
                                                    Не ругайте программистов, они извращались в то время как могли, и все-таки сделали неплохой продукт.
                                                      +1
                                                      Ой, я не ругаю программистов, я лишь говорю, что это очень плохой пример преимуществ ООП. Можно было найти гораздо лучше.
                                                      Скажем, такой:

                                                      // Этот код выполнится, но когда где-нибудь потом всплывет ошибка, будет очень тяжело её локализовать
                                                      $user['age'] = -5;
                                                      
                                                      // А вот этот код может отреагировать на неверное значение: ассертом, исключением, кодом возврата или же просто не изменив состояние объекта.
                                                      $user->setAge(-5);
                                                      
                                                        0
                                                        Вы не поверите, но PHP позволяет и в первом случае модифицировать поведение объекта.
                                                        И иногда (редко, конечно) это пригождается.
                                                          0
                                                          Вы про ArrayAccess?
                                                            0
                                                            Например да
                                                              0
                                                              Так это ООП.
                                                                0
                                                                Разумеется.
                                                                Причем высшая его степень — вся логика инкапсулирована в классе. А конечный «потребитель» видит наш объект, как просто массив. Не догадываясь в простых случаях о его внутренней структуре

                                                                $collection = new Collection;
                                                                $collection[] = $item1;
                                                                $collection[] = $item2;
                                                                $collection->doSomethingWithAllItems();
                                                                
                                                                — где еще такое возможно?

                                                                Если наконец примут предложение насчет метода __cast(), PHP вообще станет самым полиморфным языком на свете.
                                                                  0
                                                                  В C++, например. В PHP, насколько я помню, еще нет перегрузки операторов, так что до С++ еще расти и расти =)
                                                                    0
                                                                    Ваша правда. Я ж не спорю )))
                                                                    0
                                                                    — где еще такое возможно?

                                                                    А в питоне и руби разве нет?
                                                        0
                                                        А код без ООП (в данном конкретном случае) не решает основную проблему — каждый раз придется копипастить функции типа user_load(), product_load(), category_load(), foobar_load(), копируя один и тот же код (сводящийся к банальном запросу к БД). Вместо того, чтобы один раз написать метод load() в абстрактной модели.

                                                        И, разумеется, писать такое же количество банальных тестов. В ООП достаточно будет грамотно простестировать абстрактную модель. Один раз.
                                                          0
                                                          Если `_load` сплошь одинаковые, то никто не мешает написать одну функцию — `load`
                                                          load('user', $userId);
                                                          load('category', $categoryId);
                                                          load('foo', $fooId);
                                                          


                                                          Если же функции все-таки разные (а обычно так и происходит), то при любом подходе придется писать дополнительный код и дополнительные тесты.
                                                            0
                                                            Как их сделать, чтоб при этом не получилось убогое подобие того, что и так есть в объектной системе PHP?
                                                          +1
                                                          1. Иногда программист не пишет логов, ибо их некуда писать. Например, на микроконтроллере.
                                                          2. Иногда программист не пишет тестов, ибо для их написания нужно отрефакторить такую кучу legacy-кода, который написали до него, что он понимает нецелесообразность этого действа.
                                                          3. Иногда программист может не знать про какой-то код ошибки одной из внутренних библиотек, которую используют уже давно, и у нее нет автора, исходников и документации. Как-то работает — и все тут.
                                                          Да, и иногда программист может некорректно обрабатывать исключения и коды ошибок — например, падать вместо попытки исправиться. Все бывает.
                                                          4. Иногда программист не расставляет assert'ы. Например, их нет в том языке программирования, на котором он пишет.
                                                          5. Программист не всегда пишет комментарии. Код — лучшая документация, поэтому лучше написать код так, чтобы надобность в комментариях отпала.
                                                            0
                                                            Иногда это все допустимо. Только ситхи возводят все в абсолют!

                                                            иногда программист может некорректно обрабатывать исключения и коды ошибок — например, падать вместо попытки исправиться.

                                                            Падать вместо попытики исправиться — это иногда совершенно корректная обработка ошибок ;) Особенно во время разработки.
                                                          +2
                                                          Чем больше кодеров — тем дороже я стою :)
                                                            +1
                                                            Я бы программиста переименовал в статье в разработчика.

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

                                                            И это правильно — они программируют и они программисты.

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

                                                            Программист пишет код, а разработчик разрабатывает продукт. И отсюда вся разница в качестве.
                                                              0
                                                              Кодер пишет код.
                                                              Программист пишет программу.
                                                              Разработчик разрабатывает систему и строит бизнес-процесс, поддерживаемый этой системой.
                                                              Часто разработчик по-совместительству допиливает и процесс самой разработки.

                                                              Чувствуете разницу?
                                                              +1
                                                              Чо-то тут не то
                                                              if ($user->isGuest) $user->register($user->email, $user->name);
                                                              


                                                              Зачем какому-то пользователю регистрировать чье-то другое имя и email — наверное $users -> register($user)?

                                                                0
                                                                В модели:
                                                                boolean registerUser(String email, String name);
                                                                User getUserByName(String name);
                                                                Если очень хочется, то можно и для почты сделать отдельный тип
                                                                  +3
                                                                  Должно быть либо $userModel->register($user), либо $user->register()
                                                                  Все, достаточно. А то, что в топике — классический такой говнокод =)
                                                                    +2
                                                                    вроде так и написал, но ладно) Основная мысль в том, что автор по сути написал статью сам про себя сам того не понимая. Но статья от этого по мне стала еще лучше. На плохих примерах люди лучше учатся. Самое главное это не считать себя лучше других, а просто развиваться, как специалист. Если вы действительно лучше, то знающие люди это увидят, поверьте. Этим грешат джуны и это приходит со временм. Да и я сам от этого пока совсем не избавился, но в целом стараюсь. И кроме дикого самомнения, которое видно всем и никому не нравится (даже если оно и оправданное), это еще и забивает голову абсолютно ненужными мыслями. Даже на примере статьи, посчитайте, сколько времени автор потратил на нее. И исключительно для того, чтобы показать, что он лучше, чем другие.
                                                                      0
                                                                      Вопрос в том, понял ли автор, что он написал статью сам про себя? Возгордился и попал в сети темной стороны Силы =)
                                                                        0
                                                                        Да, конечно, если говорить о стороне силы, то я наверное Анакин Скайуокер/Дарт Вейдер — побывал и на тёмной и на светлой стороне, потому и сравниваю. За объяснения спасибо, поправил пример в статье
                                                                          0
                                                                          Вы считаете себя хорошим программистом?
                                                                            0
                                                                            Нет, я скорее просто многоопытный
                                                                +2
                                                                Если следовать классификации автора то должен быть еще третий уровень — разработчик. Разработчик этот тот человек который решает проблему средствами позволяющими сделать это оптимально. Так имхо будет честнее.
                                                                  –1
                                                                  Разработчик не ограничивается программой.
                                                                  Он мыслит проблемами и бизнес-процессами с точки зрения пользователя.

                                                                  Так точнее. :-)
                                                                    0
                                                                    Увы, тут действует бинарная логика. И оптимизировать уже качественно оптимизированное не имеет смысла. Вы либо говнокодите, либо пишите так, чтобы потом гордиться своей работой
                                                                      0
                                                                      По вашей классификации код либо идеален, либо это говнокод.
                                                                      Если человек не знает какой-то библиотечной функции, которая элегантно решает задачу, и в единственном месте написал вместо одной строки две-три, то всё — он говнокодер?
                                                                        0
                                                                        Нет, он просто совершил переразработку (оверинжиниринг), но если код правильно оформлен, расположен в соответствующем модуле проекта и (само)документирован, то это не говно код, а альтернативная реализация. Этот код изолирован и его легко изменить в случае, когда программист поймёт, что его можно элегантно улучшить. Это главное в качественном коде.
                                                                          0
                                                                          Идеального кода нет, и это нужно понимать. Фокус в том, чтобы сделать код максимально простым, понятным и приспособленным к дальнейшим изменениям и модернизации любым программистом. Это и есть основные критерии качества кода для проектов с длительным сроком разработки/поддержки. Оптимизация подразумевает улучшение какой-либо качественной характеристики за счёт ухудшения других, значимость которых в текущих условиях не столь велика.

                                                                    Only users with full accounts can post comments. Log in, please.