Actionscript 3本身沒有列舉,所以在開發Flash專案時大都以常數宣告成整數或字串的方式來區分類別,雖然不會有問題,但在開發大型專案時,常數的宣告方法反而會成為維護上的大問題。
舉例來說,一般Flash中重覆使用變數會宣告成:
public class MoveDirection
{
public static const UP:int = 0;
public static const DOWN:int = 1;
public static const LEFT:int = 2;
public static const RIGHT:int = 3;
public function MoveDirection()
{
}
}
假設在使用時以 function changeDirection(directionType:int):void 的方式調用,雖然使用上沒問題,但如果今天把程式碼交接給別人,在交接不清楚的情況下,directionType到底要填什麼才好,因為型態是int,所以只要是整數都可以填,在求快的情況下,有人可能就會直接填入1, 2, 3, 4,程式碼最後就充滿了魔術數字,愈來愈難維護。
為了避免上述問題,Adobe在文件上有提出一個簡單的作法,使用宣告自己的方式來固定型別,上面的程式可改寫成:
public class MoveDirection
{
public static const UP:MoveDirection = new MoveDirection();
public static const DOWN:MoveDirection = new MoveDirection();
public static const LEFT:MoveDirection = new MoveDirection();
public static const RIGHT:MoveDirection = new MoveDirection();
public function MoveDirection()
{
}
}
在使用時會變成 function changeDirection(directionType:MoveDirection):void ,型態固定了,即使沒有說清楚也可以知道要填入什麼,也不必憺心會被順便亂填, 但這方法還是有問題,如果今天我的directionType是Server告訴我,而類型是以整數方式記載,那我要怎麼換成Client看得懂的列舉,這個方法沒有處理資料轉換的問題,在溝通上還是很難用,所幸網路上還是有不錯的第三方可用,as3Commons就有提供更完整的列舉類。
筆者自已也寫了一個簡單的列舉類別,功能簡單但有實作自動遞增
package idv.gd.utils
{
import flash.utils.Dictionary;
import flash.utils.getQualifiedClassName;
import flashx.textLayout.formats.Direction;
public class Enum
{
private static var _enums:Dictionary = new Dictionary();;
private var _id:Object;
public function Enum(id:Object = null)
{
var className:String = getQualifiedClassName(this);
if (!_enums[className])
_enums[className] = new Dictionary();
if (id == null)
{
id = largestID + 1;
if (id > uint.MAX_VALUE)
throw new Error("id超過最大值");
}
_id = id;
if (!_enums[className][id])
_enums[className][id] = this;
else
throw new Error("id值已存在");
}
/**
* 取得目前最大值索引
* @return
*
*/
private function get largestID():uint
{
var className:String = getQualifiedClassName(this);
var maxValue:uint = 0;
var values:Dictionary = _enums[className];
if (values)
{
for each (var enum:Enum in values)
{
var enumID:uint = enum.idToUint();
if (enumID > maxValue)
maxValue = enumID;
}
}
return maxValue;
}
/**
* 取得id物件
* @return
*
*/
public function get id():Object
{
return _id;
}
/**
* 依id取得列舉實體
* @param enumClass 要轉換的列舉類別
* @param id 識別id
* @return
*
*/
public static function getEnumByID(enumClass:Class, id:Object):*
{
var className:String = getQualifiedClassName(enumClass);
var currentValues:Dictionary = _enums[className];
return (currentValues) ? currentValues[id] : null;
}
/**
* id轉字串
* @return
*
*/
public function idToString():String
{
return String(_id);
}
/**
* id轉正整數
* @return
*
*/
public function idToUint():uint
{
return uint(_id);
}
}
}
使用上可以寫成:
public class MoveDirection extends Enum
{
public static const UP:MoveDirection = new MoveDirection();//1
public static const DOWN:MoveDirection = new MoveDirection();//2
public static const LEFT:MoveDirection = new MoveDirection();//3
public static const RIGHT:MoveDirection = new MoveDirection();//4
public static const UP_LEFT:MoveDirection = new MoveDirection(1000);//1000
public static const UP_RIGHT:MoveDirection = new MoveDirection();//1001
public static const DOWN_LEFT:MoveDirection = new MoveDirection();//1002
public static const DOWN_RIGHT:MoveDirection = new MoveDirection();//1003
public function MoveDirection(id:Object=null)
{
super(id);
}
}
索引也可為字串,但最好不要把數字跟字串混在同一類別,底層有實作轉換,可使用getEnumByID將識別索引轉成列舉實體,在溝通上會方便許多
參考文章
沒有留言:
張貼留言