Примеры рефакторинга
От: landerhigh Пират http://www.blinnov.com
Дата: 04.12.14 09:59
Оценка: 1 (1)
Думаю, этот форум наиболее подходящее место для такой темы. Впрочем, я не против, если ее перенесут в более подходящее место.

Приглашаются все желающиее, но, пожалуйста, на первых уровнях только примеры!
www.blinnov.com
Re: Ненужная зависимость от типа параметра
От: landerhigh Пират http://www.blinnov.com
Дата: 04.12.14 10:04
Оценка: +4 :)
Вот один из наиболее часто встречающихся кандидатов на рефакторинг:


ret_type MyCoolFunc(int i1, AnotherClassType* _pPtr)
{
     //
     const char* pName = _pPtr->GetName();
     // _pPtr is not used anywhere else in the function
}


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

рефакторим:

ret_type MyCoolFunc(int i1, const char* _pName)
{
     //
     const char* pName = _pName;

}


Как результат — нужно изменить все вызовы этой функции. Но это — нефункциональное изменение, риск очень низкий.
www.blinnov.com
Re: Примеры рефакторинга
От: btn1  
Дата: 04.12.14 11:12
Оценка: -14
Здравствуйте, landerhigh, Вы писали:

L>Думаю, этот форум наиболее подходящее место для такой темы. Впрочем, я не против, если ее перенесут в более подходящее место.


L>Приглашаются все желающиее, но, пожалуйста, на первых уровнях только примеры!


Ты чего хочешь, родной? Бесплатные ослы, пишущие для тебя примеры — они на другой планете!
Re[2]: Примеры рефакторинга
От: Tolanay Россия  
Дата: 04.12.14 11:23
Оценка: +2
Здравствуйте, btn1, Вы писали:

L>>Приглашаются все желающиее, но, пожалуйста, на первых уровнях только примеры!


B>Ты чего хочешь, родной? Бесплатные ослы, пишущие для тебя примеры — они на другой планете!


Ты похоже тоже на какой-то своей планете.
Re[2]: Ненужная зависимость от типа параметра
От: rFLY  
Дата: 04.12.14 11:27
Оценка: +7 :)
Здравствуйте, landerhigh, Вы писали:

L>Вот один из наиболее часто встречающихся кандидатов на рефакторинг:


L>
L>ret_type MyCoolFunc(int i1, AnotherClassType* _pPtr)
L>{
L>     //
L>     const char* pName = _pPtr->GetName();
L>     // _pPtr is not used anywhere else in the function
L>}
L>


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

А я думал, что передается указатель.
L>Как результат — все, кто используют эту функцию, обязаны знать об AnotherClassType.
L>Совершенно ненужная связность.
С этим можно поспорить. Передав указатель на объект, ты гарантируешь, что данные будут взяты из него и будут соответствовать ожидаемым, а не передастся плод больной фантазии разработчика, то есть какая-то абракадабра, которая к этому объекту никакого отношения иметь не будет. Ну вот я не знаю об этом объекте ничего, как ты говоришь не "обязаны знать об AnotherClassType", тогда откуда мне знать, что вернет его метод GetName() и что я должен передать вторым параметром при вызове MyCoolFunc?
Re[2]: Примеры рефакторинга
От: rFLY  
Дата: 04.12.14 11:30
Оценка:
Здравствуйте, btn1, Вы писали:

B>Ты чего хочешь, родной? Бесплатные ослы, пишущие для тебя примеры — они на другой планете!

Так примеры же абстрактные. Мне бы вот тоже было бы интересно в каких случаях коллеги применяют рефакторинг
Re: Примеры рефакторинга
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 04.12.14 11:36
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Думаю, этот форум наиболее подходящее место для такой темы. Впрочем, я не против, если ее перенесут в более подходящее место.


L>Приглашаются все желающиее, но, пожалуйста, на первых уровнях только примеры!

Открываешь Фаулера и читаешь. Мне приходилось использовать почти 90% того о чём он пишет.
Sic luceat lux!
Re[2]: Ненужная зависимость от типа параметра
От: Tolanay Россия  
Дата: 04.12.14 11:41
Оценка: +2
Здравствуйте, landerhigh, Вы писали:

L>Вот один из наиболее часто встречающихся кандидатов на рефакторинг:


Вообще хотелось бы конкретный, а не абстрактный пример. Как уже писали выше, заменяя класс на строку мы теряем гарантию того, что будет передано корректное значение.
И если в дальнейшем функции понадобятся еще какие-то параметры объекта, то тебе уже придется делать обратный рефакторинг — менять список параметров на объект.
Отредактировано 04.12.2014 11:45 Tolanay . Предыдущая версия . Еще …
Отредактировано 04.12.2014 11:43 Tolanay . Предыдущая версия .
Отредактировано 04.12.2014 11:43 Tolanay . Предыдущая версия .
Отредактировано 04.12.2014 11:42 Tolanay . Предыдущая версия .
Re[3]: Ненужная зависимость от типа параметра
От: landerhigh Пират http://www.blinnov.com
Дата: 04.12.14 12:04
Оценка: +6
Здравствуйте, rFLY, Вы писали:

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

FLY>А я думал, что передается указатель.

В данном контексте неважно.

L>>Как результат — все, кто используют эту функцию, обязаны знать об AnotherClassType.

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

Это очень вредное заблуждение, следование которому приводит к макаронам в коде. Какие плюсы ты получаешь, ограничивая параметр неким специальным типом, когда все, что тебе нужно — это общий тип? У вас много разработчиков с больной фантазией, которые передают черт-те-что в функции? Тогда у вас проблема, да
Что им тогда помешает сделать так, что объект, указатель на который ты передашь, вернет какую-то абракадабру?
Что, в конце концов, будешь делать, если автор AnotherClassType решит его изменить и разрежет на два или десять разных классов? Решит, что метод GetName — устарел или изменит его сигнатуру?

Это ненужная, умозрительная и вредная "гарантия".

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

FLY>Ну вот я не знаю об этом объекте ничего, как ты говоришь не "обязаны знать об AnotherClassType", тогда откуда мне знать, что вернет его метод GetName() и что я должен передать вторым параметром при вызове MyCoolFunc?


Очевидно же, некую строку. Что эта строка должна содержать, будет описано в комментарии к методу. В любом случае, передача левой строки не должна приводить к непредвиденным (недокументированным) последствиям.

Только в моем случае это твое дело, откуда ты ее возьмешь. Оригинальный же код требует инстанции AnotherClassType. Особенно готично, когда ты вынужден держать в памяти или создавать этот объект каждый раз только для вызова той функции.
www.blinnov.com
Re[3]: Ненужная зависимость от типа параметра
От: landerhigh Пират http://www.blinnov.com
Дата: 04.12.14 12:09
Оценка: -1
Здравствуйте, Tolanay, Вы писали:

L>>Вот один из наиболее часто встречающихся кандидатов на рефакторинг:


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


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

T>И если в дальнейшем функции понадобятся еще какие-то параметры объекта, то тебе уже придется делать обратный рефакторинг — менять список параметров на объект.


А если не понадобится? А наоборот, понадобится вызывать эту функцию уже после смерти объекта?

Это, на самом деле, довольно распространенный случай.
www.blinnov.com
Re: Примеры рефакторинга
От: Ночной Смотрящий Россия  
Дата: 04.12.14 12:21
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Приглашаются все желающиее, но, пожалуйста, на первых уровнях только примеры!


Есть же wiki
Re[2]: Примеры рефакторинга
От: landerhigh Пират http://www.blinnov.com
Дата: 04.12.14 12:23
Оценка: :)
Здравствуйте, Ночной Смотрящий, Вы писали:

L>>Приглашаются все желающиее, но, пожалуйста, на первых уровнях только примеры!


НС>Есть же wiki


В вики неудобно кидаться ка обмениваться мнениями.
www.blinnov.com
Re[4]: Ненужная зависимость от типа параметра
От: rFLY  
Дата: 04.12.14 12:27
Оценка: +1
Здравствуйте, landerhigh, Вы писали:

FLY>>А я думал, что передается указатель.

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

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

L>Это очень вредное заблуждение, следование которому приводит к макаронам в коде. Какие плюсы ты получаешь, ограничивая параметр неким специальным типом, когда все, что тебе нужно — это общий тип? У вас много разработчиков с больной фантазией, которые передают черт-те-что в функции? Тогда у вас проблема, да
L>Что им тогда помешает сделать так, что объект, указатель на который ты передашь, вернет какую-то абракадабру?
Зачем им это делать? В вашем же примере я не знаю, что передавать в функцию, поскольку по вашим же словам я не должен знать ничего об этом классе, а значит и не должен знать, что вернет функция GetName() для каждого переданного объекта. Для объекта А она может вернуть "Иванов И.И.", а для объекта Б "guest". С каким значением вы мне предлагаете вызывать функцию?

L>Она дополнительно возлагает на вызывающий код обязанность не только знать об AnotherClassType, но и быть в курсе его времени жизни. А это — серьезное усложнение кода, повышение связности и затруднение тестирования.

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

L>Очевидно же, некую строку. Что эта строка должна содержать, будет описано в комментарии к методу. В любом случае, передача левой строки не должна приводить к непредвиденным (недокументированным) последствиям.

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


L> Только в моем случае это твое дело, откуда ты ее возьмешь

5+ С потолка видимо
Re[3]: Примеры рефакторинга
От: Ночной Смотрящий Россия  
Дата: 04.12.14 12:35
Оценка:
Здравствуйте, landerhigh, Вы писали:

НС>>Есть же wiki


L>В вики неудобно кидаться ка обмениваться мнениями.


Так обменивайся в комментариях, а примеры держи на вики страничке.
Re[5]: Ненужная зависимость от типа параметра
От: landerhigh Пират http://www.blinnov.com
Дата: 04.12.14 12:41
Оценка: 1 (1) +2
Здравствуйте, rFLY, Вы писали:

L>>В данном контексте неважно.

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

В данном контексте нет разницы, передается он или нет. Важно наличие зависимости.

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

L>>Это очень вредное заблуждение, следование которому приводит к макаронам в коде. Какие плюсы ты получаешь, ограничивая параметр неким специальным типом, когда все, что тебе нужно — это общий тип? У вас много разработчиков с больной фантазией, которые передают черт-те-что в функции? Тогда у вас проблема, да
L>>Что им тогда помешает сделать так, что объект, указатель на который ты передашь, вернет какую-то абракадабру?
FLY>Зачем им это делать?

Это надо у тебя спросить. Идея передавать абракадабру — твоя. Если разработчик хочет передать абракадабру, ему ничто не помешает.

FLY>В вашем же примере я не знаю, что передавать в функцию, поскольку по вашим же словам я не должен знать ничего об этом классе, а значит и не должен знать, что вернет функция GetName() для каждого переданного объекта. Для объекта А она может вернуть "Иванов И.И.", а для объекта Б "guest". С каким значением вы мне предлагаете вызывать функцию?


С тем, для какого значения требуется. В чем проблема?

L>>Она дополнительно возлагает на вызывающий код обязанность не только знать об AnotherClassType, но и быть в курсе его времени жизни. А это — серьезное усложнение кода, повышение связности и затруднение тестирования.

FLY>Вы противоречите сами себе. Я не должен знать об объекте ничего, но должен знать, что вернет его метод чтобы это значение передать в свою функцию. Должно быть телепатически

Это ты противоречишь сам себе. Смотри ниже.

L>>Очевидно же, некую строку. Что эта строка должна содержать, будет описано в комментарии к методу. В любом случае, передача левой строки не должна приводить к непредвиденным (недокументированным) последствиям.

FLY>Это пять! А в комментарии напишите "Передать имя пользователя — где хранится и как получить не скажу, потому что вы не должны об этом знать"

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

L>> Только в моем случае это твое дело, откуда ты ее возьмешь

FLY>5+ С потолка видимо

Да хоть с потолка. Главное — что я могу ее взять с потолка, и вовсе не обязан где-то брать тот большой и толстый объект только для этого.
www.blinnov.com
Re[4]: Ненужная зависимость от типа параметра
От: Erop Россия  
Дата: 04.12.14 12:50
Оценка:
Здравствуйте, landerhigh, Вы писали:
L>Что, в конце концов, будешь делать, если автор AnotherClassType решит его изменить и разрежет на два или десять разных классов? Решит, что метод GetName — устарел или изменит его сигнатуру?

Ну, наверное, тоже самое, что в местах вызова нашей функции, но один раз, а не N...

L>...затруднение тестирования.

Рефактоирнг ради рефакторинга не вреде, нет...

L>Очевидно же, некую строку. Что эта строка должна содержать, будет описано в комментарии к методу. В любом случае, передача левой строки не должна приводить к непредвиденным (недокументированным) последствиям.


А передача объекта?

L>Только в моем случае это твое дело, откуда ты ее возьмешь. Оригинальный же код требует инстанции AnotherClassType. Особенно готично, когда ты вынужден держать в памяти или создавать этот объект каждый раз только для вызова той функции.


Ну я вот всё ещё думаю, что упрощать код надо не формально, а понимая, что делаешь
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: Ненужная зависимость от типа параметра
От: landerhigh Пират http://www.blinnov.com
Дата: 04.12.14 12:58
Оценка:
Здравствуйте, Erop, Вы писали:

L>>Что, в конце концов, будешь делать, если автор AnotherClassType решит его изменить и разрежет на два или десять разных классов? Решит, что метод GetName — устарел или изменит его сигнатуру?


E>Ну, наверное, тоже самое, что в местах вызова нашей функции, но один раз, а не N...


А если решит его (класс или метод) вообще выбросить?

L>>...затруднение тестирования.

E>Рефактоирнг ради рефакторинга не вреде, нет...

В оригинальном варианте тестирование затруднено. Особенно, когда, как это часто бывает, объекты класса AnotherClassType создаются только фабрикой, которая требует 100500 зависиостей.

L>>Очевидно же, некую строку. Что эта строка должна содержать, будет описано в комментарии к методу. В любом случае, передача левой строки не должна приводить к непредвиденным (недокументированным) последствиям.


E>А передача объекта?


Что передача объекта?

L>>Только в моем случае это твое дело, откуда ты ее возьмешь. Оригинальный же код требует инстанции AnotherClassType. Особенно готично, когда ты вынужден держать в памяти или создавать этот объект каждый раз только для вызова той функции.


E>Ну я вот всё ещё думаю, что упрощать код надо не формально, а понимая, что делаешь


Это и есть понимание, чего делаешь. Назыавется — минимизация связности.
www.blinnov.com
Re[3]: Ненужная зависимость от типа параметра
От: landerhigh Пират http://www.blinnov.com
Дата: 04.12.14 13:01
Оценка: +1 -1
Здравствуйте, rFLY, Вы писали:

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


Кстати, подобная гарантия, когда она нужна, разрешается на счет "раз". Если такая гарантия нужна, то такая функция просто делается членом класса AnotherClassType.

А ты и поставившие плюсики только что провалили тест по ООП. Не понимаете принцип инкапсуляции. Поздравляю!
www.blinnov.com
Re[4]: Ненужная зависимость от типа параметра
От: rFLY  
Дата: 04.12.14 13:17
Оценка:
Здравствуйте, landerhigh, Вы писали:

L>Кстати, подобная гарантия, когда она нужна, разрешается на счет "раз". Если такая гарантия нужна, то такая функция просто делается членом класса AnotherClassType.

L>А ты и поставившие плюсики только что провалили тест по ООП. Не понимаете принцип инкапсуляции. Поздравляю!
Вы бы определились что ли — вы класс пишите или вы им пользуетесь.
PS: не нужно так на плюсики реагировать, уже декабрь и хочется наконец-то снег увидеть.
Re[5]: Ненужная зависимость от типа параметра
От: landerhigh Пират http://www.blinnov.com
Дата: 04.12.14 13:23
Оценка: -1
Здравствуйте, rFLY, Вы писали:

L>>А ты и поставившие плюсики только что провалили тест по ООП. Не понимаете принцип инкапсуляции. Поздравляю!

FLY>Вы бы определились что ли — вы класс пишите или вы им пользуетесь.

В исходной задаче все было четко обозначено.

FLY>PS: не нужно так на плюсики реагировать, уже декабрь и хочется наконец-то снег увидеть.


Вы тут о снеге мечтаете, а мне потом материться
www.blinnov.com
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.