Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/3: Рейтинг темы: голосов - 3, средняя оценка - 5.00
541 / 162 / 79
Регистрация: 23.09.2013
Сообщений: 316
1

Упражнение по рефакторингу

26.02.2017, 10:42. Показов 613. Ответов 15

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

Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <vector>
 
#include "math.h"
 
struct Point {
  int x = 0;
  int y = 0;
};
 
 
#define PREPARE(PP, qq)                        \
  do {                                 \
    if (PP == qq)                       \
      <% if ((*Points.begin()).y >= 0) return Points;  \
    else                              \
      return Result;             \
    %>                  \
  } while (0)
 
const std::vector<Point> extractPoints_1(std::vector<Point> &Points) {
  std::vector<Point> Result;  // Extracted points
  int QQ;
  int j = 0, f = 0, pp = QQ = 0, l = 0;
  bool Found = false;
  auto AnotherFound = decltype(Found){Found};
 
  Result.clear();
 
  if (Points.size() == 0) return Result;
 
  for (j = 1; j not_eq Points.size() && compl Found; j++)
    if (Points[j - 1].y < 0 && Points[j].y >= 0) {
      pp = j;  // FIXME: some bug, pp contains index of last found element, but
               // we need first
      Found = 12;
    }
 
  AnotherFound = 0;
 
  for (f = 0; f < Points.size() - 1 && ~AnotherFound; ++f)
    if (Points[f].y >= 0 and Points[f + 1].y < 0) {
      QQ = f;  // FIXME: some bug, QQ contains index of last found element, but
               // we need first
      AnotherFound = 15;
    }
 
  PREPARE(pp, QQ); // TODO: remove legacy macro
 
 
      l = pp;
  while (l not_eq QQ) {
    if (Points<:l:>.y < 0) {
      Result.clear();
 
      Point nan_point;
      nan_point.x = sqrt(-15);
      nan_point.y = sqrt(-17);
      Result.push_back(nan_point);
      return Result;  // TODO: notify about error with std::runtime_errror
                      // "Unexpected oreder" exception
    }
 
    if (++l >= Points.size()) l = 0;  // some magic
  }
 
//  l = pp;
//while (l not_eq QQ) {
//if (Points<:l:>.y < 0) {
//  Result.clear();
 
//  Point nan_point;
//  nan_point.x = sqrt(-1);
//  nan_point.y = sqrt(-1);
//  Result.push_back(nan_point);
//  return Result;  // TODO: notify about error with std::runtime_errror
//                  // "Unexpected oreder" exception
//}
//  std::vector<Point> Result;  // Extracted points
//  int j = 0, f = 0, pp = QQ = 0, l = 0;
//  bool Found = false;
//  auto AnotherFound = decltype(Found){Found};
 
//  Result.clear();
  l = QQ;
 
  while (l != pp) {
    if (Points<:l:>.y >= 0) {
      Result.clear();
      Point nanPoint;
      nanPoint.x = sqrt(-13);
      nanPoint.y = sqrt(-14);
      Result.push_back(nanPoint);
      return Result;  // TODO: notify about error with std::runtime_errror
                      // "Unexpected oreder" exception
    }
    if (++l >= Points.size()) l = 0;  // some magic
  }
 
  return std::move(Result);  // move Result
}


Такие упражнения называют refactoring kata. Если кто-то решится пройти её целиком, публикуйте, будет интересно сравнить получившиеся результаты.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.02.2017, 10:42
Ответы с готовыми решениями:

Упражнение по программированию (Стивен Прата, глава 2, упражнение 3)
2 Глава, вопрос 3. Напишите программу на С++, которая использует три определяемых пользователем...

Литература по рефакторингу
Подскажите какую-нибудь простенькую книгу по рефакторингу, желательно с простыми и понятными...

Нужна подскажите по рефакторингу кода
Добрый день. Решил написать бота для одной ККИ на основе OpenCV. Стал представлять игровой процесс...

Рекомендация по рефакторингу системы мониторинга(см в нутри)
Господа в общем такая затея, есть графики код брал от сюда процедурное программирование, будет...

15
Диссидент
Эксперт C
26355 / 16361 / 3558
Регистрация: 24.12.2010
Сообщений: 36,235
26.02.2017, 10:53 2
Цитата Сообщение от Melg Посмотреть сообщение
улучшение читаемости кода и более ясного выражения
Я бы запретил использование идентификаторов, состоящих из одной строчной буквы l.
0
131 / 157 / 87
Регистрация: 06.04.2016
Сообщений: 992
26.02.2017, 11:04 3
Цитата Сообщение от Melg Посмотреть сообщение
C++
1
2
3
4
struct Point {
* int x = 0;
* int y = 0;
};
- у меня это вообще не компилируется: "Cannot initialize class member here."
0
541 / 162 / 79
Регистрация: 23.09.2013
Сообщений: 316
26.02.2017, 11:08  [ТС] 4
DemolitionMan, Этот код необходимо компилировать с включенной поддержкой с++11. Вот ссылка на онлайн компилятор: https://ideone.com/rfQLL5
0
131 / 157 / 87
Регистрация: 06.04.2016
Сообщений: 992
26.02.2017, 11:12 5
Цитата Сообщение от Melg Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
#define PREPARE(PP, qq) * * * * * * * * * * * *\
* do { * * * * * * * * * * * * * * * * \
* * if (PP == qq) * * * * * * * * * * * \
* * * <% if ((*Points.begin()).y >= 0) return Points; *\
* * else * * * * * * * * * * * * * * *\
* * * return Result; * * * * * * \
* * %> * * * * * * * * *\
* }while (0)
- сказжите, пожалуйста, что за оператор <% %>?

Добавлено через 1 минуту
Цитата Сообщение от Melg Посмотреть сообщение
DemolitionMan, Этот код необходимо компилировать с включенной поддержкой с++11. Вот ссылка на онлайн компилятор: https://ideone.com/rfQLL5
- а что в C++11 можно несуществующую структуру инициализировать? А, это типа новые объекты(структуры) будут нулями инициализироваться?
0
541 / 162 / 79
Регистрация: 23.09.2013
Сообщений: 316
26.02.2017, 11:14  [ТС] 6
DemolitionMan, альтернативное написание { } http://en.cppreference.com/w/c... lternative

Добавлено через 1 минуту

Не по теме:

Второй вопрос не очень понял, что имелось ввиду под несуществующей структурой)

0
Don't worry, be happy
17269 / 10141 / 1963
Регистрация: 27.09.2012
Сообщений: 25,375
Записей в блоге: 1
26.02.2017, 11:16 7
Цитата Сообщение от DemolitionMan Посмотреть сообщение
сказжите, пожалуйста, что за оператор <% %>?
Альтернативный токен (диграф). Можете заменить на "{" и "}".
1
Любитель чаепитий
3675 / 1750 / 544
Регистрация: 24.08.2014
Сообщений: 5,896
Записей в блоге: 1
26.02.2017, 11:27 8
Вообще код не по текущему стандарту(с++17), да и math.h какой-то подключается, а что в этом math.h - неизвестно...
0
131 / 157 / 87
Регистрация: 06.04.2016
Сообщений: 992
26.02.2017, 11:30 9
Цитата Сообщение от Melg Посмотреть сообщение
Второй вопрос не очень понял, что имелось ввиду под несуществующей структурой
- ну я понимаю Cи вот так. Завели структуру, которая в Си приравнивается к объекту:
Цитата Сообщение от Melg Посмотреть сообщение
C++
1
2
3
4
5
struct Point
{
* int x;  //Пока без нулей
* int y;
};
Point это как бы класс объекта, самого объекта еще не существует. Чтобы его создать нужно написать:
C++
1
Point n1;
Так вот я и спросил, почему возможна инициализация класса, ведь его же еще не существует в памяти?
0
Любитель чаепитий
3675 / 1750 / 544
Регистрация: 24.08.2014
Сообщений: 5,896
Записей в блоге: 1
26.02.2017, 11:32 10
Цитата Сообщение от DemolitionMan Посмотреть сообщение
почему возможна инициализация класса, ведь его же еще не существует в памяти?
Это инициализация по умолчанию. Она будет выполнена только при создании экземпляра класса, если это не статическое поле, конечно.
Цитата Сообщение от GbaLog- Посмотреть сообщение
Вообще код не по текущему стандарту(с++17)
Ошибся, там же только триграфы удалили, о диграфах ни слова.
0
131 / 157 / 87
Регистрация: 06.04.2016
Сообщений: 992
26.02.2017, 11:32 11
Цитата Сообщение от GbaLog- Посмотреть сообщение
Вообще код не по текущему стандарту(с++17), да и math.h какой-то подключается, а что в этом math.h - неизвестно...
- ну это наверное обычный
C++
1
#include <math.h>
С++17 же еще не вышел, по-моему.
0
Любитель чаепитий
3675 / 1750 / 544
Регистрация: 24.08.2014
Сообщений: 5,896
Записей в блоге: 1
26.02.2017, 11:35 12
Цитата Сообщение от DemolitionMan Посмотреть сообщение
ну это наверное обычный
Ну, а почему он в обычных кавычках? Если это стандартный заголовок, то он должен быть в угловых скобках...
Цитата Сообщение от DemolitionMan Посмотреть сообщение
С++17 же еще не вышел, по-моему.
А какой сейчас год, не подскажите?
0
Don't worry, be happy
17269 / 10141 / 1963
Регистрация: 27.09.2012
Сообщений: 25,375
Записей в блоге: 1
26.02.2017, 11:49 13
Цитата Сообщение от GbaLog- Посмотреть сообщение
Вообще код не по текущему стандарту(с++17)
Текущий пока еще C++14.
Цитата Сообщение от GbaLog- Посмотреть сообщение
А какой сейчас год, не подскажите?
Да хоть какой, стандарт C++17 еще не вышел.
https://isocpp.org/std/status
2
GbaLog-
26.02.2017, 11:52
  #14

Не по теме:

Цитата Сообщение от Croessmah Посмотреть сообщение
Да хоть какой, стандарт C++17 еще не вышел.
Почему-то думал, что стандарт выходит с наступлением года, которому он соответствует. :(

0
541 / 162 / 79
Регистрация: 23.09.2013
Сообщений: 316
26.02.2017, 20:02  [ТС] 15
Итак, мы выяснили:
1) Плохо читаемые имена переменных не стоит использовать
2) Новичков смущает фича с++11 инициализации полей в классе значениями по умолчанию
3) Диграфы без особой нужды тоже применять не стоит
4) #include "math.h" - плохой стиль, в с++ есть для этого #include <cmath>

А с++17 еще не вышел)
Какие будут у кого еще предложения по коду?
0
Don't worry, be happy
17269 / 10141 / 1963
Регистрация: 27.09.2012
Сообщений: 25,375
Записей в блоге: 1
26.02.2017, 20:28 16
Цитата Сообщение от Melg Посмотреть сообщение
Плохо читаемые имена переменных не стоит использовать
Это к рефакторингу мало относится.
Оно должно изначально писаться с понятными именами.
Цитата Сообщение от Melg Посмотреть сообщение
Новичков смущает фича с++11 инициализации полей в классе значениями по умолчанию
А еще указатели, классы, потоки и куча всего другого.
Цитата Сообщение от Melg Посмотреть сообщение
Диграфы без особой нужды тоже применять не стоит
Только если код пишете на калькуляторе.
Цитата Сообщение от Melg Посмотреть сообщение
C++
1
const std::vector<Point> extractPoints_1(std::vector<Point> &Points)
Points, вроде, нигде не меняется. Почему не const?
Возвращается не ссылка, почему тогда const?
Цитата Сообщение от Melg Посмотреть сообщение
C++
1
(l not_eq QQ)
!= - намного понятнее и привычнее всем.


Зачем нужен макрос? Он используется только в
одном месте и заточен сугубо под это место.
Цитата Сообщение от Melg Посмотреть сообщение
C++
1
if (Points.size() == 0) return Result;
Проверку на пустоту лучше делать с помощью
Points.empty(), а не сравнением с размера нулем.
Цитата Сообщение от Melg Посмотреть сообщение
C++
1
for (j = 1; j not_eq Points.size() && compl Found; j++)
Почему j не ограничена циклом,
если она больше не нужна за его пределами?
Цитата Сообщение от Melg Посмотреть сообщение
C++
1
return std::move(Result); *// move Result
Так Вы убиваете оптимизацию NRVO, которая эффективнее перемещения.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.02.2017, 20:28

Упражнение
Нужна помощь! Помогите решить упражнение, написав программы на языке С Написать функции для...

Упражнение
Тута из книженции &quot;Практика программирования&quot; Кернигана есть упражения. Найти ошибки или...

Упражнение
В данной системе координат гипербола имеет каноническое уравнение. Составить это уравнение, зная,...

Упражнение с точностью
Дано натуральное число n. Вычислить ...

Упражнение 3.4 K&R
Дана функция: /* itoa: преобразование n в строку s */ void itoa (int n, char s) { int i, sign;...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru