不可变集合 Actionscript 3
我最近一直在尝试在 AS3 中实现一些干净的编码实践。 其中之一是不泄露包含对象中对数组的引用。 要点是我控制一个类的添加和删除,并且数组的所有其他用户接收只读版本。
目前,只读版本是我编写的 ArrayIterator 类,它实现了典型的 Iterator 接口(hasNext、getNext)。 它还扩展了 Proxy,因此可以像数组一样在 foreach 循环中使用。
所以我的问题是这不应该是许多语言的基本特征吗? 能够传递引用以只读集合视图吗?
另外,现在 AS3 中的集合以 Vector 类的形式改进了类型安全性,当我将一个 Vector 包装在 VectorIterator 中时,我会因为以下原因而丢失输入:不变性。 有没有办法在 AS3 中实现不变性和类型这两个愿望?
I've been trying lately to implement some clean coding practices in AS3. One of these has been to not give away references to Arrays from a containing object. The point being that I control addition and removal from one Class and all other users of the Array receive read only version.
At the moment that read only version is a ArrayIterator class I wrote, which implements a typical Iterator interface (hasNext, getNext). It also extends Proxy so it can be used in for each loops just as a Array can.
So my question is should this not be a fundamental feature of many languages? The ability to pass around references to read only views of collections?
Also now that there is improved type safety for collections in AS3 , in the form of the Vector class, when I wrap a a Vector in a VectorIterator I lose typing for the sake of immutability. Is there a way to implement the two desires, immutability and typing in AS3?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
看来使用 Iterator 模式是最好的方法目前在 AS3 中用于在系统中传递集合,同时保证它不会被修改。
我使用的 IIterator 接口是基于 Java 迭代器,但我没有实现remove()方法,因为这在Java社区中被许多人认为是一个设计错误,因为它允许用户删除数组元素。 下面是我的 IIterator 实现:
然后由 ArrayIterator、VectorIterator 等类实现。
为了方便起见,我还在具体的 Iterator 类上扩展了 Proxy,并为for-each 在 AS3 中通过重写 nextNameIndex() 和 nextValue() 方法进行循环。 这意味着在使用我的IIterator时,通常使用数组的代码不需要更改。
唯一的问题是...用户无法查看 IIterator 接口并知道他们可以使用 for-each 循环来迭代集合。 他们必须查看 ArrayIterator 的实现才能看到这一点。
It seems that using an Iterator pattern is the best way currently in AS3 to pass a collection around a system, while guaranteeing that it will not be modified.
The IIterator interface I use is modeled on the Java Iterator, but I do not implement the remove() method, as this is considered a design mistake by many in the Java community, due to it allowing the user to remove array elements. Below is my IIterator implemention:
This is then implemented by classes such as ArrayIterator, VectorIterator etc.
For convenience I also extend Proxy on my concrete Iterator classes, and provide support for the for-each loops in AS3 by overriding the nextNameIndex() and nextValue() methods. This means code that typically used Arrays does not need to change when using my IIterator.
Only problem is... there is no way for the user to look at the IIterator interface and know that they can use a for-each loop to iterate over the collection. They would have to look at the implementation of ArrayIterator to see this.
有些人会认为,您可以将此类模式实现为库,这一事实是反对向语言本身添加功能的论据(例如,C++ 语言设计者通常这么说)。
Some would argue that the fact that you can implement such patterns as libraries is an argument against adding features to the language itself (for example, the C++ language designers typically say that).
您是否通过代理对象获得了您想要的不变性? 请注意,您可以让 VectorIterator 构造函数采用强制的 Class 参数。 诚然,目前这对设计师来说并不友好,但我们希望未来情况会有所改善。
Do you have the immutability you want via the proxy object or not? Note, you can have the VectorIterator constructor take a mandatory Class parameter. Admittedly this is not designer friendly at the moment, but lets hope things will improve in the future.
我为 AS3 创建了一个小型的不可变集合类库,其中包括一个类型化的有序列表,听起来它可以满足您的需求。 请参阅此博文了解细节。
I have created a small library of immutable collection classes for AS3, including a typed ordered list, which sounds like it would meet your needs. See this blog post for details.
为了实现这一目标,我所做的就是让维护列表的类仅通过
slice()
。 例如,我的游戏引擎有一个类Scene
,它维护已添加到其中的所有Beings
的列表。 然后,该列表将作为副本公开,如下所示:(抱歉,要恢复旧线程,我在寻找方法来准确实现 Brian 的答案所涵盖的内容时遇到了这个问题,并认为我会在此事上投入 2 美分)。
Something I do to achieve this is to have the class that maintains the list only return a copy of that list in a getter via
slice()
. As an example, my game engine has a classScene
which maintains a list of all theBeings
that have been added to it. That list is then exposed as a copy like so:(Sorry to revive an old thread, I came across this while looking for ways to implement exactly what Brian's answer covers and thought I would throw my 2 cents in on the matter).