Pull to refresh

Comments 17

OFF: какой смысл в извлечении мозга?
> Включи мозг и извлекай, когда это имеет смысл
ага, название статьи какое-то дебильно-дебильное: «включи мозг»-«имеет смысл», а что извлекай… пока не прочтешь, думаешь «сам то мозг включил?»
уж лучше "Рефакторинг: выделяй метод, когда это имеет смысл"
Я бы сократил: «Рефакторинг — выделяй смысл» :-)
На мой взгляд тут нужно менять интерфейс. Поделив функцию на две: извлечение директории и извлечение файла.
Что касается отрефакторенного класса — лично меня напрягают классы которые что-то делают а потом сохраняют результат в себя чтобы вы могли достать его из свойства. На мой взгляд если вы хотите вернуть два и более значения — делите их обработку на разные публичные методы либо возвращайте структуру.
Более того. Как выглядело использование функции до рефакторинга? Вызвал функцию одной строчкой, и все. После рефакторинга — надо написать 3 строчки (если заметите ошибки в синтаксисе — простите, я джавист):

DirectoryFileSplitter ds = new DirectoryFileSplitter(myPath);
ds.Split() // почему бы не вызывать это в конструкторе?
string myLength = ds.length;

Ну так вот, мне приходилось пользоваться API, в котором надо выполнить 3 строчки для одного действия. Это такая боль, скажу я вам. То split() забудешь, то в первой и третьей строчке по невнимательности используешь разные переменные.

Теперь представьте, что надо реализовать сложную логику, где фигурируют 100500 разных директорий. Отладка станет болью и мучением. В результате вы напишете обертку, которая позволит вместо 3 строчек писать одну, и это будет как глоток свежего воздуха.
Абсолютно согласен.
Хочу добавить, что тут придется создавать объект, под который будет выделяться память в managed heap, что есть не очень хорошо.
Да и если логически подумать, это все ООП головного мозга, в BCL, например, ведь нет классов IntParser или NumberSummer.
--что та функция длиной в 5к строк

А в чем проблема с раземрами? В сервере одной из компаний в которой я работал были функции по 10К строк и тело класса находилось в файле размером почти мегабайт. (Прошлось просить компанию Perforce поправить их продукт чтобы работал с файлами таког размера).

Вроде никто неудобства не испытывал.
Сам факт того, что пришлось просить компанию Perforce о многом уже говорит.
UFO just landed and posted this here
Сам C# много лет уже не использовал, поэтому где-то могу ошибаться. Все мои советы нацелены на читаемость и понятность, а не на быстродействие.

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

2) «out» параметры довольно опасны и неочевидны. Если надо вернуть несколько параметров, то можно вернуть структуру или tuple (в C# tuples вроде давно есть уже).

3) Сама функция сложно воспринимается из-за if-условий для валидации. Проваленные валидации должны выходить нафиг из функции или кидать исключение:
// Так лучше не делать.
if (path != null) {
    // Тут весь оставшийся метод.
}

// Так будет понятнее, т.к. валидация логически отделена от самого метода.
if (path == null) { return; }

// Тут весь оставшийся метод.

Убирается лишний уровень отступа и функция выглядит проще.

4) Манипуляции с length не очень красивы. Лучше делать какую-то нормализацию входных данных. Типа убрать trailing-слеши у всего и дальше о них не думать. Опять же нормализация данных не относиться непосредственно к логике метода и должна быть как-то отделена от него, см. пример с валидациями.

5) В исходном методе 12 значимых строк. Делать ради этого класс мне кажется сильно круто, т.к. в итоге будет больше строк и сложность скорее увеличится, чем уменьшится. В С#, по-моему, если возможность добавления методов в уже существующие классы. Если эта функция повсеместно используется в коде, то ее вполне можно утащить в какой-нибудь класс типа Directory. Но это уже кто как любит.

Вообще, красивый метод из и из 200 строк напрягать не будет, а ужасный метод и из 20 строк будет казаться супер сложным и непонятным. Поэтому основной совет всегда один: пишите красиво, а не как курица лапой.
Вообще, красивый метод из и из 200 строк напрягать не будет, а ужасный метод и из 20 строк будет казаться супер сложным и непонятным.


Не согласен. В книгах по алгоритмам, как правило, все методы не более чем на 20 строк, очень сжатые, использующие не всегда очевидные конструкции. Но за счет размера их гораздо проще понять, хотя придется читать каждую строчку, а не наискосок.
Видел я один раз алгоритм, который вычислял число «Пи».
Алгоритм был в 6 строк кода, использовал около 8 переменных, одна из которых — массив.
Понять, что он делает, было совершенно нереально, пока не запустил и не увидел результат.
Но это простой случай.
А теперь представим, что вместо операций над переменными используются операции над интерфейсами внешних систем (той же OpenGL, например).

Разберетесь ли Вы в том, что делают эти 6 строк кода?

Правильнее даже задать вопрос по другому.

Разберетесь ли Вы, что делает эта функция? Каков ее смысл?
IMHO, в большинстве случаев Вам придется изучить несколько мест использования этой функции, чтобы это понять.
«DirectoryFileSplitter». Напомните, чей это совет не давать классам имена, оканчивающиеся на «er»?

По-хорошему, если уж выделять класс, то это должен быть класс Path со свойствами Directory и File, в конструкторе которого и делалась бы вся работа.
Не слышал о таком совете. А есть такой?)
Вот хорошая вводная статья со ссылочками на более фундаментальные.

Дело, конечно же, не в буковках имени. Смысл рекомендации в том, что следует избавляться от классов-сервисов и рассматривать все классы как сущности.
По-моему, один из них был Мартин Фаулер.
Sign up to leave a comment.

Articles