2009-12-17 1 views
3

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

void Level::RunLogic(...); 

В этой функции я считаю себя, разделив ее на несколько частных функций членов , Нет смысла разбивать функцию публичного участника на несколько функций, потому что вы не будете делать одно без другого, и я не хочу, чтобы пользователь беспокоился о том, что в каком порядке и т. Д. Скорее, функция RunLogic() что-то вроде этого ...

void Level::RunLogic(...) { 
DoFirstThing(); 
DoSecondThing(); 
DoThirdThing(); 
} 

С функциями DoThing, являющимися частными функциями-членами. В Code Complete Стив МакКоннелл рекомендует сократить количество функций, которые у вас есть в классе, но я бы предпочел не просто перевести весь этот код в одну функцию. Мое предположение о его истинном значении заключается в том, что класс не должен обладать слишком большой функциональностью, но мне просто интересно, что думают другие программисты относительно этого.

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

ответ

0

Одно правило, которое я использую, является правилом трех. Если я делаю то же самое три раза в разных местах, стоит иметь отдельную (возможно, частную) функцию-член, которая инкапсулирует это совместное поведение.

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

Что касается кода Полный комментарий о количестве функций в классе, помните, что наибольший риск, связанный с количеством функций, в первую очередь связан со сложностью внешнего интерфейса. Чем больше точек входа вы предоставляете другим людям для работы, тем больше вероятность того, что что-то пойдет не так (например, из-за ошибки в одном из публичных членов, неправильном вводе и т. Д.). Добавление частной функции-члена не увеличивает сложность публичного API.

1

Я рекомендую разбить их на отдельные методы, где каждый метод выполняет одну небольшую задачу и имеет описательный для каждого частного метода. Прерывание методов вверх и имена методов сделают логический код более читабельным! Сравните:

double average(double[] numbers) { 
    double sum = 0; 
    for (double n : numbers) { 
    sum += n; 
    } 
    return sum/numbers.length; 
} 

к:

double sum(double[] numbers) { 
    double sum = 0; 
    for (double n : numbers) sum += n; 
    return sum; 
} 

double average(double[] numbers) { 
    return sum(numbers)/numbers.length; 
} 

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

Возможно, имеет смысл сделать эти более мелкие методы защищенными пакетами, поэтому вы можете легко их протестировать, вместо этого сможете протестировать сложный RunLogic.

+0

На самом деле, я нахожу ваш первый пример более читаемым. Меньше усилий при чтении цикла for. Четыре оператора в строке, которыми я могу управлять. –

0

Вы неумышленно следующие правила ФФ:

A class should have only one reason to change/Single responsibility principle 

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

2

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

McConnell прав, что вы должны уменьшить количество методов, которые вы храните в классе.

Эти два гола не очень расходятся. Я не думаю, что Макконнелл будет защищать ваши функции дольше, чтобы уменьшить их количество. Скорее, вам следует рассмотреть возможность нажатия некоторых из этих частных методов на один или несколько классов полезности, которые могут использоваться публичным классом.

Лучший способ выполнить это, конечно, будет зависеть от деталей вашего кода.

1

Я согласен с разделением функциональности.

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

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

0

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

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

0

«Правило большого пальца», которое я использую, заключается в том, что ни одна функция не будет занимать больше места на экране за раз. Хотя он довольно прост, он помогает, когда вы можете «взять все это» на одном экране за раз. Это также ограничит (по определению) сложность любого одного метода. Когда вы ожидаете передать свою работу сотруднику для дальнейшего обслуживания, обновления и исправления ошибок (!), Сохраняя это просто, хорошо. Имея это в виду, я согласен с тем, что сохранение простых методов публики почти всегда является правильным выбором.