Код мозга "тизер" - но не совсем


Мне просто интересно, что вы, ребята, думаете об этом. Я слышал, что по офису прошла куча ответов, и я хочу посмотреть, может быть, у вас, ребята, найдется лучший.

Вопрос:

У вас есть две функции, описанные ниже:

function one()
{
    A();
    B();
    C();
}

function two()
{
    A();
    D();
    C();
}

Как бы вы переписали это (все имеет значение, вы можете создавать классы, переменные, другие методы, что угодно), чтобы уменьшить дублирование кода?

Каждый из названных методов изменяет переменные, которые должны использовать другие функции. Методы A () B() и C () уже определены.

9 3

9 ответов:

Не все языки будут поддерживать этот подход, и синтаксис передачи функции может варьироваться между теми, которые это делают, но концепция будет такой:

function one()
{
    refactored(B);
}

function two()
{
    refactored(D);
}

function refactored(middleMan)
{
    A();
    middleMan();
    C();
}

Здесь нет дублирования кода. Выглядит нормально.

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

Я бы начал с рефакторинга всего класса, чтобы использовать правильный ООП.

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

Если ваши функции one () и two () действительно являются трехстрочными, как в примере, я бы ничего не переписывал. Вы потеряете читабельность и сделаете код намного более трудным для понимания для следующего парня.

Если вызовы A () и C () на самом деле являются большими блоками кода... - определить базовый класс с помощью абстрактного метода X () и конкретного функция любого() { Один(); Икс(); С(); }

  • Определите класс, в котором X () реализуется через B ()
  • Определите класс два, где X () является реализовано с помощью D ()

Вот один из вариантов.

function (triggerA, triggerB, triggerC, triggerD)
{
     A(triggerA);
     B(triggerB);
     C(triggerC);
     D(triggerD);
}

Таким образом, вы вызываете только одну функцию, чтобы сделать все это, и пропускаете все, что вам не нужно/не нужно делать.

Если у вас есть замыкания, лямбды и т. д. доступно, вы можете написать

function one()
{
    three(B)
}

function two()
{
    three(D);
}

function three(middle) 
{
    A();
    middle();
    C();
}

Вы могли бы (но, вероятно, не должны) создать класс, где A() является конструктором, а C() - деструктором, и иметь one() и two() методы класса, вызывающего B() и D() соответственно.

Я сказал, что вы, вероятно, не должны, потому что ООП должен использоваться для написания кода, который имеет смысл, а не по неясным причинам оптимизации.

В C++ это обычно выполняется с помощью RAII, если контекст имеет смысл... этот шаблон обычно() = некоторые функции init, С() = некоторые де-инициализации функции. Обычно также существует связанный контекст, который также инициализируется или уничтожается.

   class bar
    {
        bar() {
            A();
        }

        ~bar() {
            C();
        }
    };

    void one() 
    {
        bar barvar;
        B();
    }

    void two()
    {
        bar barvar;
        D();
    }