Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Рефакторинг длинного метода с локальной переменной 
:(
    Опции темы
Woo
  Дата 9.3.2018, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 14.4.2007

Репутация: нет
Всего: нет



Есть очень длинный метод вида:
Код

void A::foo() {
  int bits = 0;

  if(<условие1>) {
    bits |= 0x1;
    <действия1>
    bits |= 0x2;
  }
  else {
    bits |= 0x4;
    <действия2>
    bits |= 0x8;  
    <действия3>
    bits |= 0x10;
  }

  if(<условие2>) {
    bits |= 0x20;
    <действия4>
    bits |= 0x40;
  }

  <...>

  print(bits);
}

В нем переменная bits используется для диагностики.
Я бы хотел отрефакторить этот код и разбить длинный метод на несколько, например такого вида:
Код

void A::foo() {
  first();
  second();
  <...>
};

void A::first() {
  if(<условие1>) {
    <действия1>
  }
  else {
    <действия2>
    <действия3>
  }
}

void A::second() {
  if(<условие2>) {
    <действия4>
  }
}

Но вот вопрос: как поступить с переменной bits?
Ведь в методы one и second её передавать плохо, так как они должны точно знать какие биты проставлять, но это странно, так как методы могут вызываться из разных мест.
Можно было бы передавать некий адаптер bits с параметром смещения битов, начиная с которого следует проставлять биты в методах, но это как-то слишком сложно.
Каким тут может быть наилучшее решение?

Это сообщение отредактировал(а) Woo - 9.3.2018, 14:43
PM MAIL   Вверх
Namira
Дата 9.3.2018, 20:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 27.2.2011

Репутация: нет
Всего: нет



Цитата(Woo @  9.3.2018,  14:41 Найти цитируемый пост)
Каким тут может быть наилучшее решение?

А закрытым членом класса ее сделать не вариант? smile 
PM   Вверх
Woo
Дата 9.3.2018, 23:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 14.4.2007

Репутация: нет
Всего: нет



Цитата(Namira @ 9.3.2018,  20:19)
Цитата(Woo @  9.3.2018,  14:41 Найти цитируемый пост)
Каким тут может быть наилучшее решение?

А закрытым членом класса ее сделать не вариант? smile

Дело в том, что эта переменная относится только к методу, а не ко всему классу, поэтому так делать некорректно.
Мне сейчас кажется лучший вариант - это использовать прием рефакторинга, который называется Замена метода объектом методов.
И уже в этом новом объекте разместить закрытый член класса. Что-то вроде такого:
Код

class A {
  friend B;

public:
  void foo() {
    B().bar();
  }
};

class B {
  int m_bits;

public:
  void bar() {
    m_bits = 0;
    first();
    second();
  }

  void first() {
    if(<условие1>) {
      m_bits |= 0x1;
      <действия1>
      m_bits |= 0x2;
    }
    else {
      m_bits |= 0x4;
      <действия2>
      m_bits |= 0x8;  
      <действия3>
      m_bits |= 0x10;
    }
  }

  void second() {
    if(<условие2>) {
      m_bits |= 0x20;
      <действия4>
      m_bits |= 0x40;
    }
  }

  void print() {
    // print m_bits;
  }
};

Как думаете, есть вариант получше?
PM MAIL   Вверх
Namira
Дата 11.3.2018, 01:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 27.2.2011

Репутация: нет
Всего: нет



Цитата(Woo @  9.3.2018,  23:08 Найти цитируемый пост)
Дело в том, что эта переменная относится только к методу, а не ко всему классу, поэтому так делать некорректно.

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

Цитата(Woo @  9.3.2018,  23:08 Найти цитируемый пост)
Мне сейчас кажется лучший вариант - это использовать прием рефакторинга, который называется Замена метода объектом методов.

Серьезно? А выше я что тебе написал? Не то же самое что написано по твоей ссылке?  smile  Заводить целый класс, ради одной переменной, которая нужна для диагностики - глупо. А вот сделать ее членом своего класса - не глупо. Но, если методы, которые получатся в результате разделения твоего длинного, будут нелогичными в рамках текущего класса, тогда их можно вместе с переменой вынести в другой класс. А городить огород из классов, только ради одной переменной - глупо.



Это сообщение отредактировал(а) Namira - 11.3.2018, 02:03
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0657 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.