10

我最近一直在尝试在 AS3 中实现一些干净的编码实践。其中之一是不放弃对包含对象的数组的引用。关键是我控制一个类的添加和删除,而数组的所有其他用户都接收只读版本。

目前只读版本是我写的一个ArrayIterator类,它实现了一个典型的Iterator接口(hasNext,getNext)。它还扩展了Proxy,因此它可以像 Array 一样用于每个循环。

所以我的问题是这不应该是许多语言的基本特征吗?将引用传递给集合的只读视图的能力?

同样,现在 AS3 中的集合的类型安全性得到了改进,以Vector类的形式,当我将 aa Vector 包装在VectorIterator中时,为了不变性,我失去了输入。有没有办法在 AS3 中实现这两个愿望,不变性和打字?

4

5 回答 5

4

似乎使用迭代器模式是目前 AS3 中在系统中传递集合的最佳方式,同时保证它不会被修改。

我使用的IIterator接口是基于 Java Iterator建模的,但我没有实现remove()方法,因为这被 Java 社区中的许多人认为是设计错误,因为它允许用户删除数组元素。下面是我的IIterator实现:

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

然后由 ArrayIterator、VectorIterator 等类实现。

为方便起见,我还在具体的 Iterator 类上扩展了Proxy ,并通过覆盖nextNameIndex()nextValue()方法为 AS3 中的for-each循环提供支持。这意味着通常使用数组的代码在使用我的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 的实现才能看到这一点。

于 2009-03-05T11:29:35.440 回答
0

有些人会争辩说,您可以将此类模式实现为库的事实是反对向语言本身添加功能的论据(例如,C++ 语言设计者通常会这么说)。

于 2009-03-01T13:52:22.977 回答
0

您是否具有通过代理对象想要的不变性?请注意,您可以让 VectorIterator 构造函数采用强制的 Class 参数。诚然,目前这对设计师来说并不友好,但希望将来事情会有所改善。

于 2009-03-01T14:22:51.343 回答
0

我为 AS3 创建了一个不可变集合类的小型库,其中包括一个类型化的有序列表,听起来它可以满足您的需求。有关详细信息,请参阅此博客文章

于 2010-04-23T14:54:42.173 回答
0

我为实现这一目标所做的事情是让维护列表的类仅在 getter via 中返回该列表的副本slice()。举个例子,我的游戏引擎有一个类Scene,它维护着所有Beings已添加到其中的列表。然后将该列表作为副本公开,如下所示:

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

(很抱歉恢复一个旧线程,我在寻找方法来实现布莱恩的答案所涵盖的内容时遇到了这个问题,并认为我会在这件事上投入 2 美分)。

于 2013-12-18T03:14:08.640 回答