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將識別索引轉成列舉實體,在溝通上會方便許多
參考文章
0 意見 :: [教學]在AS3中使用列舉
張貼留言