Неизменные Коллекции Actionscript 3 - PullRequest
10 голосов
/ 01 марта 2009

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

На данный момент эта версия только для чтения является классом ArrayIterator , который я написал, который реализует типичный интерфейс Iterator (hasNext, getNext). Он также расширяет Proxy , поэтому его можно использовать в для каждого цикла так же, как и для массива.

Итак, мой вопрос: разве это не должно быть фундаментальной чертой многих языков? Способность передавать ссылки только для чтения просмотров коллекций?

Также теперь, когда улучшена безопасность типов для коллекций в AS3, в виде класса Vector , когда я обертываю Vector в VectorIterator Я теряю набор текста ради неизменности. Есть ли способ реализовать два желания, неизменность и ввод в AS3?

Ответы [ 5 ]

4 голосов
/ 05 марта 2009

Кажется, что использование шаблона Iterator - лучший способ в настоящее время в AS3 передавать коллекцию по системе, гарантируя, что она не будет изменена.

Используемый мной интерфейс IIterator смоделирован на Java Iterator , но я не реализую метод remove () , так как это считается проектом ошибка многих в сообществе Java из-за того, что он позволяет пользователю удалять элементы массива Ниже моя IIterator реализация:

 public interface IIterator
 {
     function get hasNext():Boolean
     function next():*
 }

Затем это реализуется такими классами, как ArrayIterator, VectorIterator и т. Д.

Для удобства я также расширяю Proxy на своих конкретных классах Iterator и обеспечиваю поддержку циклов for-each в AS3 путем переопределения nextNameIndex () и nextValue () методы. Это означает, что код, который обычно использует массивы, не нуждается в изменении при использовании моего IIterator .

var array:Array = ["one", "two", "three"]

for each (var eachNumber:String in array)
{
    trace(eachNumber)
}

var iterator:IIterator = new ArrayIterator(array)

for each (var eachNumber:String in iterator)
{
    trace(eachNumber)
}

Единственная проблема в том, что ... пользователь не может взглянуть на интерфейс IIterator и знать, что он может использовать цикл for-each для перебора коллекции. , Чтобы увидеть это, им придется взглянуть на реализацию ArrayIterator.

0 голосов
/ 18 декабря 2013

Что-то, что я делаю, чтобы добиться этого, это чтобы класс, который поддерживает список, возвращал только копию этого списка в получателе через slice(). Например, у моего игрового движка есть класс Scene, который поддерживает список всех Beings, которые были добавлены к нему. Этот список затем отображается как копия:

public function get beings():Vector.<Being>
{
    return _beings.slice();
}

(Извините, что возродил старую ветку, я натолкнулся на это, когда искал пути для реализации именно того, что охватывает ответ Брайана, и подумал, что я потрачу на это 2 цента).

0 голосов
/ 23 апреля 2010

Я создал небольшую библиотеку неизменяемых коллекционных классов для AS3, включая типизированный упорядоченный список, который, похоже, будет соответствовать вашим потребностям. Подробнее см. в этом блоге .

0 голосов
/ 01 марта 2009

У вас есть неизменность, которую вы хотите через прокси-объект или нет? Обратите внимание, что конструктор VectorIterator может принимать обязательный параметр Class. По общему признанию это не является дружественным для проектировщика в настоящее время, но позволяет надеяться, что вещи улучшатся в будущем.

0 голосов
/ 01 марта 2009

Некоторые утверждают, что тот факт, что вы можете реализовать такие шаблоны в виде библиотек, является аргументом против добавления функций в сам язык (например, разработчики языка C ++ обычно так говорят).

...