分享
 
 
 

设计良好的FLASH项目架构1-单例模式

王朝other·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

单例模式(Singleton)确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例单例模式。单例模式只应在有真正的“单一实例”的需求时才可使用

为什么要在FLASH中使用单例模式?

首先我们明白,"单例"-即在软件运行时只提供一个实例,大家知道在面向对象编程中,实例化一个对象就意味着需要在内存中开辟一单元供这个对象的实例使用.而经常的,我们编写的一个类或函数需要在系统的很多地方被引用,不得已我们每次都需要去获取这个类的实例以供使用.以至于我们要不断的去new一个对象,如此一来,不但给系统增加负担,而且会给用户带来坏的使用体验-.

就象我们制作一个工具,我们希望完成后,在以后随时随地我们都可以很方便地拿出这个工具来协助我们工作.而不是每次需要使用这个工具的时候都需要花时间花力气去重新制作这个工具.

在FLASH中使用单例模式的目的即是如此.但是首先需要明确:

1,这个工具是我们经常使用的.

2,这个工具必须可以灵活使用,而不是就单针对着特定的某一件工作.正确的说,这个工具可以应付我同一类型的一系列工作,而不是异想天开的替我解决所有问题.

3,不要让其他人使用这个工具,确保这个工具的专利属于我.

在FLASH中什么情况适合使用单例模式?

在具备以下的需求时,我们可以考虑使用单例模式:需要一个通用的业务逻辑处理器来处理同一类型的工作任务,需要一个数据访问对象来处理一系列的外部数据交互工作,前提是使用一致的数据访问手段.

由于FLASH是基于客户端的软件,客户端基本上就是一个人在使用,所以我们可以忽略通常在软件设计中需要考虑的线程并发问题(在B/S,C/S架构的系统中,通常这些任务由服务器来做).而且,虽然FLASH本身是多线程的,但是它并没有允许我们编程控制线程.

因此,我们在FLASH中使用单例模式的好处就是:节约系统开销,增大代码重用性.其实最大的好处就仅是节约系统开销而已.至于代码重用我们可以基于自身对软件设计的经验使用各种方式做到.

一个基本的单例模式:

class SingletonClass{

private static var singletonClass:SingletonClass = null;

private function SingletonClass{}

public static function getInstance():SingletonClass{

if(singletonClass == null){

SingletonClass.singletonClass = new singletonClass();

}

return singletonClass;

}

}

在第一行代码.我们申明了一个静态(static)的变量,他的类型为SingletonClass类本身.既然申明的变量为static,那么在程序运行期间这个变量将会长驻在内存中而不会自动销毁

第二行代码,我们写了一个空的构造函数,而且它是私有的(private),这意味着这个类不可以在外部被实例化,这也正是我们的目的.(我们专利的工具将不会被外人模仿使用)

在 getInstance方法中,我们通过判断singletonClass的值是否为null来取决是否需要实例化singletonClass.第一次将singletonClass实例化以后,之后将不需要再实例化singletonClass.最后,这个方法将会返回一个SingletonClass实例的引用-singletonClass

看到这里,相信大家都已经明白单例模式的构成原理

下面我们来做一个应用单例模式的DEMO

我们将做一个用户信息查询的模块,应用单例模式主要的目的是保证在用户活动过程中,相关用户信息的外部数据调用工作只做一次.

考虑到设计良好的应用结构,我们将会稍微在单例模式的原则上做一些改动.我们将这一应用分为:用户模型,业务逻辑控制器,FLASH视图三部分,数据访问对象将会由FLASH内置的XML对象来充当(其实这种架构是参考常用的B/S软件结构来设计,从实际B/S系统结构的原则上讲,整个FLASH应用程序都只将作为表示层).

代表用户实体的类

MemberEntry.as

class com.hizon.domain.MemberEntry{

private var id:Number;

private var email:String;

public function getId():Number{

return id;

}

public function setId(id:Number):Void{

this.id = id;

}

public function getEmail():String{

return email;

}

public function setEmail(email:String):Void{

this.email = email;

}

}

member.xml

xml version="1.0" encoding="gbk"?>

<root>

<id>1id>

<email>bhlove@gmail.comemail>

root>

负责数据访问的类

MemberDao.as

import com.hizon.domain.MemberEntry;

class com.hizon.dao.MemberDao{

private static var memberEntry:MemberEntry = null;

private function MemberDao(){}

public static function initMemberEntry(memberId:Number,event:Function):Void{

if(MemberDao.memberEntry == null){

var memberProfileDoc:XML = memberProfileDoc = new XML();

memberProfileDoc.ignoreWhite = true;

memberProfileDoc.load("xml/member.xml");

memberProfileDoc.onLoad = function (success){

MemberDao.memberEntry = new MemberEntry();

MemberDao.memberEntry.setId(memberProfileDoc.firstChild.childNodes[0].firstChild.nodeValue);

MemberDao.memberEntry.setEmail(memberProfileDoc.firstChild.childNodes[1].firstChild.nodeValue);

event.call(MemberDao,MemberDao.memberEntry);

return;

}

}

event.call(MemberDao,MemberDao.memberEntry);

}

}

在Flash中进行用户信息打印

import com.hizon.dao.MemberDao;

import com.hizon.domain.MemberEntry;

MemberDao.initMemberEntry(1,init);

function init(mb:MemberEntry){

trace(mb["email"]);

}

在这里,我们使用了Function对象的call方法,也许你会问,为什么不在MemberDao里直接返回一个MemberEntry对象?

原因是这样的,在FLASH中的所有基于http协议的外部数据调用工作都是异步进行的(而且,FLASH没有提供线程控制编程).这样直接导致的结构就是:当数据调用还没完成的时候,AS脚本已经获取了return值,当然,这个值会是null

所以,我认为最好的方法就是将函数作为参数传递给方法,由方法在完成XML数据调用后执行目标函数.如果大家有更好的方法,希望不啬指教.

最后将一下我的设计思路吧

基于面向对象的设计原则(仿照JAVA设计模式).我使用了MemberEntry这个类作为用户的实体参照对象.这样在以后更多的业务逻辑中,如果我想获取/更新用户资料,我只需要针对这个对象进行get/set方法操作.然后由专门的类根据需求负责处理MemberEntry

例如:

负责向服务器提交数据的类

class com.hizon.web.Poster{

public function post(url:String,entry:Object,listener:Function){

var poster:LoadVars = new LoadVars();

var result_v:LoadVars = new LoadVars();

for(var name in entry){

poster[name] = entry[name];

}

poster.sendAndLoad(url,result_v,"POST");

result_v.onLoad = function (success:Boolean){

if(success){

listener.call(Poster);

}

}

}

}

这样,我只要将标准格式的实体对象作为参数交由Poster类处理,即可完成向服务器提交数据更新的工作.而不需要在多处编写POST代码.

其次,我使用了单例模式的原则,保证外部数据调用工作只做一次

最重要的,我把代码根据业务逻辑进行了分离.使各个部分都能够各司其职,保证了程序结构的清晰,增大了代码可重用性

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有