Этот документ описывает единый стиль кода, разработанный командой Terrasoft. Этот стиль будет полезен всем тем, кто ведет разработку или конфигурирование продуктов с использованием платформы Terrasoft.
Список терминов
|
Термин
|
Определение
|
|
Конфигурация
|
Структурированный набор сервисов, позволяющий выполнять некоторую бизнес задачу, с использованием платформы Terrasoft.
|
|
Язык конфигурации
|
Язык, на котором отображаются все заголовки элементов управления и пользовательские сообщения.
|
|
Сервис
|
Объект конфигурации, основной характеристикой которого является тип (Script, Table, DBDataset, Window и т.д.).
|
|
USI
|
Уникальный идентификатор сервиса (Unique Service Identifier), который состоит из трех частей – Модуля, Пути внутри модуля и кода сервиса.
|
|
Модуль
|
Первая часть уникального идентификатора сервиса (USI).
|
|
Группа
|
Элемент уникального идентификатора сервиса (USI), из набора которых строится путь к сервису внутри модуля.
|
|
Код сервиса
|
Последняя часть уникального идентификатора сервиса (USI).
|
|
Идентификатор
|
Логическое имя, определяющее некоторую сущность.
|
Стили использования регистра букв
- Pascal – указание этого стиля оформления идентификатора обозначает, что первая буква заглавная и все последующие первые буквы слов тоже заглавные. Например, BackColor, LastModified, DateTime.
- Camel – указание этого стиля обозначает, что первая буква строчная, а остальные первые буквы слов заглавные. Например, borderColor, accessTime, templateName.
Именование идентификаторов
- Идентификатор может содержать только английские буквы, цифры и знаки подчеркивания.
- Идентификатор не может начинаться с цифры.
- Необходимо избегать идентификаторов, содержащих цифры.
- Не используйте подчеркивание для отделения слов внутри идентификаторов, за исключением отделения префикса от основной части идентификатора.
- Старайтесь не использовать сокращения.
- Старайтесь делать имена идентификаторов как можно короче (но не в ущерб читабельности). Главное, чтобы смысл идентификатора был понятен в используемом контексте.
- Предпочтительно использовать имена, которые ясно и четко описывают предназначение и/или смысл сущности.
- Старайтесь не использовать для разных сущностей имена, отличающиеся только регистром букв.
- Если идентификатор имеет префикс, то префикс всегда пишется в нижнем регистре.
- Старайтесь использовать имена с простым написанием. Избегайте (в разумных пределах) использования слов с двойными буквами, сложным чередованием согласных. Прежде, чем остановиться в выборе имени, убедитесь, что оно легко пишется и однозначно воспринимается на слух. Если оно с трудом читается, и вы ошибаетесь при его наборе, возможно, стоит выбрать другое.
- Избегайте использования идентификаторов, которые совпадают с ключевыми словами используемого языка программирования.
- Если идентификатор описывает некоторую логическую сущность, то его имя предпочтительно начинать с Is, Has или Have.
Сокращения
- Необходимо избегать использования аббревиатур или неполных слов в идентификаторах, если только они не являются общепринятыми, или идентификатор слишком длинный. Например, пишите GetWindow, а не GetWin.
- Не используйте аббревиатуры, если они не общеприняты в области информационных технологий.
- Широко распространенные аббревиатуры используйте для замены длинных фраз. Например, UI вместо User Interface или Olap вместо On-line Analytical Processing.
- Если имеется идентификатор длиной менее трех букв, являющийся сокращением, то его записывают заглавными буквами, например IO, UI. Имена длиннее двух букв записывайте в стиле Pascal, например Guid, Xml, XmlDocument.
Конфигурация
- Основным стилем регистра букв объектов конфигурации является стиль Pascal.
Модули/Группы
- Имя модуля/группы пишется на английском языке.
- Имя модуля/группы может состоять из нескольких слов.
- Разделителем слов в имени модуля/группы является символ пробела.
- Каждое слово имени пишется с большой буквы.
- Необходимо избегать использования цифр в имени модуля/группы, если это не обусловлено дополнительными требованиями.
- Имя модуля пишется в единственном числе.
- Имя группы может писаться как в единственном, так и во множественном числе, в зависимости от её предназначения.
Коды сервисов
- Код сервиса формируется как "Префикс" + "_" + "Идентификатор", например ds_Account, sq_Offering.
- Код сервиса должен быть идентификатором.
- Код сервиса пишется в единственном числе.
- Префикс кода сервиса однозначно зависит от типа сервиса и должен браться из таблицы соответствия.
|
Тип сервиса
|
Префикс
|
|
ADOCommand
|
adocmd
|
|
ADOConnection
|
adocon
|
|
ADODataset
|
adods
|
|
DBDataset
|
ds
|
|
DeleteQuery
|
dq
|
|
Enum
|
enm
|
|
FastReport
|
fr
|
|
ImageList
|
il
|
|
InsertQuery
|
iq
|
|
InsertSelectQuery
|
isq
|
|
MemoryDataset
|
mds
|
|
Script
|
scr*
|
|
SelectQuery
|
sq
|
|
Table
|
tbl
|
|
UpdateQuery
|
uq
|
|
UserFields
|
uf
|
|
Window
|
wnd
|
|
WorkflowAction
|
wa
|
|
WorkflowDiagram
|
wd
|
* Префикс сервиса Script может меняться в зависимости от его предназначения. Если скрипт содержит обработчики событий для сервиса Window или Dataset, то для него используется особый способ формирования кода, который описан ниже.
Заголовки и описания
- Заголовок/описание должен раскрывать предназначение объекта.
- Заголовок/описание должен заполняться на языке конфигурации.
- Если заголовок/описание состоит из нескольких слов, то первое слово должно быть написано с большой буквы, а остальные с маленькой, если это не обусловлено дополнительными требованиями.
- Заголовок сервиса должен быть уникальным в пределах конфигурации для данного типа сервиса, т.е., например, нельзя допускать существование двух сервисов типа Table с одинаковым заголовком.
- Для некоторых объектов могут быть указаны уточнения по правилам заполнения заголовков, например, иногда заголовок должен быть равен коду объекта.
Сервисы
Script
- Префикс сервиса Script, содержащего только библиотечные функции, формируется по стандартному правилу, т.е. берется из таблицы соответствия.
- Префикс сервиса Script, содержащего обработчики событий некоторого сервиса, формируется как "Код сервиса" + "Script", например, если скрипт содержит обработчики событий окна wnd_Account, то его код будет wnd_AccountScript.
- Заголовок сервиса Script должен быть равен его коду.
- Необходимо избегать установки значения свойства Timeout=-1, т.к. это может привести к зависанию системы. Исключение могут составлять только те скрипты, логика которых действительно может потребовать длительного выполнения.
- Все требования к оформлению программного кода на языке JScript оформлены в виде отдельной статьи.
Table
- Заголовок сервиса Table должен быть написан в единственном числе.
- Для таблицы должно быть заполнено описание.
- Имена полей таблицы должны быть идентификаторами.
- Имена полей, которые являются полями ссылки на другие таблицы и поля перечислений, должны заканчиваться на ID, например поле "Ответственный" в таблице tbl_Account должно называться OwnerID.
- Для каждого поля таблицы должен быть заполнен заголовок.
- Необходимо избегать создания таблиц без пяти системных полей ID, CreatedOn, CreatedByID, ModifiedOn и ModifiedByID.
- Все системные поля должны быть объявлены в таблице первыми в следующем порядке – ID, CreatedOn, CreatedByID, ModifiedOn и ModifiedByID.
- Для каждого поля таблицы должно быть заполнено описание.
- Для всех полей таблицы, которые являются полями ссылки на другие таблицы, должны быть созданы индексы.
- Имена индексов формируются как "I" + "Основная часть кода таблицы" + "Имена всех полей индекса", например, имя индекса в таблице tbl_Account по полям "Страна" и "Город" должно быть IAccountCountryIDCityID.
- Для всех полей таблицы, которые являются полями-ссылками на другие таблицы, должны быть созданы внешние ключи.
- Имена внешних ключей формируются как "F" + "Основная часть кода таблицы" + "Имя поля ссылки", например, имя внешнего ключа в таблице tbl_Account по полю "Страна" должно быть FAccountCountryID.
- В случае если таблица является таблицей детали раздела/справочника, то для нее должна быть установлена та же группа таблиц (Parent Table Group), которая установлена для основной таблицы раздела/справочника. Например, для таблицы "Адрес контрагента" (tbl_AccountAddress) в качестве группы таблиц должно быть установлено то же значение, которое установлено для таблицы "Контрагент" (tbl_Account).
- В случае если таблица является основной таблицей раздела/справочника, то для нее должно быть установлено основное отображаемое поле (Primary Display Field).
- Для поля ID рекомендуется использовать тип "Первичный ключ" (Primary Key).
- Для полей, которые являются ссылками на другие таблицы, рекомендуется использовать тип "Уникальный идентификатор" (Global Unique Identifier).
- Ниже приведена таблица рекомендуемых названий полей для некоторых стандартных ситуаций.
|
Название поля
|
Имя поля в БД
|
|
Название
|
Name
|
|
Заголовок
|
Title
|
|
Описание
|
Description
|
|
Ответственный
|
OwnerID
|
|
Дата начала
|
StartDate
|
|
Дата завершения
|
DueDate
|
|
Продолжительность
|
Duration
|
- Необходимо избегать изменения структуры системных сервисов из модуля System, таблиц прав доступа, логирования изменений и других сервисов, создаваемых автоматически, т.к. это может привести к разрушению конфигурации.
SelectQuery, InsertQuery, UpdateQuery, DeleteQuery, InsertSelectQuery, ADOCommand
- Заголовок сервиса должен быть равен его коду.
- Для колонок, которые выбираются из основной таблицы запроса (FROM), псевдонимы (Alias) должны совпадать с именами полей таблицы.
- Для колонок, которые выбираются из присоединенных (JOIN) таблиц, псевдоним формируется как "Имя поля ссылки" + "Имя поля из присоединенной таблицы". Например, при выборе поля "Название" (Name) из таблицы "Контакты" (tbl_Contact) в запросе на выборку контрагентов (tbl_Account) как имени ответственного (OwnerID), псевдоним колонки должен быть OwnerName.
- Имена параметров запроса должны быть идентификаторами.
- В случае если параметр используется для записи значения в поле таблицы, то имя параметра должно быть равно имени поля таблицы.
- Коды фильтров должны быть идентификаторами.
- Код основного фильтра запроса должен быть равен "Where".
- Если запрос предназначен для основного набора данных раздела/справочника, то в нем обязательно должен быть параметр ID и фильтр сравнения с кодом ID.
DBDataset, MemoryDataset, ADODataset
- Заголовок сервиса должен быть написан в единственном числе.
- Имена полей должны быть идентификаторами.
- Имена полей, которые являются полями ссылки на другие таблицы (ILookupDataField) и поля перечислений (IEnumDataField), должны заканчиваться на ID, например, поле "Ответственный" в таблице ds_Account должно называться OwnerID.
- Для каждого поля набора данных должен быть заполнен заголовок.
- Для набора данных типа DBDataset заголовок поля должен совпадать с заголовком поля таблицы, которому оно соответствует.
- Необходимо избегать создания наборов данных без пяти системных полей: ID, CreatedOn, CreatedByID, ModifiedOn и ModifiedByID.
- Все системные поля должны быть объявлены в наборе данных первыми в следующем порядке – ID, CreatedOn, CreatedByID, ModifiedOn и ModifiedByID.
- В случае если набор данных является основным набором данных раздела/справочника, то для него должно быть установлено ключевое поле (Key Field) и основное отображаемое поле (Primary Display Field).
Window
- Значение свойства WindowCaption окна должно совпадать с заголовком окна.
- Высота и ширина окна должны быть кратны пяти.
- Имена визуальных и невизуальных компонентов окна (кнопки, поля ввода, таймеры, и т.д.) формируются как "Префикс" + "Идентификатор", например, edtName.
- Префикс имени компонента однозначно зависит от типа компонента, и должен браться из таблицы соответствия.
|
Тип компонента
|
Префикс
|
|
ActionMenu
|
am
|
|
ActionMenuItem
|
ami
|
|
ActionMenuSeparator
|
ami
|
|
ActiveXControl
|
axc
|
|
BoolDataControl
|
chb
|
|
Button
|
btn
|
|
CalculatorControl
|
clc
|
|
CalendarControl
|
cal
|
|
ChartSpaceControl
|
crts
|
|
CheckBox
|
chb
|
|
ColorBox
|
edt
|
|
ColorBoxDataControl
|
edt
|
|
CV6600Reader
|
rdr
|
|
DataGrid
|
grd
|
|
DataGridColumn
|
col
|
|
DataGridView
|
dgv
|
|
DatasetLink
|
dl
|
|
DataTreeGrid
|
grd
|
|
DateTimeControl
|
edt
|
|
DateTimeDataControl
|
edt
|
|
Edit
|
edt
|
|
EnumControl
|
edt
|
|
EnumDataControl
|
edt
|
|
EnumLink
|
el
|
|
FastReportPreviewer
|
frp
|
|
FileChangeNotifier
|
fcn
|
|
FiltersBuilderControl
|
fbc
|
|
FloatDataControl
|
edt
|
|
Frame
|
fm
|
|
FrameGroup
|
fg
|
|
FrameSet
|
fm
|
|
FunnelControl
|
fc
|
|
ImageDataControl
|
img
|
|
IntegerDataControl
|
edt
|
|
Label
|
lbl
|
|
LookupControl
|
edt
|
|
LookupDataControl
|
edt
|
|
MemoDataControl
|
mm
|
|
NumericEdit
|
edt
|
|
Page
|
pg
|
|
Pages
|
pc
|
|
PivotTableControl
|
pt
|
|
ProgressBar
|
pb
|
|
RadioButton
|
rb
|
|
RichDataControl
|
rch
|
|
ScheduleControl
|
sch
|
|
TAPILine
|
tl
|
|
TextDataControl
|
edt
|
|
Timer
|
tmr
|
|
Toolbar
|
tb
|
|
UserFieldsGroup
|
ufg
|
|
Window
|
wnd
|
|
WindowContainer
|
wnd
|
|
WorkflowDiagramPreviewer
|
wdp
|
|
WorkspaceNavigator
|
wn
|
- Имена визуальных компонентов окна, предназначенных для отображения и модификации одного поля набора данных (TextDataControl, LooupDataControl, и т.д.), формируются как "Префикс" + "Имя поля набора данных", например, элемент управления для поля "Название" (Name) контрагента должен называться edtName.
- При создании нескольких кнопок на контейнере Frame/FrameGroup для соответствующего компонента необходимо устанавливать значение свойства HasSeparator=false, что позволит убрать расстояние между кнопками.
- Если необходимо разбить элементы управления на группы внутри одного контейнера, то такое разбиение делается присвоением значения Offset (OffsetLeft, OffsetRight) равным пяти для первого элемента управления в группе.
- Для самого нижнего контейнера Frame/FrameGroup, на котором располагаются только кнопки, должно быть установлено значение свойства GroupType=fgtFooter.
- Если для контейнера Frame/FrameGroup значение свойства GroupType=fgtFooter, то должно быть установлено значение свойства Size=33.
ImageList
- Заголовок сервиса должен быть равен его коду.
- Имя изображения (Image) должно быть идентификатором.
- Имя изображения формируется как "Идентификатор" + "Суффикс".
- Если элемент управления имеет только один тип отображения, то суффикс изображения не используется, и в этом случае имя формируется как "Идентификатор".
- Суффикс имени изображения однозначно зависит от типа отображения картинки элементом управления, и должен браться из таблицы соответствия.
|
Тип отображения
|
Суффикс
|
|
Обычное
|
Normal
|
|
Активное (горячее)
|
Hot
|
|
Нажатое
|
Pressed
|
|
Неактивное (отключенное)
|
Disabled
|
Enum
- Заголовок сервиса должен быть написан в единственном числе.
- В качестве идентификаторов (ID) элемента перечисления может использоваться любая строка.
- Код элемента перечисления формируется как "Префикс" + "_" + "Идентификатор".
- Префикс элемента перечисления формируется из первых букв кода перечисления. Например, для перечисления enm_RelationRoleType префикс для всех элементов должен быть rrt (rrt_Contact, rrt_Account).
UserFields
- Заголовок сервиса должен совпадать с заголовком основной таблицы (Table) раздела, для которого он создается.
- В список сервисов и объектов, которые модифицируются сервисом UserFields, должны быть обязательно добавлены следующие объекты:
- Основная таблица раздела (Table).
- Основной запрос раздела (SelectQuery).
- Основной набор данных раздела (DBDataset).
- Окно основного реестра раздела (Window).
- Элемент управления основного реестра (DataGrid).
WorkflowAction
- Заголовок сервиса должен быть написан в единственном числе.
- Если элемента процесса предназначен для работы с объектами определенного раздела, то его заголовок должен совпадать с заголовком основной таблицы раздела.
- Цвет элемента должен быть изменен на уникальный, для облегчения идентификации типа элемента на диаграмме.
- Для каждого действия процесса должно быть создано окно редактирования, которое позволяет в удобном виде менять его параметры.
- Имена параметров элемента процесса должны быть идентификаторами.
WorkflowDiagram
- Диаграмма процесса должна содержать только один элемент начала процесса (IWorkflowDiagramStartItem).
- Диаграмма процесса должна содержать как минимум один элемент завершения процесса (WorkflowDiagramFinishItem).
- Имена параметров процесса должны быть идентификаторами.
- Если элемент процесса (WorkflowDiagramItem) используется в скрипте процесса, то его имя должно удовлетворять всем принципам именования идентификаторов.
- Если связь элементов процесса (WorkflowDiagramLink) используется в скрипте процесса, то ее имя должно удовлетворять всем принципам именования идентификаторов.