По известному закону ближе к концу перевода наткнулся на уже готовый перевод на русский, но решил все-таки выложить, т.к.:
- получилось не так уж и плохо;
- хуже от этого не будет :)
Flex SDK coding conventions and best practices
- Именование
- Сокращения
- Акронимы
- Границы слов в названии
- Названия, использующие названия типов данных
- Имена пакетов
- Имена файлов
- Имена пространств имен
- Имена интерфейсов
- Имена классов
- Имена событий
- Имена стилей
- Строковые значения свойств
- Имена констант
- Имена свойств (переменных и геттеров/сеттеров)
- Имена закрытых переменных
- Имена методов
- Имена обработчиков событий
- Имена аргументов
- Имена пакетов ресурсов
- Имена идентификаторов ресурсов
- Прочие соглашения
- Использование языка
- Опции компилятора
- API, основанные на свойствах
- Объявления типов
- Литералы
- Выражения
- Директивы
- Объявления переменных
- Организация файла
- Объявление об авторском праве
- Директива package
- Директива import
- Директива use namespace
- Метаданные класса
- Объявление класса
- Директива include для Version.as
- Реализация интерфейса
- Инициализация класса
- Константы класса
- Class mix-ins
- Ресурсы класса
- Переменные класса
- Статические переменные
- Статические методы
- Конструктор
- Переопределенные свойства
- Свойства
- Переопределенные методы.
- Методы
- Переопределенные обработчики событий.
- Обработчики событий
- Out-of-package helper classes
- Форматирование
- Ширина строки
- Отступ
- Разделители секций
- Разделители в объявлениях переменных
- Метаданные
- Индексирование массива
- Запятые
- Литералы массива
- Литералы объектов
- Литералы функций
- Объявление типов
- Операторы и присваивание
- Директивы
- Объявление констант и переменных
- Объявление функций
- Вызов функции
- Директива if
- Директива for
- Директива switch
- ASDoc
Введение
Этот документ определяет соглашения написания кода компонент открытого фреймворка Flex на языке ActionScript 3. Соблюдение этих соглашений сделает исходный код связанным и последовательным, хорошо организованным и профессиональным.
Некоторые из этих соглашений совершенно произвольны, т.к. не всегда есть единственный лучший способ написать определенный код. Однако, для обеспечения совместимости, весь код Flex SDK будет соответствовать этим соглашениям.
Именование
Выбор хороших названий очень важен для легкого в использовании и понимании кода. Вы всегда должны уделять некоторое время, чтобы подумать, действительно ли вы выбрали хорошее имя для свойства или метода, особенно если это часть открытого API.
Наши стандарты именования главным образом совместимы с ECMAScript и Flash Player 9.
Сокращения
Как правило, их следует избегать. Например, calculateOptimalValue() – лучшее название для метода, чем calcOptVal().
Ясность более важна, чем уменьшение количества нажатий клавиш. И если вы не используете сокращений, то другим разработчикам не нужно будет запоминать какое сокращение слова «qualified» (например) больше нравиться вам – «qual» или «qlfd».
Однако мы стандартизировали некоторые сокращения:
* acc от accessibility (доступность), например ButtonAccImpl
* auto от automatic (автоматический), например autoLayout
* eval от evaluate (оценивать), например EvalBindingResponder
* impl от implementation (реализация), например ButtonAccImpl
* info от information (информация), например GridRowInfo
* num от number of (количество, число), например numChildren
* min от minimum (минимум), например minWidth
* max от maximum (максимум), например maxHeight
* nav от navigation (навигация), например NavBar
* regexp от regular expression (регулярное выражение), например RegExpValidator
* util от utility (утилита), например StringUtil
Возможно, этот список не включает все сокращения, которые используются. Если вы намереваетесь использовать сокращение, которого нет в этом списке, то поищите его в исходном коде, чтобы определить используется ли оно. Если нет, то дважды подумайте, является ли это сокращение наиболее соответствующим сокращаемому слову.
Иногда мы (намеренно) непоследовательны в сокращениях. Например, мы обстоятельно поясняем «горизонтальный» и «вертикальный» в большинстве случаев, таких как horizontalScrollPolicy и verticalScrollPolicy, но сокращаем для очень часто используемых и привычных HBox и VBox.
Акронимы
Различные акронимы распространены в Flex: AIR, CSS, HLOC, IME, MX, MXML, RPC, RSL, SWF, UI, UID, URL, WSDL и XML.
Для всех символов акронима используется одновременно либо только верхний регистр (SWF), либо только нижний (swf), но никогда оба регистра вместе (Swf). Единственный случай, когда символы акронима используют нижний регистр – когда акроним используется как идентификатор (название свойства или метода) или начало названия идентификатора. Идентификатор всегда должен начинаться со строчной буквы.
Примеры названий с акронимами - CSSStyleDeclaration, IUID, uid, IIME и imeMode.
Границы слов в названии
Если идентификатор содержит несколько слов, мы используем два способа, чтобы показать границы этих слов: изменение регистра (LayoutManager или measuredWidth) или нижнее подчеркивание (object_proxy).
Иногда непонятно, является ли сочетание слов в названии просто сочетанием или устоявшимся отдельным словом, и мы снова в таких случаях непоследовательны: dropdown, popUp, pulldown.
В случае, когда в названии идут подряд два или более акронима, необходимо придерживаться соглашений для акронимов. Пример (который фактически не используется) – loadCSSURL(). Но по возможности избегайте таких названий.
Названия, использующие названия типов данных
Если вы хотите включить тип данных в название, сделайте это в конце названия. Не используйте старые соглашения ActionScript 1, которые предлагают использование суффиксов типа _mc. Например, границу скина или шейпа стоит назвать borderSkin или borderShape, но не border_mc.
Часто, лучшее название для объекта это просто название соответствующего типа данных в нижнем регистре
var button:Button = new Button();
Имена пакетов
Их следует начинать со строчной буквы и использовать заглавные буквы для обозначения границ слов: controls, listClasses.
Имена пакетов должны быть всегда существительными или герундиями (существительное, образованное от глагола с – ing на конце), но не глаголами, прилагательными или наречиями.
У пакета, в котором реализуется множество подобных друг другу вещей, должно быть название, которое является множественным числом этой вещи: charts, collections, containers, controls, effects, events, formatters, managers, preloaders, resources, skins, states, styles, utils, validators.
Распространено использование герундий для названия пакета, содержимое которого совершает определенное действие: binding, logging, messaging, printing. С другой стороны это могут быть существительные, определяющие концепцию: accessibility, core, graphics, rpc.
Пакет, содержащий классы, обслуживающие компонент FooBar должен называться fooBarClasses.
Имена файлов
Для импортируемых API, имена файлов должны совпадать с именами файлов куда они импортируются. Но это правило не распространяется для включаемых (с помощью директивы include) файлов.
Имена включаемых (include) файлов для метаданных типа [Style(...)] должны начинаться с большой буквы и использовать верхний регистр для выделения границ слов и иметь на конце слово «Style»: BorderStyles.as, ModalTransparencyStyles.as.
Начинайте названия присоединяемых файлов с нижнего регистра и используйте нижнее подчеркивание для разделения слов: icon_align_left.png.
Имена пространств имен
Начинайте названия с нижнего регистра и используйте нижнее подчеркивание для разделения слов: mx_internal, object_proxy.
Имена интерфейсов
Названия следует начинать с буквы «I» и использовать верхний регистр для выделения границ слов: IList, IFocusManager, IUID.
Имена классов
Их следует начинать с заглавной буквы и использовать верхний регистр для выделения границ слов: Button, FocusManager, UIComponent.
Имя подкласса класса Event - FooBarEvent.
Имя подкласса класса Error - FooBarError.
Имена подклассов с функцио
Имя подкласса класса Formatter – FooBarFormatter.
Имя подкласса класса Validator – FooBarValidator.
Имена для классов скинов - FooBarBackground, FooBarBorder, FooBarSkin, FooBarIcon, FooBarIndicator, FooBarSeparator, FooBarCursor и т.д.
Сервисные классы лучше назвать FooBarUtil (но не FooBarUtils, оставьте множественное число для именования пакетов, классы должны именоваться в единственном числе)
Базовые классы принято называть FooBarBase: ComboBase, DateBase, DataGridBase, ListBase.
Имена событий
Название начинается со строчной буквы и используется изменение регистра для обозначения границ слов: "creationComplete".
Имена стилей
То же: color, fontSize.
Строковые значения свойств
То же: "auto", "filesOnly"
Имена констант
Имена констант пишутся в верхнем регистре, и для разделения слов используется нижнее подчеркивание: OFF, DEFAULT_WIDTH.
Значение константы (если ее тип String) должно соответствовать имени этой константы:
public static const FOO_BAR:String = "fooBar";
Имена свойств (переменных и геттеров/сеттеров)
Начинаются со строчной буквы и используется верхний регистр для выделения границ слов: i, width, numChildren.
Используйте «i» для именования итератора цикла и «n» для границы цикла. «j» и «m» используются аналогично, если нужен вложенный цикл:
for (var i:int = 0; i < n; i++)
{
for (var j:int = 0; j < m; j++)
{
...
}
}
Используйте «p» (сокращение от «property» - свойство) для использования в циклах for-in:
for (var p:String in o)
{
...
}
Если в классе переопределяются геттер/сеттер и есть необходимость использовать базовые (непереопределенные) геттер/сеттер, то переопределенные называются также как и базовые, но с добавлением в начале символа «$». Переопределенный геттер/сеттер должен быть объявлен с инструкцией «final» и не делать ничего, кроме вызова супергеттера/сеттера:
mx_internal final function get $numChildren():int
{
return super.numChildren;
}
Имена закрытых переменных
В начале имени добавляется нижнее подчеркивание: _foo.
Имена методов
Начинаются со строчной буквы и для обозначения границ слов используется верхний регистр: measure(), updateDisplayList().
Имена методов всегда должны быть глаголами.
Параметризующие методы нельзя называть getFooBar() и setFooBar(); они должны быть реализованы в виде геттеров/сеттеров. С другой стороны, если метод getFooBar() медленный и требует большого количества вычислений, то его лучше назвать findFooBar(), calculateFooBar(), determineFooBar() и т.д.
Если класс переопределяет метод и есть необходимость продолжать использовать базовый метод, то переопределенные называются также как и базовые, но с добавлением в начале символа «$». Переопределенный метод должен быть объявлен с инструкцией «final» и не делать ничего, кроме вызова базового метода:
mx_internal final function $addChild(child:DisplayObject):DisplayObject
{
return super.addChild(child);
}
Имена обработчиков событий
Имена обработчиков событий получаются добавлением к имени события слова «Handler»: mouseDownHandler().
Если обрабатываются события отсылаемые потомками (не this), то к названию обработчика в начале добавляется имя потомка и нижнее подчеркивание: textInput_focusInHandler().
Имена аргументов
Используйте «value» для именования аргумента каждого сеттера:
public function set label(value:String):void
но не так:
public function set label(lab:String):void
не так:
public function set label(labelValue:String):void
и не так:
public function set label(val:String):void
Используйте «event» (не «e», «evt» или «eventObj») для именования аргумента обработчика:
protected function mouseDownHandler(event:Event):void
Имена пакетов ресурсов
Если пакет ресурсов содержит ресурсы для специфического пакета, назовите пакет ресурсов так же как и специфический пакет: controls, {formatters}}, validators.
Имена идентификаторов ресурсов
Должны начинаться со строчной буквы и использовать верхний регистр для обозначения границ слов: pm, dayNamesShort.
Прочие соглашения
Избегайте использования в именах слова «object», т.к. это создает неопределенность.
Используйте слово «item» для именования элемента данных, но не отображаемого объекта.
Слово «renderer» для именования отображаемого объекта, который визуализирует элемент данных.
Не используйте «type» для обозначения типа, для этого используйте «kind»
Использование языка
Эта часть соглашений покажет, как использовать конструкции языка AS3, особенно когда можно получить один и тот же результат разными способами.
Опции компилятора
Компилируйте с включенными опциями -strict и -show-actionscript-warnings. (По умолчанию они включены в flex-config.xml)
API, основанные на свойствах
Старайтесь применять API, которые основываются на свойствах, а не на методах, т.к. это более подходит для декларативного стиля программирования на MXML.
Объявления типов
Пишите тип каждой объявленной переменной, аргумента, возвращаемого методом значения и константы. Если переменная не имеет типа, то это нужно указать явно.
Так
var value:*;
Но не так:
var value;
Используйте самый подходящий тип для более полного соответствия. Например int а не Number, и тем более не Object или просто *. Другой пример – обработчик mouseDownHandler должен иметь аргумент event:MouseEvent а не event:Event.
Используйте int для целых чисел, даже если они не могут быть отрицательными. Используйте uint только для цветов RGB, битовых масок и других не числовых переменных.
Используйте * только для значений, которые могут быть не определены (undefined). В остальных случаях используйте Object, чтобы при значении равном null получить сообщение “object doesn't exist”
Если вы присваиваете какой-либо переменной тип Array, добавляйте в комментарии тип элементов, которые содержит этот массив:
var a:Array /* of String */ = [];
но не так
var a:Array = [];
И делайте так
function f(a:Array /* of Number */):Array /* of Object */
{
...
}
но не так
function f(a:Array):Array
Литералы
Undefined
Избегайте использования undefined везде, где это возможно. Он необходим только там, где тип переменной объявлен с *. Однако и * вы должны использовать как можно реже.
int и uint
Не используйте десятичную точку в целом числе:
Нужно так:
2
Но не так:
2.
Используйте нижний регистр для х и верхний для A-Z в шестнадцатеричных чисел
Нужно так:
0xFEDCBA
Но не так:
0Xfedcba
Всегда используйте запись цветов RGB с использованием шестизначного номера.
Нужно так:
private const BLACK:uint = 0x000000;
Но не так:
private const BLACK:uint = 0;
Number
Если числовое значение может быть дробным, указывайте это с помощью десятичной точки и нуля, который следует за этой точкой:
Так
alphaFrom = 0.0;
alphaTo = 1.0;
Но не так
alphaFrom = 0;
alphaTo = 1;
Однако не нужно это делать для координат точки даже если она может быть дробной.
Нужно так:
var xOffset:Number = 3;
Но не так:
var xOffset:Number = 3.0;
Используйте е, а не Е для обозначения экспотенциальных значений:
Нужно так:
1.0e12
Но не так:
1.0E12
Используйте значение по умолчанию для числовых значений NaN при объявлении числовых переменных, если нет другого значения.
String
Используйте двойные, а не одинарные кавычки для разделения строк, имеющих кавычки как символ строки
Нужно так
"What's up, \"Big Boy\"?"
Но не так:
'What\'s up, "Big Boy"?'
Используйте \u, а не \U для экранирования уникода.
Array
Используйте литерал массива для создания нового вместо конструкции new Array()
Нужно так:
[]
Но не так:
new Array()
И нужно так
[ 1, 2, 3 ]
Но не так
new Array(1, 2, 3)
Используйте конструктор если необходимо создать пустой массив определенной длины, т.е. вместо [ undefined, undefined, undefined ] использовать new Array(3)
Object
Используйте литерал {} вместо new Object().
Нужно так:
{}
Но не так:
new Object()
И нужно так:
o = { a: 1, b: 2, c: 3 };
Но не так:
o = new Object();
o.a = 1;
o.b = 2;
o.c = 3;
Или так:
o = {};
o.a = 1;
o.b = 2;
o.c = 3;
Function
Избегайте использования литералов функций для создания анонимных функций. Необходимо использовать методы классов и функции уровня пакета.
Если нужно использовать литерал функции, объявите тип возвращаемого значения и закончите последнюю строчку тела функции точкой с запятой:
Нужно так:
function(i:int):void { doIt(i - 1); doIt(i + 1); }
Но не так:
function(i:int) { doIt(i - 1); doIt(i + 1) }
RegExp
Используйте литерал вместо конструкции RegExp для создания регулярного выражения из строки:
Нужно так:
var pattern:RegExp = /\d+/g;
Но не так:
var pattern:RegExp = new RegExp("\\d+", "g");
XML и XMLList
Используйте литерал вместо конструктора для создания XML из строки:
Нужно так:
var node:XML = ;
Но не так:
var node:XML = new XML("");
Используйте двойные кавычки для определения значений атрибутов XML:
Нужно так:
var node:XML = ;
Но не так:
var node:XML = ;
Классы
Используйте полную ссылку на класс (с именами пакетов) только если нужно разделить в классе два одинаковых класса, которые принадлежат разным пакетам:
Нужно так:
import mx.controls.Button;
...
var b:Button = new Button();
Но не так:
import mx.controls.Button;
...
var b:Button = new mx.controls.Button();
Но в этой ситуации нужно использовать полную ссылку:
import mx.controls.Button;
import my.controls.Button;
...
var b:Button = new mx.controls.Button();
Выражения
Круглые скобки
Не используйте круглые скобки со следующими операторами +, -, *, /, &&, ||, <, <=, >, >=, ==, and !=.
Нужно так:
var e:Number = a * b / (c + d);
Но не так
var e:Number = (a * b) / (c + d);
И нужно так:
var e:Boolean = a && b || c == d;
Но не так:
var e:Boolean = ((a && b) || (c == d));
Правила ассоциативности для других операторов сложнее запомнить, поэтому для них применение круглых скобок оправданно.
Приведение типов
Не приводите булево значение в true или false – оно уже является или тем или тем.
Нужно так:
if (flag)
Но не так:
if (flag == true)
И нужно так:
var flag:Boolean = a && b;
Но не так:
var flag:Boolean = (a && b) != false;
Старайтесь приводить явно значения типов Number, String, XML, XMLList, Array, Object, or * к булеву типу, т.к. эти типы имеют множество значений и трудно запомнить, какое из них приводиться к false, а какое к true в AS3.
Нужно так:
if (s != null && s != "")
Но не так:
if (s)
Подклассам класса Object (например UIComponent) можно позволить приводиться к булеву типу самостоятельно, т.к. понятно что к false они будут приведены только если равны null. (Замечание: Object и его подклассы не могут получать значение undefined)
Нужно так:
if (child)
Но не так:
if (child != null)
И нужно так:
if (!child)
Но не так:
if (child == null)
int и uint, если их значения равны нулю, будут приведены в false а любые другие значения в true. Так, если вы хотите использовать неявное приведение типов, то все ОК.
Лучше использовать приведение, чем оператор as. Используйте оператор as когда приведение может привести к ошибке и вы хотите выражение привести к null, а не получить ошибку.
Нужно так:
IUIComponent(child).document
Но не так:
(child as IUIComponent).document
Сравнения
Следует писать в порядке, в котором они имеют смысл:
Нужно так:
if (n == 3) // "if n is 3"
Но не так:
if (3 == n) // "if 3 is n"
Операторы ++ и --
В случае, когда постфиксные и префиксные операторы эквивалентны используйте постфиксные. Используйте префиксные операторы только тогда, когда вы должны использовать значение прежде чем оно будет изменено.
Нужно так:
for (var i:int = 0; i < n; i++)
Но не так:
for (var i:int = 0; i < n; ++i)
Тернарный оператор
Используйте тернарные операторы вместо инструкций if/else, особенно для «нулевых» проверок:
Нужно так:
return item ? item.label : null;
Но не так:
if (!item)
return null;
return item.label;
Но не используйте тернарные операторы вместо комплексной логики if/else:
Нужно так:
if (a < b)
return -1;
else if (a > b)
return 1;
return 0;
Но не так:
return a < b ? -1 : (a > b ? 1 : 0);
Оператор new
Используйте круглые скобки после ссылки на класс, даже если конструктор класса не принимает никаких аргументов:
Нужно так:
var b:Button = new Button();
Но не так:
var b:Button = new Button;
Директивы
Заканчивайте каждую директиву точкой с запятой.
Нужно так:
a = 1;
b = 2;
c = 3;
Но не так:
a = 1
b = 2
c = 3
Директива include
Используйте include, но не # include. Заканчивайте каждую директиву include точкой с запятой:
Нужно так:
include "../core/ComponentVersion.as";
Но не так:
#include "../core/ComponentVersion.as"
Используйте относительные, а не абсолютные пути.
Директива import
Импортируйте определенные классы, интерфейсы и функции уровня пакета. Не используйте * при импорте:
Нужно так:
import mx.controls.Button;
import flash.utils.getTimer;
Но не так:
import mx.core.*;
Директива use namespace
Избегайте ее использования. Используйте :: для ссылки на неоткрытое пространство имен.
Нужно так
import mx.core.mx_internal;
// Позже в каком-нибудь методе...
mx_internal::doSomething();
Но не так:
import mx.core.mx_internal;
use namespace mx_internal;
// Позже в каком-нибудь методе...
doSomething();
Директива if
Если выражение конструкции if/else содержит единственную директиву, то не нужно ее заключать в фигурные скобки.
Нужно так:
if (flag)
doThing1();
Но не так:
if (flag)
{
doThing1();
}
И нужно так:
if (flag)
doThing1();
else
doThing2();
Но не так:
if (flag)
{
doThing1();
}
else
{
doThing2();
}
Но если выражение содержит больше одной директивы, то заключаем его в блоки:
Нужно так:
if (flag)
{
doThing1();
}
else
{
doThing2();
doThing3();
}
Но не так:
if (flag)
doThing1();
else
{
doThing2();
doThing3();
}
Делая многочисленные проверки на ошибки, используйте последовательно оператор if, который сразу будет возвращать false, как только найдется ошибка. Не делайте вложенных проверок, которые будут выполняться целиком для возвращения результата.
Нужно так:
if (!condition1)
return false;
...
if (!condition2)
return false;
...
if (!condition2)
return false;
...
return true;
Но не так:
if (condition1)
{
...
if (condition2)
{
...
if (condition3)
{
...
return true;
}
}
}
return false;
Директива for
Заключайте тело цикла в фигурные скобки, даже если оно содержит только одну директиву:
Нужно так:
for (var i:int = 0; i < 3; i++)
{
doSomething(i);
}
Но не так:
for (var i:int = 0; i < 3; i++)
doSomething(i);
Храните предел цикла в локальной переменной, чтобы она не переопределялась (если это не нужно) в каждой итерации.
Нужно так:
var n:int = a.length;
for (var i:int = 0; i < n; i++)
{
...
}
Но не так:
for (var i:int = 0; i < a.length; i++)
{
...
}
Объявляйте итератор цикла внутри круглых скобок директивы for, если он не используется многократно в других местах.
Нужно так:
for (var i:int = 0; i < 3; i++)
Но не так:
var i:int;
for (i = 0; i < 3; i++)
{
...
}
Директива while
Тело while необходимо заключать в фигурные скобки, даже если оно содержит единственную директиву:
Нужно так:
while (i < n)
{
doSomething(i);
}
Но не так:
while (i < n)
doSomething(i);
Директива do
Тело do необходимо заключать в фигурные скобки, даже если оно содержит единственную директиву:
Нужно так:
do
{
doSomething(i);
}
while (i < n);
Но не так:
do
doSomething(i);
while (i < n);
Директива switch
Все выражения конструкции switch должны быть заключены в фигурные скобки. Поместите break или return в блок, но не после него. Если необходим return, не помещайте break после return. Обрабатывайте выражение default так же, как и выражения case.
Нужно так:
switch (n)
{
case 0:
{
foo();
break;
}
case 1:
{
bar();
return;
}
case 2:
{
baz();
return;
}
default:
{
blech();
break;
}
}
Но не так:
switch (n)
{
case 0:
foo();
break;
case 1:
{
bar();
}
break;
case 2:
baz();
return;
break;
default:
blech();
}
Директива return
Не заключайте возвращаемое значение в скобки:
Нужно так:
return n + 1;
Но не так:
return (n + 1);
return в середине метода – это нормально.
Объявления переменных
Не делайте объявления нескольких переменных в одной строке:
Нужно так:
var a:int = 1;
var b:int = 2;
Но не так:
var a:int = 1, b:int = 2;
Ключевое слово override
Помещать его нужно перед модификатором доступа:
Нужно так:
override protected method measure():void
Но не так:
protected override method measure():void
Модификаторы доступа
Модификаторы доступа должны всегда указываться явно (там, где это допустимо). Не используйте internal, если вы его не используете явно в других случаях.
Перед тем как сделать API public или protected, хорошо подумайте, действительно оно должно быть именно таким. public и protected API должны быть задокументированы.
Ключевое слово static
Используйте его после модификатора доступа
Нужно так:
public static const MOVE:String = «move»;
Но не так:
static public const MOVE:String = «move»;
Ключевое слово final
Используйте его после модификатора доступа
Нужно так:
public final class BoxDirection
Но не так:
final public class BoxDirection
Объявляйте «перечисляемые классы» с ключевым словом final.
«Базовые» свойства и методы (которые начинаются с $) также должны быть объявлены с ключевым словом final.
Константы
Все константы должны быть объявлены с ключевым словом static. Нет повода использовать несколько констант, которые будут хранить одно и тоже значение.
Нужно так:
public static const ALL:String = "all";
Но не так:
public const ALL:String = "all";
Переменные
Если объявляемая переменная при инициализации должна иметь значение отличное от значения по умолчанию, то это значение нужно присваивать при объявлении, а не в конструкторе:
Нужно так:
private var counter:int = 1;
Но не так:
private var counter:int;
...
public function MyClass()
{
super();
...
counter = 1;
}
Локальные переменные
Используйте локальные переменные сразу в их объявлении. Не надо их сначала объявлять, а ниже использовать:
Нужно так:
private function f(i:int, j:int):int
{
var a:int = g(i - 1) + g(i + 1);
var b:int = g(a - 1) + g(a + 1);
var c:int = g(b - 1) + g(b + 1);
return (a * b * c) / (a + b + c);
}
Но не так:
private function f(i:int, j:int):int
{
var a:int;
var b:int;
var c:int;
a = g(i - 1) + g(i + 1);
b = g(a - 1) + g(a + 1);
c = g(b - 1) + g(b + 1);
return (a * b * c) / (a + b + c);
}
Объявляйте каждую локальную переменную только один раз в теле функции.
Нужно так:
var a:int;
if (flag)
{
a = 1;
...
}
else
{
a = 2;
...
}
Но не так:
if (flag)
{
var a:int = 1;
...
}
else
{
var a:int = 2;
...
}
И нужно так:
var i:int;
for (i = 0; i < n; i++)
{
...
}
for (i = 0; i < n; i++)
{
...
}
Но не так:
for (var i:int = 0; i < n; i++)
{
...
}
for (var i:int = 0; i < n; i++)
{
...
}
Классы
Если класс расширяет Object, то выражение «extends Object» можно опустить.
Конструктор не должен принимать параметров только тогда, когда единственное назначение класса – вызов инициализирующего метода, например loadResources().
Конструкторы
Если класс содержит только свойства, напишите конструктор, в котором вызовите super(), даже если он пустой.
Если конструктор принимает аргументы, которые будут затем присвоены его свойствам, то эти аргументы нужно назвать так же как и эти свойства:
Нужно так:
public function MyClass(foo:int, bar:int)
{
this.foo = foo;
this.bar = bar;
}
Но не так:
public function MyClass(fooVal:int, barVal:int)
{
foo = fooVal;
bar = barVal;
}
Не присваивайте свойствам класса значения в его конструкторе, сделайте это при их объявлении. С другой стороны, если они должны быть сброшены для каждого экземпляра класса, то это должно быть сделано в конструкторе.
Interfaces
TBD
Namespaces
TBD
Implementing properties
TBD
Metadata
TBD
Пакеты
Хотя бы один открытый член в пакете должен быть (обычно это класс, иногда пространство имен или функция)
Организация файла
В этом разделе определяется порядок, в котором должен быть организован файл фреймворка Flex.
Объявление об авторском праве
Это включение делается в самом верху *.as файла фреймворка. Формат следующий:
////////////////////////////////////////////////////////////////////////////////
//
// ADOBE SYSTEMS INCORPORATED
// Copyright 2008 Adobe Systems Incorporated
// All Rights Reserved.
//
// NOTICE: Adobe permits you to use, modify, and distribute this file
// in accordance with the terms of the license agreement accompanying it.
//
////////////////////////////////////////////////////////////////////////////////
Заметим, что его размер не более 80 символов по ширине.
Директива package
TBD
Директива import
TBD
Директива use namespace
TBD
Метаданные класса
Организуйте метаданные в секции, в следующем порядке: Events, Styles, Effects, Excluded APIs и т.д. Для каждой секции используйте заголовок. Заметим, что заголовок должен быть не более 40 символов в ширину и иметь два пробела между // и названием секции.
Расположите метаданные в алфавитном порядке по name = «…» в каждой секции. В секции Other metadata они могут быть расположены по тэгу:
//--------------------------------------
// Events
//--------------------------------------
/
**
* ASDoc comment.
*/
[Event
/**
* ASDoc comment.
*/
[Event
//--------------------------------------
// Styles
//--------------------------------------
/**
* ASDoc comment.
*/
[Style
/**
* ASDoc comment.
*/
[Style]
//--------------------------------------
// Effects
//--------------------------------------
/**
* ASDoc comment.
*/
[Effect
/**
* ASDoc comment.
*/
[Effect]
//--------------------------------------
// Excluded APIs
//--------------------------------------
[Exclude(name=”horizontalAlign”, kind=”style”)]
[Exclude(name=”verticalAlign”, kind=”style”)]
//--------------------------------------
// Other metadata
//--------------------------------------
[DefaultBindingProperty(source=”text”, destination=”text”)]
[IconFile(“Text.png”)]
Объявление класса
TBD
Директива include для Version.as
Каждый класс должен включать core/Version.as используя для этого относительный путь. Этот файл содержит объявление для static const VERSION:String.
include "../core/Version.as";
Реализация интерфейса
TBD
Инициализация класса
TBD
Константы класса
Используйте static const для их объявления.
AS3 не позволяет иметь константе в качестве значения экземпляры классов Array и Object. Объявляйте такие константы с помощью static var, а не static const, но помещайте их в этой же секции констант, т.к. концептуально они являются константами
Ресурсы класса
TBD
Переменные класса
TBD
Статические переменные
Объявляйте статические геттеры/сеттеры здесь. Расположите их в алфавитном порядке. Используйте небольшой разделитель для каждого имени переменной. Геттер следует поместить перед сеттером
Статические методы
Здесь помещаются статические функции класса.
Конструктор
TBD
Переменные
TBD
Переопределенные свойства
Помещайте переопределенные не статические геттеры/сеттеры здесь. Располагайте их в алфавитном порядке. Используйте небольшой разделитель для каждого имени свойства. Располагайте геттер перед сеттером.
Свойства
Помещайте новые не статические геттеры/сеттеры здесь. Располагайте их в алфавитном порядке. Используйте небольшой разделитель для каждого имени свойства. Располагайте геттер перед сеттером.
Переопределенные методы.
Здесь помещаются не статические переопределенные методы.
Методы
Здесь помещаются не статические методы.
Переопределенные обработчики событий
Здесь помещаются переопределенные обработчики событий.
Обработчики событий
Новые обработчики событий помещаются здесь.
Out-of-package helper classes
TBD
Форматирование
Этот раздел о том, как должен быть отформатирован класс фреймворка Flex.
Ширина строки
Разбивайте код на строчки длиной не более 80 символов. Это нужно делать по следующим причинам:
- разработчики с небольшими мониторами не должны пользоваться горизонтальной прокруткой кода;
- сравнивающие утилиты должны иметь возможность отображать два класса бок о бок целиком.
- размер шрифта может быть увеличен отдельными участниками группы, для этого не нужно будет пользоваться горизонтальной прокруткой.
- Исходный код может быть распечатан без обрезки и переноса.
Отступ
Используйте 4-пробельный отступ. Настройте свой текстовый редактор для вставки пробелов, а не табуляции. Это позволит другим программам, например Notepad отображать код корректно, не уродуя его.
Разделители секций
Большие секции внутри класса должны быть разделены следующим образом:
//--------------------------------------------------------------------------
//
// Overridden methods
//
//--------------------------------------------------------------------------
Он располагается от колонки 4 до колонки 80 . Текст выровнен по колонке 8.
Небольшие секции, например между свойствами разделены следующим образом:
//----------------------------------
// visible
//----------------------------------
Он располагается от колонки 4 до колонки 40 . Текст выровнен по колонке 8.
Перед и после разделителя оставьте пустую строку.
Разделители в объявлениях переменных
Используйте пустую строку для разделения объявлений переменных, констант и методов:
/**
* @private
* Holds something.
*/
var a:Number;
/**
* @private
*/
var b:Number
Метаданные
TBD
Нужно так:
Inspectable[a="1", b="2"]
Но не так:
Inspectable[a=1 b=2]
Индексирование массива
Не ставьте пробелы между индексом и квадратной скобкой
Нужно так:
a[0]
Но не так:
a[ 0 ]
Запятые
После запятой ставьте один пробел.
Литералы массива
Ставьте один пробел после левой квадратной скобки и один пробел перед правой квадратной скобкой, и один пробел после каждой запятой:
Нужно так:
[ 1, 2, 3 ]
Но не так:
[1, 2, 3]
[1,2,3]
Пустые массивы отдельный случай:
Нужно так:
[]
Но не так:
[ ]
Форматируйте длинные инициализаторы массива следующим образом:
static var numberNames:Array /* of String */ =
[
"zero",
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine"
];
Литералы объектов
Здесь все по аналогии с литералами массивов:
Нужно так:
{ a: 1, b: 2, c: 3 }
Но не так:
{a: 1, b: 2, c: 3}
{a:1, b:2, c:3}
{a:1,b:2,c:3}
Пустые объекты отдельный случай:
Нужно так:
{}
Но не так:
{ }
Длинные инициализаторы форматируются так:
private static var TextStyleMap:Object =
{
color: true,
fontFamily: true,
fontSize: true,
fontStyle: true,
fontWeight: true,
leading: true,
marginLeft: true,
marginRight: true,
textAlign: true,
textDecoration: true,
textIndent: true
};
Литералы функций
TBD
var f:Function;
f = function():void
{
doSomething();
};
Объявление типов
Не ставьте пробелы для разделения переменной, двоеточия и типа данных:
Нужно так:
var n:Number;
Но не так:
var n : Number;
var n: Number;
И нужно так:
function f(n:Number):void
Но не так:
function f(n : Number) : void
function f(n: Number): void
Операторы и присваивание
Ставьте по одному пробелу до и после оператора присваивания:
Нужно так:
a = 1;
Но не так:
a=1;
так:
a + b * c
Но не так:
a+b*c
так:
a == b
Но не так:
a==b
так:
!o
Но не так:
! o
Так:
i++
Но не так:
i ++
Директивы
Начинайте каждую директиву с новой строки, чтобы можно было установить контрольную точку для каждой директивы:
Нужно так:
a = 1;
b = 2;
c = 3;
Но не так:
a = 1; b = 2; c = 3;
Выравнивайте блоки директив так:
function f():void
{
var n:int = numChildren;
for (var i:int = 0; i < n; i++)
{
if ()
{
x = horizontalGap * i;
y = verticalGap * i;
}
}
}
Но не так:
function f():void {
var n:int = numChildren;
for (var i:int = 0; i < n; i++) {
if () {
x = horizontalGap * i;
y = verticalGap * i;
}
}
}
Объявление констант и переменных
TBD
Объявление функций
TBD
Нужно так:
f(a, b)
Но не так:
f(a,b)
f( a, b )
Если параметры разделяются на несколько строк, то перенесенные параметры выравниваются по левой круглой скобке. Несколько параметров могут располагаться в одной строке, если они для этого подходят. Иначе каждый параметр располагается в отдельной строке. Если даже один параметр не входит в строку, в которой объявляется метод, то он переноситься на следующую строку и выравнивается по имени метода:
public function foo(parameter1:Number, parameter2:String,
parameter3:Boolean):void
public function foo(parameter1:Number,
parameter2:String,
parameter3:Boolean):void
public function aVeryLongFunctionName(
parameter1:Number, parameter2:String,
parameter3:Boolean):void
Вызов функции
TBD
Нужно так:
f(a, b)
Но не так:
f(a,b)
f( a, b )
Директива if
Нужно так:
if (a < b)
Но не так:
if(a < b)
if( a < b )
if ( a < b )
Директива for
Нужно так:
for (var i:int = 0; i < n; i++)
Но не так:
for(var i:int = 0; i < n; i++)
for( var i:int = 0; i < n; i++ )
for ( var i:int = 0; i < n; i++ )
Если условный блок нужно перенести, то его части выравниваются по левой круглой скобке:
for (var aLongLoopVariableName:int = aLongInitialExpression;
aLongLoopVariableName < aLongUpperLimit;
aLongLoopVariableName++)
Директива switch
Нужно так:
switch (n)
Но не так:
switch(n)
switch( n )
switch ( n )
Нужно так:
switch (n)
{
case 1:
{
a = foo();
break;
}
case 2:
{ a = bar();
break;
}
default:
{
a = blech();
break;
}
}
Но не так:
switch(n)
switch( n )
switch ( n )
ASDoc
Комментирование свойств
Документировать нужно только первый метод из пары геттер/сеттер:
/**
* @private
* возвращаемая переменная геттера
*/
private var _someProp:Foo;
/**
* Здесь располагаются все комментарии – сначала для геттер, затем для сеттера
*/
public function get someProp():Foo
{
...
}
/**
* @private
*/
public function set someProp(value:Foo):void
{
...
}
Кроме того, комментарии ASDoc применяются и к тэгам метаданных так же, как и к любым другим конструкциям в пределах класса, поэтому стоит позаботиться, чтобы комментарии относились к надлежащему адресату. Если вы комментируете someProp то:
Нужно так:
[Bindable("somePropChanged")]
/**
* Комментарии для someProp
*/
public function get someProp():Foo
Но не так:
/**
* Комментарии для someProp
*/
[Bindable("somePropChanged")]
public function get someProp():Foo
Браво, браво! То, что доктор прописал.
ОтветитьУдалитьПотрясающий перевод! Огромное спасибо за проделанную работу!
ОтветитьУдалить