Как стать автором
Обновить

Комментарии 28

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

Только прошу вас, не пишите примеры в стиле наследуем пингвина от слона и добавляем интерфейс "плавать":)

Хотелось бы видеть более практичные кейсы.

Подробнее чем Мартин и Макконнелл всё-равно не напишешь, их труды фундаментальны.
Это скорее статья-напоминание.
Ну и ссылку на доку для джавистов в статье вижу.

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

Или ещё лучше: игнорировать существовать паттернов программирования. А то вдруг другие программисты их не знают.

Согласен, но часто разработчики злоупотребляют и паттеранми и абстракциями. К примеру https://habr.com/ru/company/abbyy/blog/173885/

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

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

Это просто статья, где много пересказа Роберта Мартина и чуток Мартина Фаулера с его рефакторингом. Хоть бы от себя добавили чего:)

Ну как же, добавили описание Idea!

По сути согласен: перепевка Мартина, и не более.

На самом деле здесь все из разряда «Капитан Очевидность». Не будем решать задачу «как сделать код понятный всем», хотя бы только для себя, спустя некоторое время. А сделать это достаточно нетривиально, если нет «семи пядей во лбу».

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

Если приходится иметь дело с чужим кодом, то прежде чем начать серьезно работать с ним, я его «причесываю». Иначе, просто не могу адекватно воспринимать. Если интересно, можете посмотреть мой C++ код в моих последних двух статьях:

habr.com/ru/post/566864
habr.com/ru/post/466713

По-хорошему, чтобы понять чужой код, нужно чтобы программист описал его в своей статье либо статьях. Да и мало просто хорошего стиля, должна быть еще «правильная» парадигма программирования. А тут трудно вести речь «вообще», даже по частным направлениям, скажем, программирование GUI на C++ / WTL уже может вызвать кучу споров, начиная с того, зачем вообще нужно иметь дело с этими инструментами?

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

В его команде один человек, которому стиль подходит - это он сам.

> А если ваш стиль или концепция не подходит команде?

Я не думаю, что мой стиль не подойдет команде. Просто я сторонник красиво оформленного кода. А многие просто ленятся наводить лишний марафет на свои программы. Это хорошо видно по опенсорсу.

Что до концепции, то здесь погоду делает рынок, то бишь, ориентация на максимальную прибыль. Особенно, в крупных программистских компаниях. Мне, волею судьбы, не пришлось там работать. Соответственно, логично исходить из собственных интересов. Которые заточены на удовольствие от программирования. Да, это не командный стиль, там важнее скорость и запланированный результат. Но, именно корпоративные программисты придумали стишок :)

Тяжела и неказиста жизнь простого программиста,
Легка и казиста жизнь сложного программиста.

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

Есть у кого то на примете какой-нибудь проект с открытым исходным кодом, популярный (библиотека, приложение), в котором бы было видно применение чистого кода?

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

Могу привести пример из своего проекта. Не стал все пихать в один класс.

Пример вывода линии. Делал по примеру SDL.

https://github.com/JordanCpp/Lt/blob/master/Examples/Graphics/05_DrawLine/main.cpp

#include <Lt/Graphics/Render.hpp>
#include <Lt/Graphics/FpsLimiter.hpp>
#include <Lt/Core/Console.hpp>
#include <Lt/Graphics/FpsCounter.hpp>

//Для удобства вывода ошибки
void ShowError(const Lt::Core::ErrorHandler& errorHandler)
{
	Lt::Core::Console console;

	console.Write(errorHandler.Message());
	console.Show();
}

int main()
{
  //Создаем обработчик ошибок
	Lt::Core::ErrorHandler errorHandler;

  //Создаем окно
	Lt::Graphics::Window window(&errorHandler, Lt::Graphics::Point2u(0, 0), Lt::Graphics::Point2u(800, 600), "Window!");

	if (errorHandler.Error())
	{
		ShowError(errorHandler);

		return 0;
	}
  //Создаем рендер
	Lt::Graphics::Render render(&errorHandler, &window);

	if (errorHandler.Error())
	{
		ShowError(errorHandler);

		return 0;
	}

	Lt::Events::Event report;
//Создаем счетчик fps
	Lt::Graphics::FpsCounter fpsCounter;
  //Создаем IntegerToString
	Lt::Core::IntegerToString integerToString;

	while (window.GetEvent(report))
	{
		render.Color(Lt::Graphics::Color(195, 195, 195));
		render.Clear();

		if (report.Type == Lt::Events::IsQuit)
		{
			window.StopEvent();
		}

		render.Color(Lt::Graphics::Color(237, 28, 36));
		render.Line(Lt::Graphics::Point2u(0, 0), render.Size());

		render.Present();

		if (fpsCounter.Calc())
		{
			if (integerToString.Convert(fpsCounter.Fps()))
			{
				window.Title(integerToString.Result());
			}

			fpsCounter.Clear();
		}
	}

	return 0;
}

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

https://github.com/JordanCpp/Lt/tree/master/Tests/Graphics

Так же в классы вынесены такой функционал как, создание скриншотов и ограничитель fps

https://github.com/JordanCpp/Lt/blob/master/Tests/Graphics/Screenshoter.cpp

К примеру конвертация пикселей, тоже имеет свой отдельный класс.

https://github.com/JordanCpp/Lt/blob/master/Tests/Graphics/PixelConverter.cpp

Такой способ мне помог написать тесты и не писать жирные классы содержащие джунгли и гориллу.:)

Еще как пример. Не стал пихать в класс окна обработчик сообщений. Он реализован отдельно, и так же к нему написан тест.

https://github.com/JordanCpp/Lt/blob/master/include/Lt/Events/Eventer.hpp

Сам тест.

https://github.com/JordanCpp/Lt/blob/master/Tests/Events/Eventer.cpp

Сам я такую моду взял из C#, так как является основным языком для работы. С++ навещаю как любовницу:)

Сходу в глаза бросаются очевидные (не нужные) комкментарии, множество пустых строк, из-за которых метод разросся

Всегда отделяю строки между собой, пустой строкой.

функции должны делать что-то одно

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

НЛО прилетело и опубликовало эту надпись здесь

Совет по именам он прямо очень вредный. Никаких

int fileSizeInBytes

и уж тем более

Date generationTimestamp

быть не должно, несоответствие между Date и Timestamp приводит к ещё бОльшему количеству WTF. fileSizeInBytes просто долго читается и отвлекает от сути, забиывает голову ненужными нюансами. Эти переменные должна называться size и generation, то что это Date видно из типа, никакой это не Timestamp внезапно

date.happensInLeapYear

должно быть

date.year.isLeap

Как правильно уже написали выше про i,j,k в циклах полностью норм, и остальные локальные переменные должны быть одним словом, одним.

List<WordFrequency> wordFrequencyList = getWordFrequencyList(inputStr)

ещё один ужасный пример, на кой черт постоянно переписывать WordFrequency и List когда они уже есть в типе

List<WordFrequency> frequencies = parse(input)

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

Про "функция должна делать что-то одно" уже много раз говорили по-моему, что Мартин сам неоднократно переобувался что же он имел в виду под этим, очередное мутное и непонятное "правило"

Ну единственное с чем можно согласиться так это с комментариями. Если программист не смог написать достаточно понятный код, не следует ожидать от него что он напишет понятный комментарий :-)

Как сказал один широко известный деятель в узких кругах, наименование размером менее 20-25 символов, как минимум выглядит не солидно)

Чем меньше аргументов у функции, тем она чище

сперва не понял, как такое может быть:)

потом дошло что чистая в плане clean, а не pure

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

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

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

Я бы хотел прокомментировать ситуации, когда комментарии вполне уместны:
Информация об авторских правах.

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

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

противоречит всему что было написано в этом параграфе про комментарии
Комментарии публичных API обязательны (JavaDocs, …), но избегайте их в непубличном коде. Не заставляйте команду комментировать все функции всех ваших классов!

Это те самые JavaDocs которые вставляются IDE автоматически, которые не добавляют ничего нового к описанию методов и параметров, потому что генерируются на основе имён методов и параметров, и никогда никем потом не актуализируются и не обогащаются дополнительными разъяснениями по используемым параметрам и особенностям работы методов. На основе таких комментариев генерируются странички с документацией, которая вроде как есть, но не разъясняет ничего о том, как использовать методы и какие параметры передавать, тому, кто нашёл эту документацию. И те редкие разработчики, как например разработчики Spring-а, гордятся тем, что стараются писать такие комментарии максимально подробно и поддерживать в актуальном состоянии.

По поводу "минимизировать кол-во аргументов у функции": посмотрите на read_excel в pandas и попробуйте уменьшить ...

Зарегистрируйтесь на Хабре, чтобы оставить комментарий