Что такое помощник? Это шаблон дизайна? Это алгоритм?

40

Может быть, немного насмешливо, но так как я не могу найти этот ответ нигде в Google, чтобы убедиться, что у Software Engineering есть ответ:

Что такое помощник?

Я видел, как имя используется везде (имена модулей, имена классов, имена методов), как будто семантика была глубокой и содержательной, но в контексте компьютерных наук (хотя у меня нет степени в этом), я ' никогда не видел ни описания, ни определения!

Это шаблон дизайна? Это алгоритм? Однажды я работал над программой, в которой модуль и класс назывались somethingsomethinghelper (где somethingsomething тоже было довольно общим), и я быстро переименовал его в нечто, что имело смысл для меня, но я чувствую, что здесь что-то упущено!

Аарон Холл
источник
9
Помощник - это то, что вы называете чем-то, когда вы не знаете, как это назвать, но знаете одного из его друзей. Вроде как называть тебя «другом Зака» вместо Аарона. Двойной плюс нехорошо.
david.pfx
Помощник - это любой частный член, вплоть до изоморфизма.
Томас Эдинг
@ThomasEding Извините, что вернулся через 3 года - но я видел много «публичных» членов, называемых «помощниками», включая интерфейсы. Я хотел бы получить источник вашего определения (чем выше качество, тем лучше), потому что это определенно дало бы мне смысл для большего количества запахов кода.
Аарон Холл,

Ответы:

63

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

А если серьезно, то основная проблема с классами Helper заключается в том, что они, как правило, представляют собой операции, которые действуют на определенный класс, что, очевидно, означает, что в терминах ОО они страдают от острого случая зависти к функциям . Эта неспособность связать поведение с данными, на которые он воздействует, является причиной того, что разработчики так часто (по моему опыту) не могут его найти.

В дополнение к этому, как вы уже определили, SomethingSomethingHelper на самом деле ужасное имя. Это не описательно и не дает вам реального представления о том, какие операции выполняет класс (это помогает?), Что также означает, что при добавлении новых поведений не очевидно, принадлежат ли они классу Helper или нет. Я бы разбил такие классы по направлениям связанного поведения, которые логически группируются, а затем переименовал новые классы, чтобы отразить, что они делают.

Мистер Кочезе
источник
9
Уверен, что SomethingSomethingHelperэто не настоящее название класса. Является ли это запахом кода или нет, зависит от того, насколько специфичен вспомогательный класс, так как вспомогательные классы Mathвообще не являются запахом кода.
Роберт Харви
10
@RobertHarvey - Да, большинство из тех, кого я видел , были названы SomethingSomethingHelper. Черт, я сейчас смотрю на класс, названный HelperMethodsв <company>.Helpersпространстве имен. Для меня Helperкласс находится в том же ведре, что и *Manager.
Теластин
8
@Telastyn: Возможно, это вещь опыта, тогда. Я просмотрел вспомогательные классы в моем текущем проекте (их несколько), и все они имеют значимые имена. Есть только один с суффиксом Helper, и я думаю, что это для устранения неоднозначности из класса в .NET Framework с таким же именем. Я бы посчитал *Helperприемлемым, если бы *что-то значимое. HelperMethodsэто просто провал воображения; должны быть по крайней мере конкретные концептуальные группы.
Роберт Харви
4
@RobertHarvey - Вы, вероятно, правы. Вся моя карьера с использованием современных языков сводилась к уборке крушения поезда.
Теластин
1
Существует подмножество их, называемых «вспомогательными функциями», которые на самом деле полезны и являются хорошим шаблоном. Например, общий набор строк, которые в противном случае должны были бы повторяться внутри функции - один из примеров того, где они отображаются, - когда вам нужен do..whileцикл в Python, который язык не поддерживает (см. Второй пример здесь ). Другой будет структура if / elif /.../ else, но необходимо повторить регистр сверху и снизу. Однако, если это возможно, их следует сделать локальными для этой функции и вообще не называть их «помощниками».
Изката
5

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

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

digits = digits.Remove(0, TextHelper.FindRep('0', digits, 0, digits.Length - 2));

Вспомогательный метод очень прост, но очень неудобен для копирования и вставки, и фреймворк не предоставляет никакого решения.

public static int FindRep(char chr, string str, int beginPos, int endPos)
{
    int pos;

    for (pos = beginPos; pos <= endPos; pos++)
    {
        if (str[pos] != chr)
        {
            break;
        }
    }

    return pos - beginPos;
}

И вот пример плохого помощника:

public static class DutchZipcodeHelper
{
    public static bool Validate(string s)
    {
        return Regex.IsMatch(s, @"^[1-9][0-9]{3}[A-Z]{2}$", RegexOptions.IgnoreCase);
    }
}

public class DutchZipcode
{
    private string value;

    public DutchZipcode(string value)
    {
        if (!DutchZipcodeHelper.Validate(value))
        {
            throw new ArgumentException();
        }

        this.value = value;
    }

    public string Value
    {
        get { return value; }
    }
}
Леопольд Аспергер
источник
-1

Моя компания использовала методологию базового класса / вспомогательного класса, где у каждого объекта было бы два класса. У вас будет класс Person, который содержит все свойства и определения класса, и класс PersonHelper, который содержит все методы, операторы SQL и Logic, которые манипулируют классом Person. Это хорошо сработало для нас, потому что все наши приложения используют операторы SQL для манипулирования данными, и нам было очень легко находить и изменять операторы SQL по мере необходимости.

С тех пор мы пошли дальше и теперь поместили все в класс Person / Base. Мы прекратили использовать соглашение об именах Helper, потому что хотели, чтобы в наших проектах было меньше файлов. Кроме того, длина некоторых имен классов вышла из-под контроля. смешно.

Не хороший пример, но вы поняли идею.

s = CompanyName.PersonHelper.GetPerson()
s = CompanyName.Person.GetPerson()

Я не говорю, что использование соглашения о присвоении имен является идеальным решением, но оно работало для нас в течение нескольких лет.

Брайан
источник
2
Вы не объяснили почему.
Роберт Харви
2
Да, я тоже хотел бы это объяснение.
Аарон Холл
@AaronHall Считайте, что это хорошо, что вы не понимаете их выбор.
Леопольд Аспергер