Руководство по actionscript. часть 3, стр. 015

Проблема решена на 9/10. Помещение переменных и методов в пространство имен mx internal, безусловно, уменьшает их непосредственную видимость, однако технически это не запрещает коду за пределами прикладной среды Flex обращаться к ним. Любой разработчик, которому известен идентификатор URI пространства имен mx_internal, может применять этот идентификатор для обращения к любой переменной или методу, уточняемому с использованием пространства имен mx_internal.

Однако целью пространства имен mx internal является не техническое запрещение использования переменных и методов разработчиком. Скорее оно является большим знаком предупреждения, сообщающим о том, что переменные и методы не предназначены для использования внешним кодом и могут быть изменены без предупреждения или привести к ошибочному поведению, если обращение к ним осуществляется из кода за пределами прикладной среды Flex.

Пример: управление доступом на основании разрешений

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

Защищаемый класс — класс, который предоставляет доступ к своим защищенным методам и переменным.

Методы и переменные с ограниченным доступом — группа методов и переменных, доступ к которым ограничен.

Авторизованные классы — классы, которым разрешен доступ к методам и переменным с ограниченным доступом.

Рассмотрим базовый код защищаемого класса:

package { // Это защищаемый класс, public class ShelteredClass {

// Пространство имен restricted уточняет переменные

// и методы, доступ к которым ограничен.

private namespace restricted;

// Это массив авторизованных классов. В данном примере // определен только один авторизованный класс: Caller, private var authorizedClasses:Array = [ Caller ];

// Это переменная с ограниченным доступом.

// К ней могут обращаться только авторизованные

// классы.

Руководство по actionscript. часть 3, стр. 016

Restricted var secretData:String = «No peeking»;

// Это метод с ограниченным доступом.

// К нему могут обращаться только авторизованные

// классы.

restricted function secretMethod ( ).void { trace(«Restricted method secretMethod( ) called»);

}

}

}

Защищаемый класс хранит массив авторизованных классов. Кроме того, в нем объявлено пространство имен с использованием модификатора управления доступом private, которое применяется для уточнения методов и переменных с ограниченным доступом. Более того, идентификатор URI для этого пространства имен генерируется автоматически, поэтому его невозможно узнать и использовать за пределами данного класса. Наконец, защищаемый класс определяет сами переменные и методы с ограниченным доступом.

Для обращения к методу или переменной с ограниченным доступом (например, secretData или secretMethod ( ) ) потенциальный класс должен получить общеизвестные «ключи от парадной двери». Другими словами, он должен получить ссылку на пространство имен, которое уточняет методы и переменные с ограниченным доступом. Однако защищаемый класс предоставит эту ссылку только в том случае, если потенциальный класс — будем называть его «вызывающим классом» — является одним из элементов массива authorizedClasses.

В нашем примере вызывающий класс будет просить у класса ShelteredClass ссылку на пространство имен restricted, используя метод getRestricted Namespace ( ) класса ShelteredClass. Метод getRestrictedAccess ( ) принимает экземпляр вызывающего класса в качестве аргумента. Если экземпляр вызывающего класса оказывается авторизованным, метод getRestrictedNames расе ( ) вернет ссылку на пространство имен restricted. В противном случае метод вернет значение null, которое сообщает о том, что вызывающий класс не имеет права обращаться к методам и переменным с ограниченным доступом. Рассмотрим код метода getRestrictedNamespace ( ):

public function getRestrictedNamespace

(cal lerObject:Object.):Namespace { // Проверяем, есть ли объект cal1erObject в массиве authorizedClasses. for each (var authorizedClass:Class in authorizedClasses) { // Если вызывающий объект является экземпляром авторизованного класса… if (callerObject is authorizedClass) { // …возвращаем обратно ссылку на пространство имен restricted // («ключи от парадной двери») return restricted;

// Вызывающий объект не является экземпляром

// авторизованного класса, поэтому

// запрещаем дальнейшее обращение к переменной

// и методу с ограниченным доступом.

Руководство по actionscript. часть 3, стр. 017

Return null;

}

В листинге 17.5 продемонстрирован весь код класса ShelteredClass, включая метод getRestrictedNamespace ( ).

Листинг 17.5. Класс ShelteredClass

package { // Это защищаемый класс public class ShelteredClass {

// Пространство имен restricted уточняет переменные

// и методы, доступ к которым ограничен.

private namespace restricted;

// Это массив авторизованных классов. В данном примере // определен только один авторизованный класс: Caller, private var authorizedClasses:Array = [ Caller ];

// Это переменная с ограниченным доступом.

// К ней могут обращаться только авторизованные классы.

restricted var secretData.-String = «No peeking»;

// Это метод с ограниченным доступом. // К нему могут обращаться только авторизованные классы, restricted function secretMethod ( ):void { trace(«Restricted method secretMethod( ) called»);

}

public function getRestrictedNamespace

(callerObject:Object):Namespace { // Проверяем, есть ли объект callerObject в массиве authorizedClasses. for each (var authorizedClass:Class in authorizedClasses) { // Если вызывающий объект является экземпляром // авторизованного класса… if (cal1erObject is authorizedClass) { // …возвращаем обратно ссылку на пространство имен restricted // («ключи от парадной двери») return restricted;

}

}

// Вызывающий объект не является экземпляром // авторизованного класса, поэтому // запрещаем дальнейшее обращение к переменной // и методу с ограниченным доступом, return null;

Теперь рассмотрим класс Caller — класс, который желает получить доступ к методам и переменным с ограниченным доступом класса Shel teredClas s. Принимая во внимание значения элементов массива authorizedClasses класса ShelteredClass, мы знаем, что класс Caller является допустимым. В нашем примере Caller также является основным классом приложения, поэтому он расширяет класс Sprite. Класс Caller создает экземпляр класса ShelteredClass в своем методе конструктора и присваивает этот экземпляр переменной shelteredOb j ect.

Руководство по actionscript. часть 3, стр. 018

Package { import flash. display.*;

public class Caller extends Sprite { private var shelteredObject:ShelteredClass;

public function Caller ( ) { shelteredObject = new ShelteredClass( );

}

}

}

Чтобы вызвать метод secretMethod ( ) класса ShelteredClass, объект Caller должен сначала получить ссылку на пространство имен restricted. Для этого объект Caller передает себя в метод getRestrictedNamespace ( ) и присваивает результат (либо пространство имен restricted, либо значение null) переменной key для дальнейшего использования.

var key:Namespace = shelteredObject. getRestrictedNamespace(this);

Далее, перед тем как вызвать метод secretMethod ( ), объект Caller проверяет, ссылается ли переменная key на допустимое пространство имен. Если это так, объект Caller использует переменную key в качестве пространства имен для вызова метода secureMethod ( ):

if (key!= null) { shelteredObject. key::secureMethod( );

}

Для удобства метод с именем callSecretMethod ( ) нашего класса Caller включает код, который вызывает метод secretMethod ( ):

public function callSecretMethod ( ):void { var key:Namespace = shelteredObject. getRestrictedNamespace(this); if (key!= null) { shelteredObject. key:: secretMethod( );

}

}

Листинг 17.6 демонстрирует весь код рассматриваемого класса Caller, включая метод callSecretMethod ( ) и другой удобный метод displaySecret ( ), который обращается к переменной secretData с ограниченным доступом, используя тот же основной принцип.

Руководство по actionscript. часть 3, стр. 019

Листинг 17.6. Класс Caller

package { import flash. display.*;

public class Caller extends Sprite {

private var shelteredObject:ShelteredClass;

public function Caller ( ) { shelteredObject = new ShelteredClass( ); callSecretMethod( ); displaySecret( );

}

public function callSecretMethod ( ):void { var key-.Namespace = shelteredObject. getRestrictedNamespace(this) ; if (key!= null) { shelteredObject. key::secretMethod( );

}

}

public function displaySecret ( ):void { var key:Namespace = shelteredObject. getRestrictedNamespace(this); if (key!= null) { trace(shelteredObject. key. :secretData);

}

}

}

}

Пример: реализация режимов работы программы

Последним рассматриваемым примером будет электронный словарь, который позволяет переводить с японского языка на английский и наоборот. Словарь демонстрирует использование режимов программы — область программирования на языке ActionScript, где применяются пространства имен, с самым большим потенциалом. Находясь в «режиме японского языка», словарь возвращает английский перевод для японских слов; находясь в «режиме английского языка», словарь возвращает японский перевод для английских слов. Каждый режим представляется пространством имен: j apanese для японско-английского режима и english для англо-японского режима.

Руководство по actionscript. часть 3, стр. 020

В этом примере задействованы следующие участники:

? Japane se — пространство имен для переменных и методов, относящихся к японскому языку;

? English — пространство имен для переменных и методов, относящихся к английскому языку;

? QueryManager — класс, осуществляющий поиск слов;

? SearchOptions — этот класс содержит базовые настройки для операции поиска;

? JapaneseSearchOptions — класс, содержащий настройки, характерные для операции поиска на японском языке;

? Engl ishSearchOpt ions — данный класс хранит настройки, характерные для операции поиска на английском языке;

? JEDictionary — основной класс приложения.

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

Начнем с рассмотрения определений пространств имен japanesenenglish, чей код уже должен быть вам знаком:

package {

public namespace english = «http://www. example. com/jedict/english»;

}

package {

public namespace japanese = «http://www. example. com/jedict/japanese»;

}

Далее идет класс QueryManager, который определяет два метода для поиска слова, — japanese: : search ( ) и english: : search ( ). Вызов подходящего метода происходит в зависимости от текущего режима программы. Каждый метод search ( ) принимает apryMeHT’options, который определяет настройки поиска в виде либо объекта класса JapaneseSearchOptions, либо объекта класса EnglishSearchOpt ions соответственно. Далее при рассмотрении класса JEDictionary мы увидим, что настройки поиска выбираются в соответствии с текущим режимом программы. Вот код класса QueryManager:

package { public class QueryManager {

japanese function search (word:String.

Руководство по actionscript. часть 3, стр. 021

Options.-JapaneseSearchOptions): Array { trace («Now searching for ‘» + word + ‘»An»

+ » Match type: » + options. getMatchType( ) + «\n»

+ » English language variant: » + options. getEnglishVariant( ));

// Расположенный здесь код (не показан) должен выполнять поиск // в японско-английском словаре и возвращать результаты. * // но для эксперимента мы будем просто возвращать предопределенный // список результатов:

return ["English Word 1". "English Word 2". "etc"];

}

english function search (word.-String.

options:Engl ishSearchOptions):Array { traceCNow searching for ‘» + word + ‘»An»

+ » Match type: » + options. getMatchType( ) + «\n»

+ » Use kanji in results: » + options. getKanjiInResults( ));

// Расположенный здесь код (не показан) должен выполнять поиск // в англо-японском словаре и возвращать результаты,

// но для эксперимента мы будем просто возвращать предопределенный // список результатов;

return ["Japanese Word 1", "Japanese Word 2". "etc"];

}

}

}

Теперь рассмотрим три класса, предоставляющие настройки поиска: SearchOptions и два его подкласса JapaneseSearchOptions и EnglishSearchOptions. Класс SearchOptions задает, с использованием какого режима программа должна выполнять поиск указанной строки: «точного совпадения» (искомое слово должно полностью совпадать со строкой поиска), «совпадает начало» (все искомые слова должны начинаться со строки поиска) или «содержит совпадение» (все искомые слова должны включать строку поиска).

Руководство по actionscript. часть 3, стр. 022

Различные типы совпадений представлены такими константами, какМАТСН_ЕХАСТ, MATCH_STARTSWITH и MATCH_CONTAINS. Тип совпадений для текущего поиска может быть установлен и получен с помощью методов setMatchType ( ) и getMatchType ( ). Рассмотрим класс SearchOptions:

package { public class SearchOptions { public static const MATCH_EXACT:String = «Exact»; public static const MATCH_STARTSWITH:String = «StartsWith»; public static const MATCH_CONTAINS:String = «Contains»;

private var matchType:String;

public function SearchOptions ( ) { // По умолчанию используется режим «точного совпадения». setMatchTypeCSearchOptions. MATCHJXACT);

}

public function getMatchType ( ):String { return matchType;

}

public function setMatchType (newMatchType:String):void { matchType = newMatchType;

}

}

}

Класс JapaneseSearchOptions расширяет класс SearchOptions, добавляя настройки, характерные только для японско-английского режима поиска, — определение того, какой вариант английского языка должен использоваться для возвращаемых результатов: U. S. English (американский) или U. K. English (британский). Эти два варианта английского языка представляются константами ENGLISH_UK и ENGLISH_US. Вариант английского языка для текущего поиска может быть установлен и получен с помощью методов setEnglishVariant ( ) и getEnglishVariant ( ).

package {

public class JapaneseSearchOptions extends SearchOptions { public static const ENGLISH_UK:String = «EnglishUK»; public static const ENGLISHES:String = «EnglishUS»;

private var englishVariant:String;

public function JapaneseSearchOptions ( ) { setEnglishVariant(JapaneseSearchOptions. ENGLISHJJK);

}

public function getEnglishVariant ( ):String { return englishVariant;

}

public function setEnglishVariant (newEnglishVariant:String):void { englishVariant = newEnglishVariant;

}

}

}

Как и JapaneseSearchOptions, класс Engl ishSearchOpt ions расширяет класс SearchOptions, добавляя настройки, характерные только для англо-японского режима поиска, — определение того, набор каких символов должен использоваться для возвращаемых результатов: кандзи (набор идеографических символов) или хирагана (набор фонетических символов). Набор символов для текущего поиска может быть установлен или получен с помощью методов setKanj ilnResults ( ) и getKanj ilnResults ( ):

package { .

Руководство по actionscript. часть 3, стр. 023

Public class EnglishSearchOptions extends SearchOptions { private var kanjiInResults:Boolean = false;

public function getKanjilnResults ( ):Boolean { return kanjiInResults;

}

public fun’ction setKanjiInResults (newKanjiInResults:Boolean):void { kanjiInResults = newKanjiInResults;

}

}

}

Наконец, рассмотрим основной класс приложения JEDict ionary, в котором происходит основная «магия», связанная с использованием пространств имен. Бегло просмотрите код класса, представленный в листинге 17.7, после чего мы рассмотрим его более подробно.

Листинг 17.7. Класс JEDictionary

package { import flash. display. Sprite;

public class JEDictionary extends Sprite { private var queryMan:QueryManager;

japanese var options:JapaneseSearchOptions; english var options:EnglishSearchOptions;

private var lang:Namespace;

public function JEDictionary( ) { queryMan = new QueryManager( );

japanese::options = new JapaneseSearchOptions( );

japanese::options. setMatchType(SearchOptions. MATCH_STARTSWITH);

japanese: :options. setEnglishVari ant (JapaneseSearchOptions. ENGLISHES);

english::options = new EnglishSearchOptions( );

engl i sh::opti ons. setMatchType(SearchOpti ons. MATCH_CONTAINS);

engli sh::opti ons. setKanjiInResul ts(true);

// Найти перевод японского слова… setModeJapaneseToEnglish( ); findWordC’sakana»);

// Найти перевод английского слова… setModeEnglishToJapaneseC ); findWordC’fish»);

}

public function findWord (word:String):void { var words:Array = queryMan. lang::search(word, lang::options); tracer Words found: » + words);

public function setModeEnglishToJapanese ( ):void { lang = english;

}

public function setModeJapaneseToEnglish ( ):void { lang = japanese;

}

}

}

Итак, основной класс приложения JEDictionary расширяет класс Sprite: public class JEDictionary extends Sprite {

Для поиска класс JEDictionary создает экземпляр класса QueryManager, который присваивается переменной queryMan:

private var queryMan:QueryManager;

Затем класс JEDictionary создает две переменные, каждая из которых имеет локальное имя options, уточняемое пространствами имен j apanese и english. Эти переменные хранят настройки поиска, которые будут передаваться в метод экземпляра search ( ) класса QueryManager. Обратите внимание, что их типы данных соответствуют типу выполняемого поиска:

japanese var options:JapaneseSearchOptions; english var options:EnglishSearchOptions;

После этого идет определение важной переменной lang, которая ссылается на пространство имен, соответствующее текущему режиму словаря (японскому или английскому):

private var lang:Namespace;

Это все, что касается переменных класса JEDictionary; теперь рассмотрим его методы: setModeEnglishTo Japanese ( ), setModeJapaneseToEnglish ( ) и findWord ( ). Они активизируют различные режимы словаря, присваивая переменной lang пространство имен english или j арапеse соответственно:

public function setModeEnglishToJapanese ( ):void { lang = english;

}

public function setModeJapaneseToEnglish ( ):void { lang = Japanese;

}

Метод findWord ( ) применяет объект класса QueryManager для выполнения поиска в словаре, используя подходящий метод search ( ). Вызов метода search ( ) является самой важной строкой кода в нашем примере со словарем:

queryMan. lang::search(word, lang::options)

Обратите внимание, что пространство имен (режим программы) определяет не только тип выполняемого поиска (поведение), но и тип вариантов, используемых для этого поиска (данные). Когда переменной lang присвоено пространство имен j арапе se, вызывается метод j арапе se: : search ( ), в который передается объект JapaneseSearchOptions. Когда переменной lang присвоено пространство имен english, вызывается метод english: : search ( ), в который передается объект EnglishSearchOptions.

Руководство по actionscript. часть 3, стр. 024

Результат вызова метода search ( ) присваивается локальной переменной words, после чего полученные результаты отображаются в виде отладочного сообщения:

public function findWord (word:String):void { var words:Array = queryMan.1ang::search(word. lang::options); traceC Words found: » + words);

}

Для демонстрационных целей метод-конструктор класса JEDictionary выполняет поиск по словарю двух предопределенных слов (хотя в полнофункциональном приложении поиск по словарю обычно осуществляется в ответ на введенную пользователем строку). Процедура поиска выполняется экземпляром приложения QueryManager, который создается в конструкторе, как показано ниже:

queryMan = new QueryManager( );

Стандартные настройки для всех японско-английских и англо-японских поисков также задаются в конструкторе:

japanese::options = new JapaneseSearchOptions( );

japanese::options. setMatchType(SearchOptions. MATCH_STARTSWITH);

japanese::opti ons. setEngli shVari ant(JapaneseSearchOpti ons. ENGLISHJJS):

english::options = new EnglishSearchOptions( ):

engli sh::opti ons. setMatchType(SearchOpti ons. MATCH_CONTAINS):

engli sh::opti ons. setKanjiInResults(true);

Для осуществления поиска конструктор устанавливает режим словаря, после чего передает строку поиска в метод экземпляра findWord ( ) класса JEDictionary:

// Найти перевод японского слова… setModeJapaneseToEnglish( ); findWordC»sakana»);

// Найти перевод английского слова… setModeEnglishToJapanese( ); findWordC’fish»): }

В зависимости от режима словаря вызывается подходящий метод search ( ) и используются соответствующие варианты поиска.



Полезные ссылки
Случайные записи
  • 22.03.2011">Руководство по actionscript. часть 2, стр. 017
  • 26.02.2011">Руководство по actionscript. часть 6, стр. 070
  • 10.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.90
  • 18.05.2010">Самоучитель по креативному веб-дизайну. Книга 2, стр.63
  • 13.03.2011">Руководство по actionscript. часть 3, стр. 103
  • 08.09.2013">Первые новости о Windows 10
  • 03.06.2010">Самоучитель по креативному веб-дизайну. Книга 3, стр.97
  • 28.02.2011">Руководство по actionscript. часть 6, стр. 009
  • 09.06.2011">Выбираем курицу
  • 07.03.2011">Руководство по actionscript. часть 4, стр. 107
  • 02.03.2011">Руководство по actionscript. часть 5, стр. 106
  • 01.03.2011">Руководство по actionscript. часть 5, стр. 122
  • 10.05.2010">Самоучитель по креативному веб-дизайну. Книга 1, стр.91
  • 21.03.2011">Руководство по actionscript. часть 2, стр. 048
  • 14.06.2010">Самоучитель по креативному веб-дизайну. Книга 4, стр.82
Опрос

Какие цвета вы предпочитаете?

View Results

Loading ... Loading ...