Delphi - Объявление в классе или нет? - PullRequest
4 голосов
/ 22 января 2010

Совсем недавно, вероятно, потому что я поддерживал какой-то старый код, я начал смотреть на то, как / почему я что-то делаю. Как ты.

Большая часть моего программирования на Delphi была взята на собственном опыте или из примеров, разбросанных по сети или руководствам. И в некоторых вещах сделано только потому, что «вот как я это делаю»

В настоящее время я задаюсь вопросом: Объявление , переменных, процедур, функций и т. Д.

Когда я работаю с формой, я помещаю все свои процедуры и функции в public или private . Хотя я буду стараться избегать глобальных переменных и константы, как правило, будут иметь значение var или const , либо в интерфейсе, либо в реализации, в зависимости от того, куда их нужно вызывать (иногда, хотя они будут перейти в публичный / частный)

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

Есть ли правильный способ сделать это? Есть ли правила того, что должно / не должно идти в классе? Или это стиль / когда ты начал что-то делать?

Изменить, чтобы добавить

У меня вопрос не о том, идет ли объявление процедуры в private / public, а о том, должны ли все объявления в модуле TForm входить в один из них. Точно так же должен быть var / const в одном или другом?

Дополнительные уточнения

Я понимаю, что не декларирование в интерфейсе или декларирование в public / private / etc влияет на видимость процедур / функций для других модулей в моем приложении.
Суть моего вопроса в том, почему я не хочу объявить? - особенно при работе в форме / модуле, когда размещение в частном порядке гораздо более очевидно, что объявленная вещь недоступна для других модулей ...

Приветствие Dan

Ответы [ 2 ]

6 голосов
/ 22 января 2010

Все, что может иметь различное значение в зависимости от конкретного экземпляра, принадлежит классу, т.е.

TDog = class
strict private
  FColor : TColor;
  FName : String;
public
  property Color : TColor read FColor write FColor;
  property Name : String read FName write FName;
end;

Цвет и имя явно являются атрибутами каждой собаки (и каждая собака будет иметь другие значения здесь).

Общие правила:

  • Поля принадлежат private (видимый в этом классе и в этом модуле) или strict private (видимый только в этом классе)
  • Если вам нужен доступ к полям из других классов, создайте свойство public. Это дает вам свободу в дальнейшем изменить простой доступ к полям на более сложный метод получения / установки без изменения интерфейса вашего класса.
  • Все должно быть максимально локальным. Если private достаточно, нет необходимости делать его protected (также видимым в подклассах). И делайте только те вещи, которые вам действительно нужны, public извне.
  • Формы: только те вещи, которые вы хотите сохранить в файле DFM, должны быть published.
  • Положите столько, сколько сможете в разделе реализации, и столько, сколько сможете в разделе интерфейса. Это также верно для uses предложений.

Возможно, вы путаете термин глобальная переменная . Если он объявлен в классе, он не является глобальной переменной (даже если объявлен public). Глобальные переменные (которые, как вы правильно считаете, следует избегать) всегда помещаются в раздел var либо в интерфейсе, либо в разделе реализации (что предпочтительно в соответствии с приведенными выше общими правилами)

4 голосов
/ 22 января 2010

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

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

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

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

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

  • с использованием глобальных переменных существует только одно 'значение' (термин используется свободно) для всего приложения.
  • Используя поля класса или атрибуты записи, каждый новый экземпляр класса или записи имеет свои собственные значения, независимые от других экземпляров.
  • Это, похоже, подразумевает, что вы можете использовать какую-то глобальную форму, когда вашему приложению нужна только одна вещь. Однако, как упоминалось ранее: это не единственная причина, чтобы избежать глобальных изменений.
    • Лично я даже склонен избегать глобальных процедур.
    • Я часто обнаруживаю, что вещи, которые казались нормально объявленными глобальными, не так универсальны, как кажется на первый взгляд. (Например, Delphi VCL объявляет глобальный объект Screen, я работаю на двух экранах; многие наши клиенты используют от 4 до 6.)
    • Я также считаю полезным связывать подпрограммы, которые могли бы быть глобальными с конкретными классами, как методы класса . Как правило, это облегчает понимание кода.

Таким образом, перечисляя эти «местоположения» от самой большой области до самой маленькой, вы, как правило, стремитесь выбрать местоположения в списке ниже (особенно для данных).

  • интерфейс глобальный
  • глобальная реализация
  • интерфейс threadvar
  • реализация threadvar
  • опубликовано (заметьте, я действительно не считаю это идентификатором области; это действительно общедоступная область; «и включает в себя информацию RTTI» - теоретически было бы полезно также пометить некоторые частные атрибуты как «включающие RTTI».)
  • 1055 * общественное *
  • 1057 * защищен *
  • частный
  • строгое личное
  • локальная переменная

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

Методы, позволяющие успешно сбалансировать эти потребности, попадают в категорию гораздо более сложных (а иногда даже спорных) вопросов по проектированию системы. Плохой дизайн может побудить человека выставить «слишком много» с «слишком большой» областью видимости и (возможно, как это ни парадоксально) также снизить возможность повторного использования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...