ActionScript 3 中的对象序列化

    我们都知道对象序列化的目的是为了对象能够在网络上传输,以便存储对象,这是很有用处的,比如一个在线Flash游戏,玩家玩到一半想明天再玩,这时需要通过对象序列化把游戏数据保存起来,不然关闭浏览器数据就都没了,又要从头开始,当然利用Flash中的LSO也可以进行存储数据,不过是存在客户端上,这样的数据不一定能持久,对象序列化的主要目的是保存到服务器的数据库里,也许有人会问,干嘛不把对象的属性直接保存到数据库,还这么麻烦饶一大圈,这当然可以,但是如果对象的属性非常多,写起来会不会很繁琐呢,不如直接把对象保存起来这样反而跟简便,对象序列化的原理是把对象转换为字符串的形式,因为字符串任何语言都认识都能处理,而对象类型只能是属于特定的语言,比如一个Rectangle实例有width,height,fillColor,lineColor属性,把它转换为字符串格式后:"width=value|height=value|fillColor=value|lineColor=value"。
    ActionScript 3本身并没有提供对象序列化的APIs,因为它已经有了flash remoting(AMF协议),AMF协议完成对象的序列化和反序列化,这里我们先不谈AMF,看看如何自定义实现对象的序列化,OReilly.Essential.ActionScript.3.0的作者提供了一系列类和接口来实现对象序列化,我们看看他是如何做的:

定义了一个 Serializable接口,只声明一个方法用于对象的序列化:
package  serializer
{
    
public interface Serializable
    
{
        function serialize():String;
    }

}

定义一个 实现 Serializable接口的 Serializer类,用于完成对象
package  serializer
{
    
public class Serializer implements Serializable
    
{
        
private var serializationVars:Array; //存储对象的属性
        
private var serializationObj:Serializable; //指向可序列化的对象引用
        
private var recordSeparator:String; //指定属性之间的分隔符
        
        
public function Serializer(){
            setSerializationObj(
this);
        }

        
public function setSerializationVars(vars:Array):void{
            serializationVars 
= vars;
        }

        
public function setSerializationObj(obj:Serializable):void{
            serializationObj 
= obj;
        }

        
public function setRecordSeparator(rs:String):void{
            recordSeparator 
= rs;
        }

        
public function serialize():String
        
{
            var s:String 
= "";
            
for (var i:int = serializationVars.length; -->= 0;){
                s 
+= serializationVars[i] + "=" + String(serializationObj[serializationVars[i]]);
                
if(i>0){
                    s 
+= recordSeparator;
                }

            }

            
return s;
        }

        
    }

}

一个继承 Serializer的Point类,我们将对Point类实例进行序列化处理:
package  serializer
{
    
public class Point extends Serializer
    
{
        
public var x:Number;
        
public var y:Number;
        
public var name:String = "Point";
        
        
public function Point(x:Number,y:Number)
        
{
            
super();
            setRecordSeparator(
","); //设置分隔符
            setSerializationVars([
"x","y"]); //序列化x,y属性
            
this.x = x;
            
this.y = y;
        }

        
    }

}

测试类,输出结果为: y=6,x=5
package
{
    
import flash.display.Sprite;
    
import serializer.Point;
    
import serializer.Rectangle;
    
import serializer.Rectangle;

    
public class TestSerialization extends Sprite
    
{
        
public function TestSerialization()
        
{
            
super();
            var p:Point 
= new Point(5,6);
            trace(p.serialize());     

        }

        
    }

}

我们看到已经成功把Point对象变成字符串“y=6,x=5”,我们再来看一个例子:

Shape类,定义了两个属性fillColor,lineColor:
package  serializer
{
    
public class Shape
    
{
        
public var fillColor:uint = 0xFFFFFF;
        
public var lineColor:uint = 0;
        
        
public function Shape(fillColor:uint,lineColor:uint){
            
this.fillColor = fillColor;
            
this.lineColor = lineColor;
        }

    }

}

Rectangle类继承Shape,同时实现 Serializable接口:
package  serializer
{
    
public class Rectangle extends Shape implements Serializable
    
{
        
public var width:Number = 0;
        
public var height:Number = 0;
        
public function Rectangle(fillColor:uint, lineColor:uint)
        
{
            
super(fillColor, lineColor);
        }

        
public function setSize(w:Number,h:Number):void{
            width 
= w;
            height 
= h;
        }

        
public function getArea():Number{
            
return width*height;
        }

        
public function serialize():String
        
{
            var ser:Serializer 
= new Serializer();
            ser.setRecordSeparator(
"|");
            ser.setSerializationVars([
"height","width","fillColor","lineColor"]);
            ser.setSerializationObj(
this);
            
return ser.serialize();
        }

        
    }

}
 
一个类要想能够被序列化,要么实现 Serializable接口,要么继承已经实现 Serializable接口的类,因为Rectangle类的父类没有实现 Serializable接口,所以Rectangle类必须实现 Serializable接口,而上面那个Point类的父类已经实现 Serializable接口,等于是间接实现了,我们看到Rectangle类的serialize()方法,把Serializer当作序列化工具,对Rectangle对象进行序列化处理,  对于核心类Serializer作者设计的比较巧妙,能同时处理两种情况的序列化。
    最后还是要说一下一个小问题,假如序列化后的字符串保存到数据库了,再读取进行反序列化时,该怎么知道这些字符串是什么类的呢??? 我的想法是在序列化时同时保存类名以便为反序列化做准备,拿Point例子来说:
增加一个属性代表类名:
package  serializer
{
    
public class Point extends Serializer
    
{
        
public var x:Number;
        
public var y:Number;
        
public var name:String = "Point";
        
        
public function Point(x:Number,y:Number)
        
{
            
super();
            setRecordSeparator(
",");
            setSerializationVars([
"x","y","name"]);
            
this.x = x;
            
this.y = y;
        }

        
    }

}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值