Immutable Collections Actionscript 3

穿精又带淫゛_ 提交于 2019-12-03 12:30:04

问题


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?


回答1:


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:

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

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.

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)
}

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.




回答2:


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).




回答3:


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.




回答4:


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.




回答5:


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 class Scene which maintains a list of all the Beings that have been added to it. That list is then exposed as a copy like so:

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

(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).



来源:https://stackoverflow.com/questions/599825/immutable-collections-actionscript-3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!