Существует много времен, где я не уверен, должен ли конкретный метод быть сделан частным или нет. Например, я создаю класс прямо сейчас, который, ответственно за генерацию отчета. Этот класс имеет buildReport метод и несколько методов, которые собирают необходимые данные для buildReport.
// single public method
// uses a set of helper methods
public buildReport()
// helper methods
private avgSurveyTime()
private fetchVendors()
private fetchSendCounts()
private ...
Я дебатирую, должен ли я обнародовать эти вспомогательные методы. Единственный метод, который я действительно планирую на вызове снаружи в данный момент, buildReport()
. Однако могло бы быть полезно получить просто список поставщиков с fetchVendors()
и т.д.
Я вижу две философских школы на этом: можно всегда выставлять как можно меньше. (В этом случае многие мои классы только имели бы один открытый метод), ИЛИ можно выставить все, что Вы можете, это могло бы быть полезно для пользователя класса.
Существует ли хорошее эмпирическое правило для использования для решения, когда методы должны быть сделаны общедоступными/частными?
Единственное правило, которому я следую, - как можно меньше публиковать.
Посмотрите на это с другой стороны. Позже вы всегда можете сделать что-то публичным - это не повредит существующий код. Попытка сделать что-то частное, что было общедоступным, вполне может привести к поломке большого количества существующего кода.
Если кому-то нужно больше функциональности от вашего класса, он может сделать запрос, и вы сможете предоставить то, что им нужно. Скорее всего, они захотят что-то, немного отличающееся от того, что у вас уже есть, поэтому вам понадобится новый интерфейс.
Если он не нужен вне класса, в котором он находится в данный момент, сделайте его частным. Если позже, вы можете сделать его защищенным или общедоступным по мере необходимости.
Если сомневаетесь - оставьте наедине.
Если класс предназначен для внутреннего использования в вашей организации, т.е. вы не распространяете его как библиотеку общего пользования, то я от души согласен, что вам следует сделать как можно больше приватных или защищенных функций. Если позже вы обнаружите, что какому-то другому классу нужен доступ к приватной функции, прекрасно, тогда измените ее на публичную. Это несложно сделать.
Единственное предостережение - если это что-то, что вы "публикуете", где другие, у которых нет прямой линии для получения изменений, будут использовать это. Тогда вам нужно тщательно продумать полный API.
Но если это не удается, просто напишите код, который вам нужен. Не пишите функции, которые вы думаете, что когда-нибудь сможете использовать.
простые правила:
Если вы не хотите раскрывать его вне класса, который использует его сделайте его ЧАСТНЫМ .
Если вы хотите предоставить доступ к нему внутри той же сборки другим классам , но не за пределами сборки , сделайте его ВНУТРЕННИЙ (C #) / Друг (VB.NET).
Если вы хотите предоставить функциональность вне сборки для всех, сделайте ее ПУБЛИЧНОЙ
Все, что не включено в интерфейс класса, должно (действительно, должно) быть приватным. Если вы не уверены, что такое интерфейс класса (т. Е. Вы не http://www.artima.com/lejava/articles/designprinciples.html> программирование интерфейсов или эти интерфейсы еще не полностью определены, начните с всем частным и делайте вещи общедоступными, защищенными, закрытыми для пакетов и т. д.
Но подумайте внимательно! Как только что-то становится доступным для другого кода, существует зависимость между этим кодом и этим классом и рефакторинг ограничен. Практическое правило: раскрывайте только те методы, которые определяют абстракцию, а не то, как она реализована.
Я работаю над системой, состоящей в основном из двух функций: импорта данных из различных источников и создания отчетов. Проблема в том, что все это было разработано кем-то, кому не хватало базовых навыков объектно-ориентированного проектирования. В том же «классе» у них были бы «частные» методы для чтения данных из базы данных, вызывающие «частные» методы для проверки указанных данных, которые также вызываются другой «частной» функцией из 500 строк, более или менее дублированной в все приложение, которое просто форматирует указанные данные.
Вы должны удалить частный avgSurveyTime () частный fetchVendors () частный fetchSendCounts () из фактического класса, который обрабатывает макет страницы.
Публичные и приватные методы - очень разные чудовища. Будьте осторожны, прежде чем делать метод общедоступным.
Частные методы не имеют ни одного из этих ограничений.
Как правило, вы должны раскрывать как можно меньше и делать все, что возможно, конфиденциальным.
Если вы допустили ошибку и скрыли то, что должны были разоблачить, нет проблем, просто сделайте это достоянием общественности. Однако, если вы сделаете что-то общедоступным, а затем решите, что это должно быть закрытым, у вас могут возникнуть проблемы, потому что теперь открытый метод может использоваться многими другими классами.
Вы можете изменять реализацию своих частных методов без каких-либо внешних эффектов. Если у вас есть все общедоступные классы, это может быть невозможно, потому что эти методы могут использоваться кем-то вне ваших классов.
Вы должны открывать внешнему миру только то, что ему действительно нужно. Часто лучше добавлять функциональные возможности для потребителей класса тогда, когда это необходимо , а не сначала. В наши дни мудрость состоит в том, чтобы избегать предварительной разработки . ( см. YAGNI )
Конечно, может быть приемлемо иметь общедоступные методы, которые также используются другими функциями внутри класса. Однако это следует считать незначительным неприятным запахом . Это может указывать на то, что ваш класс пытается сделать слишком много вещей.
Я предполагаю оставить ваши занятия такими, какие они есть. Затем, когда эти другие, более мелкие методы потребуются внешнему миру, подумайте, следует ли вам разделять классы. Если цель каждого из этих классов - дать один отчет, то вам не следует выставлять эти методы из этого объекта. Вместо этого поместите «меньшие» методы в общий вспомогательный класс. Таким образом, они становятся доступными для внешнего мира без существенного изменения характера существующих классов отчетов. Вкратце:
Не делайте это только потому, что думаете, что это может быть полезно позже . Если / когда необходимы дополнительные функции, пересмотрите свой общий дизайн, чтобы он соответствовал новым требованиям.
Я всегда следую этому: « Дизайн для завтрашнего дня, код для сегодняшнего дня. »
Если сегодня вам нужен только один общедоступный метод, оставьте только один общедоступный метод.
Полезным методом руководства является написание интерфейса для вашего класса до того, как вы начнете реализацию. Затем при реализации скажите себе, что метод, не входящий в интерфейс, должен быть частным или вообще не принадлежать этому классу.
Если вы не знали, что метод должен присутствовать при разработке контракта класса, он, вероятно, не должен быть частью его открытого интерфейса.
Правило состоит в том, что метод должен быть предоставлен, если он не нужен. Одна из основных причин этого заключается в том, что в будущих выпусках API и т. Д. Вы всегда можете сделать частную функцию общедоступной, но вы почти никогда не сможете сделать предыдущую публичную функцию частной без нарушения существующего кода.