Profil de 影欢迎进入飞影 的 圣域PhotosBlogListesPlus ![]() | Aide |
|
|
2009-10-11 转载的,搞笑的
1、 早上临上班,和老公吻别。 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 花木兰从军。。。 一天打仗的时候月经来了,正要换卫生巾,突然一个炮弹打过来。她就昏了过去。。。。当她醒来时已经在手术台上了。。。。医生说“。你没事吧?!!!”花木兰说:“怎么了??,我没事呀”。。。。“这还叫没事。。命根子都让炸去了还没事?!!”
2008-09-14 love to be loved by you---<我愿意你爱我或者我喜欢被你爱着>love to be loved by you 中英文歌词. 歌曲中文意思为 <我愿意你爱我或者我喜欢被你爱着> I can′t believe I′m standing here 我不敢相信我一直在这里等了这么多年 中文歌词大意 艺术人生艺术人生(一)
鄙人特喜欢音乐,且不论听,唱,都是注入了感情的!我内心的各种情感都能与好些类音乐产生共鸣,{第一次听到<德国战车>乐队的音乐,我整个人都热血沸腾起来,很来径,主唱的高大,及从他胸腔蓄气到喉咙发出来的声音,那种感觉,就二字"震撼"!!!}但通俗流行歌曲例外,如国内比较流行的:以爱为主打歌,经常都爱得死去活来的,听着都腻了!拜托!唱这些流行歌的艺人们,咱门人是有感情的,生活中能随时充满着爱,固然挺好,但我们人的一生经历感悟广泛,不只是爱,还有其他类型的情感元素啊!我们的情感主要有两大类:积极向上的与消极不悦的,譬如::高兴,悲哀,痛苦,烦闷,焦虑,忧郁;生活中的得失,对大自然的向往---或以战争地区平民视角来唱出他们的感受,也有激励向上的朋客类,歌颂生灵的歌特史诗类.....反正唱出咱们人生在世的方方面面,这些都可以用音乐加以修饰!个人觉得音乐的价值变在于此!{纯粹个人体会:所谓艺术,是人们以各种符合咱们人的欣赏形式来含蓄的表达,从各个角度,层面去描述咱们人世社会的方方面面,写到此处,我甚至觉得,艺术是表达我们人类的历史的灵魂!若有谁能以艺术的形式去展现一个文明的历史的话,那此人才真的叫HI/NB/牛} 听音乐 能调节心情,各类音乐能满足心理变化的需求 唱歌 更能释放自己压抑的内心,某种层面来讲,能给予人满足感!!
我发觉我早上嗓子不错,清脆,犀利的感觉,语气很轻的就能唱出高音调子来,真的!!但平时上火时,我嗓子一点都不好,甚至是沙哑的,有点像声带发育不健全样,也许这跟我鼻炎有关吧!!!
-----{怎么感觉我的写作方式有点怪异呢???!!!}
2008-07-13 憨态聪慧的WALL·E--(2008)机器人总动员WALL·E(2008) 瓦力 .....台湾译名
Wall-E Jim Capobianco .....titles
机器人总动员WALL·E(2008)--- 这影片虽然演的是机器人,却有着非常浪漫动人的爱情故事!!!我推荐5颗*****,大家快去观赏观赏吧!!我是看得眼含湿润了的!!! 特感人! 我总结这类情节叫:源自前卫&古典的非正统的浪漫形式!!!! 一个孤独的在地球处理垃圾几百年了的 “男主角”—瓦力WALL-E,外表憨态可掬,一双炯炯有神的眼睛让人难以把它再当作一堆“废铁机器人”! 另一个来自未来,一个超级前卫的“女主角伊芙”,无论是无缝链接的外观还是所展现的科技!!! 也是眼睛特有魅力!两歌闪烁着天蓝色光芒的“圈圈”,随着“心情”变化而闪烁变化着,无不随时散发出一种无比卡哇伊的,一种让男人见了就无法忘怀的女人味道!!!
影片故事发生在2700年,由于人类无度的破坏环境,地球此时已经成为漂浮在太空中的一个大垃圾球,人类不得已移居到太空船上,并且聘请Buynlarge公司清除地球上的垃圾,等待着有一天垃圾清理完重新回到地球上。
于是Buynlarge公司向地球运送了大量机器人来捡垃圾,但是这种机器人并不适合地球的环境,渐渐的都坏掉了,最后只剩下一个机器人还在日复一日的按照预定程序捡垃圾。显然这是个不可能完成的任务。就这么过了几百年,机器人收集了不少人造的物品,其中最让它喜欢的是一盒录像带——芭芭拉·史翠珊主演的歌舞片《你好,多莉!》(Hello, Dolly !)!
随着时间的流逝,这个孤独的机器人开始有了自我意识,它渴望有人来陪陪它。有一天一艘飞船差点落在它头顶,一个漂亮的女机器人Eve来到地球负责搜索一些东西,捡垃圾的机器人“爱”上了Eve,但是它面临着抉择,是随着Eve和飞船离开地球,还是继续按照预设的指令把垃圾捡下去。当然它最后选择和Eve一起离开,飞向太空,不过好戏才刚刚开始……
影片片名“WALL-E”是一个缩写,全称为“Waste Allocation Load Lifters - Earth”,就是Buynlarge公司派往地球捡垃圾的那些机器人的官方称呼。另外这部影片中还会出现真人演员佛莱德·威拉德(Fred Willard),他将扮演Buynlarge公司总裁,在动画片中出现真人,这在皮克斯也是首次。
让我们随着影片进入一个离我们并不是十分遥远的星系,那里有一个毅然决绝的机器人,顽固且执着地守护着被人类遗弃的地球,已经有几百年的时间了……2700年,地球早就被人类祸害成了一个巨大的垃圾场,已经到了无法居住的地步,人类只能大举迁移到别的星球,然后委托一家机器人垃圾清理公司善后,直至地球的环境系统重新达到生态平衡。
在人类离开之后,垃圾清理公司将机器人WALL·E成批地输送到地球,并给他们安装了惟一的指令--垃圾分装,然而随着时间的推移,机器人一个接一个地坏掉,最后只剩下惟一的一个,继续在这个似乎已经被遗忘了的角落,勤勤恳恳地在垃圾堆中忙碌着,转眼就过去了几百年的时间,寂寞与孤独变成了围绕着他的永恒的主题。
然而,一艘突然而至的宇宙飞船打破了这里的平静,它还带来了专职搜索任务的机器人伊芙,当WALL·E经历了几百年的孤独,终于见到了另一个机器人时,他觉得自己好像爱上她了……伊芙在经过了精确的计算之后,数据显示出,看起来漫不经心的WALL·E很可能是关乎着地球未来的关键所在,她通过宇宙飞船将自己的发现报告给人类,收到了将WALL·E带离地球的指令--人类正想尽办法重回地球,所以他们不会放弃任何可能的机会。于是,WALL·E追随着伊芙,展开了一次穿越整个银河系、最令人兴奋、也是最具有想象力的奇幻旅程。 飞影的豆瓣
2008-04-24 (转载)MXML--电子工业出版社《完全手册--Flex3.0 RIA开发详解:基于ActionScript3.0实现》Flex技术架构:
![]() 以下是Flex三个典型应用:
![]() ![]() ![]() MXML--电子工业出版社《完全手册--Flex3.0 RIA开发详解:基于ActionScript3.0实现》-----》
![]() 本书前言
Flash的难题 传统的HTML应用程序功能单一、人机交互性差、安全性能不高。随着RIA(Rich Internet Application)技术的不断发展,Web开发有了新的发展分支,即包含丰富用户体验的应用程序。 最早的RIA应用程序大多由Flash开发工具制作。RIA程序的效果非常理想,且可运行于不同平台中,但Flash工具的特点决定了它不适合开发中大型RIA程序。其一,Flash工具是专业用于制作动画的开发平台,适合于开发时间逻辑较强的程序,但并不适合于开发业务逻辑复杂的程序。其二,Flash工具倡导DIY精神,只提供最基础的组件,所以几乎所有的任务都要自行完成。 Flex横空出世 Flex技术的出现解决了Flash技术的大部分问题。使用Flex技术开发部署RIA应用程序非常简单。由于Flex技术基于MXML标准、CSS标准、XML标准、ActionScript 3.0标准,所以开发过程更规范、应用程序更容易扩展。Flex技术中提供丰富的组件,使得Flex开发人员只需将注意力集中于业务逻辑开发上。另外,Flex编程是面向对象的编程,开发过程与大部分编程语言相似,所以其他语言开发人员可较容易地理解和掌握Flex。从Google趋势(http://www.google.cn/trends?q=fl ... geo=CN&date=all)上可以看出Flex发展迅猛,如下图所示, ![]() 为了帮助初学者入门和掌握Flex技术,本人翻阅了大量英文文档,编写了大量实例代码,花费大约半年时间编写此书。本书全面地介绍了Flex技术,并以实例介绍了如何使用Flex技术开发应用程序。通过本书的学习,读者能够了解和掌握Flex开发技巧,具有一定的开发实践能力。 本书的特点 1.提供完善的售后服务:为了帮助大家学习Flex,我们为广大读者建立专门的讨论区,网址为www.rzchina.net。广大读者可以和作者进行对Flex技术进行讨论。 2.循序渐进,由浅入深:为了方便读者学习,本书首先让读者了解什么是Flex,使用什么工具开发,并详细介绍第一个Flex应用程序的开发过程。读者可通过第一个Flex程序,逐步了解和熟悉Flex技术的开发过程、开发技巧。本书先介绍ActionScript 3.0语言的语法,后介绍Flex组件开发、美化界面、数据传输、开发框架等内容,最后以综合实例帮助读者学习Flex技术。 3.技术全面,内容充实:本人花费2~3个月时间进行前期准备,详细分析了现行Flex技术及相关技术的特点和实例应用。全书包含Flex常用的各种技术和工具,如Flex Builder 3、LiveCycle Data Services、Cairngorm、Flex-Ajax Bridge,以及与这些技术的结合。 4.案例精讲,深入剖析:根据本人多年的项目经验和对Flex技术的深入研究,认为学习Flex技术的捷径在于多看多实践,所以本书中为每个知识点都提供实例代码。读者通过分析和理解代码及代码解释,可以更快地掌握Flex技术中的知识点和开发技巧。本书在实例代码中提供详细的注释,对有特殊用法或含义的代码进行详细阐述。 5.综合实例,灵活应用:本书最后三章分别介绍了Flex播放器实例、CairngormStore实例和视频分享网站。这三个实例都具有一定的代表性。通过Flex播放器实例,读者可以学习和掌握如何在Flex中控制视频和音频。CairngormStore实例是一个简单的在线购物网站。而视频分享网站是Flex现在最成功的商业应用。读者通过此实例地学习可了解和掌握如何使用Flex开发中大型的应用程序。 6.配有光盘,加速学习:本书配套光盘中包含书中全部实例的工程源代码,读者可以方便地学习和参考。查看和分析大量源代码能快速、有效地提高Flex编程能力,掌握开发技巧。 本书目录: 第1篇 基础篇 第 1章 Flex概述2 第 2章 熟悉开发环境Flex Builder 317 第2篇 ActionScript 3.0语法篇 第 3章 ActionScript 3.0基础30 第 4章 数据类型38 第 5章 运算符和表达式51 第 6章 程序设计的基本结构64 第 7章 函数83 第 8章 面向对象基础94 第 9章 数字处理106 第 10章 日期与时间114 第 11章 字符串122 第 12章 数组136 第 13章 使用XML160 第3篇 组件篇 第 14章 使用组件构建Flex界面176 第 15章 Flex 3.0界面设计实战186 第 16章 自定义效果美化界面227 第 17章 CSS美化界面245 第 18章 Flex美化应用305 第4篇 数据篇 第 19章 Flex中的数据处理360 第 20章 使用正则表达式匹配字符串数据389 第 21章 数据传输与交互402 第5篇 扩展篇 第 22章 Cairngorm开发框架440 第 23章 Flex 3.0新特性的应用473 第6篇 实例篇 第 24章 FLV播放器516 第 25章 经典实例CairngormStore的分析543 (转载)给80后男生找老婆的几点建议给80后男生找老婆的几点建议 文章提交者:yehena 加贴在 情感论坛 铁血论坛 http://bbs.tiexue.net/bbs_159.html 80后出生的孩子,基本上都是独生子女,在这个年代出生,正是遇上改革开放的大好时光,老百姓的日子是芝麻开花-——节节高,所以这时的他们在生活上都用不着象六七十年代还要考虑到温饱问题,家境的逐渐殷实,使80后的孩子个个都被宠成了小皇帝、小公主。
一直在温室中在父母双翼中呵护成长起来的这些小皇帝、小公主,到了也要谈婚论嫁的时候才突然傻眼了,问题严重起来了,为啥?原来跟他们同年代出生的80后女生,不是被六七十年代的老男人霸占着,就是向你要房要车要彩礼……..而这些让刚刚步入社会的80后男生显然是心有余而力不足。
于是有人疾呼,80后的男生咱这么命苦啊? 60后,70后一代的人可以享受着最后一批廉价房、福利房,可我们呢?没有!每天只得孤独的徘徊在各个楼市之前,盘算着到底是掏出80%还是90%的收入来换取20年的苦役宣判!这样的付出,到底在为谁买单?更可恶的是60年代出生的老男人凭着权力与金钱, 也将“魔爪”伸向80后女孩,使许多80后女孩成了“小姐”“二奶”“情妇”的“主力军”,再加上70年未出生的一代”钻石级”晚婚男人,择偶的目光也在锁定80后女孩身上,使本来就是男多女少的80后一代,出现了"僧多肉少"的尴尬局面,眼看着这样仅有的一点资源还要被六七十年代的那批黑心的爷们儿占去不少.无奈的80后男生只好面观90后女生了?倒,有的还没发育成熟,就算有些已经长大起来的90后女孩,但她们对于80后的表情却是不屑,她觉得你没什么,很一般,不足道,傻,笨,土,嫩,思想不开化,晕!此时80后男生表情是狂抓中~~~~~~~
但是老婆总是要娶的啊,就因为被六七十年代的老男人横刀夺爱,凭什么就要让80后的男生从此打上光棍的称号?
当然不是,其实这是一场勇气、才气与智慧的较量!
1:首先80后的男生你要培养出自己独特的个性来,也许你不是很帅,在经济与权力上也拼不过六七十年代的男人,但是,你可以展现你80后男生独有的个性和人格魅力! 因为大多数80后女生还是会选择比较有自己个性的男生,这样才能够展现80后的独特气质。
2:要有才,一个有才气的男人,无论走到哪都是吃香的, 80后的女生也特别欣赏那些有才的男生,也许你可以不够帅,不够酷,但只要你有才, 同样会得到80后女生的青睐。
3:有份固定的工作,一份固定的工作,不仅保障了你的经济来源,也让80后的女生对你产生一种安全感和可靠感. 虽然说新时代的女性自信独立了,但80后的女生一旦恋爱,一定也会是一付小女生的模样。而你的一份好工作让她感觉你就是这个家的大男人!
4:风趣,幽默,懂得疼爱女性. 对于这一点,应该是任何年龄阶段的女人重要的择偶标准之一,那么同样80后娇滴滴的女生,她们更需要这样一份体贴和关爱, 女人其实并不贪,只要你记得多哄哄,多疼疼,我想就算她有铁石心肠也会被打动的!
5:要有责任感,一个男人,如果没有了责任感,言语说得再动听也不会有人想去嫁给他! 只有有责任感的男人,才值得女人去托付终生。那么对于80后女生来说,同样如此了。
6:要学会做点家务,80后的女生,都是受过高等教育,,不可能象五六十年代出生的女性一样老老实实呆在家相夫教子,任劳任怨.经济上独立的她们,此时回到家更渴望与丈夫共同承担家务和料理孩子,不要求你天天做家务,但如果此时能吃上一顿老公亲手做的饭菜,那也将是一件非常幸福的事哦!
7:诚信,守实,感情要专一.一个好女孩,一个懂得欣赏男人的女人,那么她首先就是要看对方是否诚信,守实,对待感情是否专一?花心的男人,即使他的嘴上象抹了蜜一样的甜,也得不到真正的爱情. 因为对于女人来说,爱情里面是容不得一粒沙子的。
8:有一个好脾气,懂得谦让和宽容。80后男生为什么有时会抢不过六七十年代的男人呢?就是因为脾气表现得太过于急躁和虚浮,或许年龄和社会阅历的原因,80后男生还不能够很好的展现男人应有的成稳和风度。
当然,以上只是参考,没有一个男人能够如此的完美,全部符合。事实上,如果你够得上其中的二三条标准,你就已经称得上是一个新好男人了。呵呵,也一定会抢手哦!"天生我才必有用",加油吧,80后男生! 2008-03-25 蚁群算法ACO(ant colony optimization)的原理以及实现源代码
小小的蚂蚁总是能够找到食物,他们具有什么样的智能呢?设想,如果我们要为蚂蚁设计一个人工智能的程序,那么这个程序要多么复杂呢?首先,你要让蚂蚁能够避开障碍物,就必须根据适当的地形给它编进指令让他们能够巧妙的避开障碍物,其次,要让蚂蚁找到食物,就需要让他们遍历空间上的所有点;再次,如果要让蚂蚁找到最短的路径,那么需要计算所有可能的路径并且比较它们的大小,而且更重要的是,你要小心翼翼的编程,因为程序的错误也许会让你前功尽弃。这是多么不可思议的程序!太复杂了,恐怕没人能够完成这样繁琐冗余的程序。 为什么这么简单的程序会让蚂蚁干这样复杂的事情?答案是:简单规则的涌现。事实上,每只蚂蚁并不是像我们想象的需要知道整个世界的信息,他们其实只关心很小范围内的眼前信息,而且根据这些局部信息利用几条简单的规则进行决策,这样,在蚁群这个集体里,复杂性的行为就会凸现出来。这就是人工生命、复杂性科学解释的规律! 下面就是实现如此复杂性的七条简单规则: 1、范围: 下面的程序开始运行之后,蚂蚁们开始从窝里出动了,寻找食物;他们会顺着屏幕爬满整个画面,直到找到食物再返回窝。 其中,‘F’点表示食物,‘H’表示窝,白色块表示障碍物,‘+’就是蚂蚁了。 参数说明: 源代码如下: /*ant.c*/ #define SPACE 0×20 #define ESC 0×1b #define ANT_CHAR_EMPTY ‘+’ #define ANT_CHAR_FOOD 153 #define HOME_CHAR ‘H’ #define FOOD_CHAR ‘F’ #define FOOD_CHAR2 ‘f’ #define FOOD_HOME_COLOR 12 #define BLOCK_CHAR 177 #define MAX_ANT 50 #define INI_SPEED 3 #define MAXX 80 #define MAXY 23 #define MAX_FOOD 10000 #define TARGET_FOOD 200 #define MAX_SMELL 5000 #define SMELL_DROP_RATE 0.05 #define ANT_ERROR_RATE 0.02 #define ANT_EYESHOT 3 #define SMELL_GONE_SPEED 50 #define SMELL_GONE_RATE 0.05 #define TRACE_REMEMBER 50 #define MAX_BLOCK 100 #define NULL 0 #define UP 1 #define DOWN 2 #define LEFT 3 #define RIGHT 4 #define SMELL_TYPE_FOOD 0 #define SMELL_TYPE_HOME 1 #include “stdio.h” #include “conio.h” #include “dos.h” #include “stdlib.h” #include “dos.h” #include “process.h” #include “ctype.h” #include “math.h” void WorldInitial(void); void BlockInitial(void); void CreatBlock(void); void SaveBlock(void); void LoadBlock(void); void HomeFoodInitial(void); void AntInitial(void); void WorldChange(void); void AntMove(void); void AntOneStep(void); void DealKey(char key); void ClearSmellDisp(void); void DispSmell(int type); int AntNextDir(int xxx,int yyy,int ddir); int GetMaxSmell(int type,int xxx,int yyy,int ddir); int IsTrace(int xxx,int yyy); int MaxLocation(int num1,int num2,int num3); int CanGo(int xxx,int yyy,int ddir); int JudgeCanGo(int xxx,int yyy); int TurnLeft(int ddir); int TurnRight(int ddir); int TurnBack(int ddir); int MainTimer(void); char WaitForKey(int secnum); void DispPlayTime(void); int TimeUse(void); void HideCur(void); void ResetCur(void); /* ————— */ struct HomeStruct { int xxx,yyy; int amount; int TargetFood; }home; struct FoodStruct { int xxx,yyy; int amount; }food; struct AntStruct { int xxx,yyy; int dir; int speed; int SpeedTimer; int food; int SmellAmount[2]; int tracex[TRACE_REMEMBER]; int tracey[TRACE_REMEMBER]; int TracePtr; int IQ; }ant[MAX_ANT]; int AntNow; int timer10ms; struct time starttime,endtime; int Smell[2][MAXX+1][MAXY+1]; int block[MAXX+1][MAXY+1]; int SmellGoneTimer; int SmellDispFlag; int CanFindFood; int HardtoFindPath; /* —– Main ——– */ void main(void) { char KeyPress; int tu; clrscr(); HideCur(); WorldInitial(); do { timer10ms = MainTimer(); if(timer10ms) AntMove(); if(timer10ms) WorldChange(); tu = TimeUse(); if(tu>=60&&!CanFindFood) { gotoxy(1,MAXY+1); printf(“Can not find food, maybe a block world.”); WaitForKey(10); WorldInitial(); } if(tu>=180&&home.amount<100&&!HardtoFindPath) { gotoxy(1,MAXY+1); printf(“God! it is so difficult to find a path.”); if(WaitForKey(10)==0×0d) WorldInitial(); else { HardtoFindPath = 1; gotoxy(1,MAXY+1); printf(” “); } } if(home.amount>=home.TargetFood) { gettime(&endtime); KeyPress = WaitForKey(60); DispPlayTime(); WaitForKey(10); WorldInitial(); } else if(kbhit()) { KeyPress = getch(); DealKey(KeyPress); } else KeyPress = NULL; } while(KeyPress!=ESC); gettime(&endtime); DispPlayTime(); WaitForKey(10); clrscr(); ResetCur(); } /* —— general sub process ———– */ int MainTimer(void) /* output: how much 10ms have pass from last time call this process */ { static int oldhund,oldsec; struct time t; int timeuse; gettime(&t); timeuse = 0; if(t.ti_hund!=oldhund) { if(t.ti_sec!=oldsec) { timeuse+=100; oldsec = t.ti_sec; } timeuse+=t.ti_hund-oldhund; oldhund = t.ti_hund; } else timeuse = 0; return (timeuse); } char WaitForKey(int secnum) /* funtion: if have key in, exit immediately, else wait ’secnum’ senconds then exit input: secnum — wait this senconds, must < 3600 (1 hour) output: key char, if no key in(exit when timeout), return NULL */ { int secin,secnow; int minin,minnow; int hourin,hournow; int secuse; struct time t; gettime(&t); secin = t.ti_sec; minin = t.ti_min; hourin = t.ti_hour; do { if(kbhit()) return(getch()); gettime(&t); secnow = t.ti_sec; minnow = t.ti_min; hournow = t.ti_hour; if(hournow!=hourin) minnow+=60; if(minnow>minin) secuse = (minnow-1-minin) + (secnow+60-secin); else secuse = secnow - secin; /* counting error check */ if(secuse<0) { gotoxy(1,MAXY+1); printf(“Time conuting error, any keyto exit…”); getch(); exit(3); } } while(secuse<=secnum); return (NULL); } void DispPlayTime(void) { int ph,pm,ps; ph = endtime.ti_hour - starttime.ti_hour; pm = endtime.ti_min - starttime.ti_min; ps = endtime.ti_sec - starttime.ti_sec; if(ph<0) ph+=24; if(pm<0) { ph–; pm+=60; } if(ps<0) { pm–; ps+=60; } gotoxy(1,MAXY+1); printf(“Time use: %d hour- %d min- %d sec “,ph,pm,ps); } int TimeUse(void) { int ph,pm,ps; gettime(&endtime); ph = endtime.ti_hour - starttime.ti_hour; pm = endtime.ti_min - starttime.ti_min; ps = endtime.ti_sec - starttime.ti_sec; if(ph<0) ph+=24; if(pm<0) { ph–; pm+=60; } if(ps<0) { pm–; ps+=60; } return(ps+(60*(pm+60*ph))); } void HideCur(void) { union REGS regs0; regs0.h.ah=1; regs0.h.ch=0×30; regs0.h.cl=0×31; int86(0×10,®s0,®s0); } void ResetCur(void) { union REGS regs0; regs0.h.ah=1; regs0.h.ch=0×06; regs0.h.cl=0×07; int86(0×10,®s0,®s0); } /* ———— main ANT programe ————- */ void WorldInitial(void) { int k,i,j; randomize(); clrscr(); HomeFoodInitial(); for(AntNow=0;AntNow<MAX_ANT;AntNow++) { AntInitial(); } /* of for AntNow */; BlockInitial(); for(k=0;k<=1;k++) /* SMELL TYPE FOOD and HOME */ for(i=0;i<=MAXX;i++) for(j=0;j<=MAXY;j++) Smell[k][i][j] = 0; SmellGoneTimer = 0; gettime(&starttime); SmellDispFlag = 0; CanFindFood = 0; HardtoFindPath = 0; } void BlockInitial(void) { int i,j; int bn; for(i=0;i<=MAXX;i++) for(j=0;j<=MAXY;j++) block[i][j] = 0; bn = 1+ MAX_BLOCK/2 + random(MAX_BLOCK/2); for(i=0;i<=bn;i++) CreatBlock(); } void CreatBlock(void) { int x1,y1,x2,y2; int dx,dy; int i,j; x1 = random(MAXX)+1; y1 = random(MAXY)+1; dx = random(MAXX/10)+1; dy = random(MAXY/10)+1; x2 = x1+dx; y2 = y1+dy; if(x2>MAXX) x2 = MAXX; if(y2>MAXY) y2 = MAXY; if(food.xxx>=x1&&food.xxx<=x2&&food.yyy>=y1&&food.yyy<=y2) return; if(home.xxx>=x1&&home.xxx<=x2&&home.yyy>=y1&&home.yyy<=y2) return; for(i=x1;i<=x2;i++) for(j=y1;j<=y2;j++) { block[i][j] = 1; gotoxy(i,j); putch(BLOCK_CHAR); } } void SaveBlock(void) { FILE *fp_block; char FileNameBlock[20]; int i,j; gotoxy(1,MAXY+1); printf(” “); gotoxy(1,MAXY+1); printf(“Save to file…”,FileNameBlock); gets(FileNameBlock); if(FileNameBlock[0]==0) strcpy(FileNameBlock,“Ant.ant”); else strcat(FileNameBlock,“.ant”); if ((fp_block = fopen(FileNameBlock, “wb”)) == NULL) { gotoxy(1,MAXY+1); printf(“Creat file %s fail…”,FileNameBlock); getch(); exit(2); } gotoxy(1,MAXY+1); printf(” “); fputc(home.xxx,fp_block); fputc(home.yyy,fp_block); fputc(food.xxx,fp_block); fputc(food.yyy,fp_block); for(i=0;i<=MAXX;i++) for(j=0;j<=MAXY;j++) fputc(block[i][j],fp_block); fclose(fp_block); } void LoadBlock(void) { FILE *fp_block; char FileNameBlock[20]; int i,j,k; gotoxy(1,MAXY+1); printf(” “); gotoxy(1,MAXY+1); printf(“Load file…”,FileNameBlock); gets(FileNameBlock); if(FileNameBlock[0]==0) strcpy(FileNameBlock,“Ant.ant”); else strcat(FileNameBlock,“.ant”); if ((fp_block = fopen(FileNameBlock, “rb”)) == NULL) { gotoxy(1,MAXY+1); printf(“Open file %s fail…”,FileNameBlock); getch(); exit(2); } clrscr(); home.xxx = fgetc(fp_block); home.yyy = fgetc(fp_block); food.xxx = fgetc(fp_block); food.yyy = fgetc(fp_block); gotoxy(home.xxx,home.yyy); putch(HOME_CHAR); gotoxy(food.xxx,food.yyy); putch(FOOD_CHAR); food.amount = random(MAX_FOOD/3)+2*MAX_FOOD/3+1; /* food.amount = MAX_FOOD; */ home.amount = 0; home.TargetFood = (food.amount<TARGET_FOOD)?food.amount:TARGET_FOOD; for(AntNow=0;AntNow<MAX_ANT;AntNow++) { AntInitial(); } /* of for AntNow */; for(i=0;i<=MAXX;i++) for(j=0;j<=MAXY;j++) { block[i][j] = fgetc(fp_block); if(block[i][j]) { gotoxy(i,j); putch(BLOCK_CHAR); } } for(k=0;k<=1;k++) /* SMELL TYPE FOOD and HOME */ for(i=0;i<=MAXX;i++) for(j=0;j<=MAXY;j++) Smell[k][i][j] = 0; SmellGoneTimer = 0; gettime(&starttime); SmellDispFlag = 0; CanFindFood = 0; HardtoFindPath = 0; fclose(fp_block); } void HomeFoodInitial(void) { int randnum; int homeplace; /* 1 — home at left-up, food at right-down 2 — home at left-down, food at right-up 3 — home at right-up, food at left-down 4 — home at right-down, food at left-up */ randnum = random(100); if(randnum<25) homeplace = 1; else if (randnum>=25&&randnum<50) homeplace = 2; else if (randnum>=50&&randnum<75) homeplace = 3; else homeplace = 4; switch(homeplace) { case 1: home.xxx = random(MAXX/3)+1; home.yyy = random(MAXY/3)+1; food.xxx = random(MAXX/3)+2*MAXX/3+1; food.yyy = random(MAXY/3)+2*MAXY/3+1; break; case 2: home.xxx = random(MAXX/3)+1; home.yyy = random(MAXY/3)+2*MAXY/3+1; food.xxx = random(MAXX/3)+2*MAXX/3+1; food.yyy = random(MAXY/3)+1; break; case 3: home.xxx = random(MAXX/3)+2*MAXX/3+1; home.yyy = random(MAXY/3)+1; food.xxx = random(MAXX/3)+1; food.yyy = random(MAXY/3)+2*MAXY/3+1; break; case 4: home.xxx = random(MAXX/3)+2*MAXX/3+1; home.yyy = random(MAXY/3)+2*MAXY/3+1; food.xxx = random(MAXX/3)+1; food.yyy = random(MAXY/3)+1; break; } food.amount = random(MAX_FOOD/3)+2*MAX_FOOD/3+1; /* food.amount = MAX_FOOD; */ home.amount = 0; home.TargetFood = (food.amount<TARGET_FOOD)?food.amount:TARGET_FOOD; /* data correctness check */ if(home.xxx<=0||home.xxx>MAXX||home.yyy<=0||home.yyy>MAXY|| food.xxx<=0||food.xxx>MAXX||food.yyy<=0||food.yyy>MAXY|| food.amount<=0) { gotoxy(1,MAXY+1); printf(“World initial fail, any key to exit…”); getch(); exit(2); } gotoxy(home.xxx,home.yyy); putch(HOME_CHAR); gotoxy(food.xxx,food.yyy); putch(FOOD_CHAR); } void AntInitial(void) /* initial ant[AntNow] */ { int randnum; int i; ant[AntNow].xxx = home.xxx; ant[AntNow].yyy = home.yyy; randnum = random(100); if(randnum<25) ant[AntNow].dir = UP; else if (randnum>=25&&randnum<50) ant[AntNow].dir = DOWN; else if (randnum>=50&&randnum<75) ant[AntNow].dir = LEFT; else ant[AntNow].dir = RIGHT; ant[AntNow].speed = 2*(random(INI_SPEED/2)+1); ant[AntNow].SpeedTimer = 0; ant[AntNow].food = 0; ant[AntNow].SmellAmount[SMELL_TYPE_FOOD] = 0; ant[AntNow].SmellAmount[SMELL_TYPE_HOME] = MAX_SMELL; ant[AntNow].IQ = 1; for(i=0;i<TRACE_REMEMBER;i++) { ant[AntNow].tracex[i] = 0; ant[AntNow].tracey[i] = 0; } ant[AntNow].TracePtr = 0; /* a sepecail ant */ if(AntNow==0) ant[AntNow].speed = INI_SPEED; } void WorldChange(void) { int k,i,j; int smelldisp; SmellGoneTimer+=timer10ms; if(SmellGoneTimer>=SMELL_GONE_SPEED) { SmellGoneTimer = 0; for(k=0;k<=1;k++) /* SMELL TYPE FOOD and HOME */ for(i=1;i<=MAXX;i++) for(j=1;j<=MAXY;j++) { if(Smell[k][i][j]) { smelldisp = 1+((10*Smell[k][i][j])/(MAX_SMELL*SMELL_DROP_RATE)); if(smelldisp>=30000||smelldisp<0) smelldisp = 30000; if(SmellDispFlag) { gotoxy(i,j); if((i==food.xxx&&j==food.yyy)||(i==home.xxx&&j==home.yyy)) /* don’t over write Food and Home */; else { if(smelldisp>9) putch(‘#’); else putch(smelldisp+‘0′); } } Smell[k][i][j]-= 1+(Smell[k][i][j]*SMELL_GONE_RATE); if(Smell[k][i][j]<0) Smell[k][i][j] = 0; if(SmellDispFlag) { if(Smell[k][i][j]<=2) { gotoxy(i,j); putch(SPACE); } } } } /* of one location */ } /* of time to change the world */ } /* of world change */ void AntMove(void) { int antx,anty; int smelltodrop,smellnow; for(AntNow=0;AntNow<MAX_ANT;AntNow++) { ant[AntNow].SpeedTimer+=timer10ms; if(ant[AntNow].SpeedTimer>=ant[AntNow].speed) { ant[AntNow].SpeedTimer = 0; gotoxy(ant[AntNow].xxx,ant[AntNow].yyy); putch(SPACE); AntOneStep(); gotoxy(ant[AntNow].xxx,ant[AntNow].yyy); /* ant0 is a sepecail ant, use different color */ if(AntNow==0) textcolor(0xd); if(ant[AntNow].food) putch(ANT_CHAR_FOOD); else putch(ANT_CHAR_EMPTY); if(AntNow==0) textcolor(0×7); /* remember trace */ ant[AntNow].tracex[ant[AntNow].TracePtr] = ant[AntNow].xxx; ant[AntNow].tracey[ant[AntNow].TracePtr] = ant[AntNow].yyy; if(++(ant[AntNow].TracePtr)>=TRACE_REMEMBER) ant[AntNow].TracePtr = 0; /* drop smell */ antx = ant[AntNow].xxx; anty = ant[AntNow].yyy; if(ant[AntNow].food) /* have food, looking for home */ { if(ant[AntNow].SmellAmount[SMELL_TYPE_FOOD]) { smellnow = Smell[SMELL_TYPE_FOOD][antx][anty]; smelltodrop = ant[AntNow].SmellAmount[SMELL_TYPE_FOOD]*SMELL_DROP_RATE; if(smelltodrop>smellnow) Smell[SMELL_TYPE_FOOD][antx][anty] = smelltodrop; /* else Smell[…] = smellnow */ ant[AntNow].SmellAmount[SMELL_TYPE_FOOD]-= smelltodrop; if(ant[AntNow].SmellAmount[SMELL_TYPE_FOOD]<0) ant[AntNow].SmellAmount[SMELL_TYPE_FOOD] = 0; } /* of have smell to drop */ } /* of have food */ else /* no food, looking for food */ { if(ant[AntNow].SmellAmount[SMELL_TYPE_HOME]) { smellnow = Smell[SMELL_TYPE_HOME][antx][anty]; smelltodrop = ant[AntNow].SmellAmount[SMELL_TYPE_HOME]*SMELL_DROP_RATE; if(smelltodrop>smellnow) Smell[SMELL_TYPE_HOME][antx][anty] = smelltodrop; /* else Smell[…] = smellnow */ ant[AntNow].SmellAmount[SMELL_TYPE_HOME]-= smelltodrop; if(ant[AntNow].SmellAmount[SMELL_TYPE_HOME]<0) ant[AntNow].SmellAmount[SMELL_TYPE_HOME] = 0; } /* of have smell to drop */ } } /* of time to go */ /* else not go */ } /* of for AntNow */ textcolor(FOOD_HOME_COLOR); gotoxy(home.xxx,home.yyy); putch(HOME_CHAR); gotoxy(food.xxx,food.yyy); if(food.amount>0) putch(FOOD_CHAR); else putch(FOOD_CHAR2); textcolor(7); gotoxy(1,MAXY+1); printf(“Food %d, Home %d “,food.amount,home.amount); } void AntOneStep(void) { int ddir,tttx,ttty; int i; ddir = ant[AntNow].dir; tttx = ant[AntNow].xxx; ttty = ant[AntNow].yyy; ddir = AntNextDir(tttx,ttty,ddir); switch(ddir) { case UP: ttty–; break; case DOWN: ttty++; break; case LEFT: tttx–; break; case RIGHT: tttx++; break; default: break; } /* of switch dir */ ant[AntNow].dir = ddir; ant[AntNow].xxx = tttx; ant[AntNow].yyy = ttty; if(ant[AntNow].food) /* this ant carry with food, search for home */ { if(tttx==home.xxx&&ttty==home.yyy) { home.amount++; AntInitial(); } if(tttx==food.xxx&&ttty==food.yyy) ant[AntNow].SmellAmount[SMELL_TYPE_FOOD] = MAX_SMELL; } /* of search for home */ else /* this ant is empty, search for food */ { if(tttx==food.xxx&&ttty==food.yyy) { if(food.amount>0) { ant[AntNow].food = 1; food.amount–; ant[AntNow].SmellAmount[SMELL_TYPE_FOOD] = MAX_SMELL; ant[AntNow].SmellAmount[SMELL_TYPE_HOME] = 0; ant[AntNow].dir = TurnBack(ant[AntNow].dir); for(i=0;i<TRACE_REMEMBER;i++) { ant[AntNow].tracex[i] = 0; ant[AntNow].tracey[i] = 0; } ant[AntNow].TracePtr = 0; CanFindFood = 1; } /* of still have food */ } if(tttx==home.xxx&&ttty==home.yyy) ant[AntNow].SmellAmount[SMELL_TYPE_HOME] = MAX_SMELL; } /* of search for food */ } void DealKey(char key) { int i; switch(key) { case ‘p’: gettime(&endtime); DispPlayTime(); getch(); gotoxy(1,MAXY+1); for(i=1;i<=MAXX-1;i++) putch(SPACE); break; case ‘t’: if(SmellDispFlag) { SmellDispFlag=0; ClearSmellDisp(); } else SmellDispFlag = 1; break; case ‘1′: DispSmell(SMELL_TYPE_FOOD); getch(); ClearSmellDisp(); break; case ‘2′: DispSmell(SMELL_TYPE_HOME); getch(); ClearSmellDisp(); break; case ‘3′: DispSmell(2); getch(); ClearSmellDisp(); break; case ’s’: SaveBlock(); break; case ‘l’: LoadBlock(); break; default: gotoxy(1,MAXY+1); for(i=1;i<=MAXX-1;i++) putch(SPACE); } /* of switch */ } void ClearSmellDisp(void) { int k,i,j; for(k=0;k<=1;k++) /* SMELL TYPE FOOD and HOME */ for(i=1;i<=MAXX;i++) for(j=1;j<=MAXY;j++) { if(Smell[k][i][j]) { gotoxy(i,j); putch(SPACE); } } /* of one location */ } void DispSmell(int type) /* input: 0 — Only display food smell 1 — Only display home smell 2 — Display both food and home smell */ { int k,i,j; int fromk,tok; int smelldisp; switch(type) { case 0: fromk = 0; tok = 0; break; case 1: fromk = 1; tok = 1; break; case 2: fromk = 0; tok = 1; break; default:fromk = 0; tok = 1; break; } SmellGoneTimer = 0; for(k=fromk;k<=tok;k++) /* SMELL TYPE FOOD and HOME */ for(i=1;i<=MAXX;i++) for(j=1;j<=MAXY;j++) { if(Smell[k][i][j]) { smelldisp = 1+((10*Smell[k][i][j])/(MAX_SMELL*SMELL_DROP_RATE)); if(smelldisp>=30000||smelldisp<0) smelldisp = 30000; gotoxy(i,j); if(i!=food.xxx||j!=food.yyy) { if((i==food.xxx&&j==food.yyy)||(i==home.xxx&&j==home.yyy)) /* don’t over write Food and Home */; else { if(smelldisp>9) putch(‘#’); else putch(smelldisp+‘0′); } } } } /* of one location */ } int AntNextDir(int xxx,int yyy,int ddir) { int randnum; int testdir; int CanGoState; int cangof,cangol,cangor; int msf,msl,msr,maxms; int type; CanGoState = CanGo(xxx,yyy,ddir); if(CanGoState==0||CanGoState==2||CanGoState==3||CanGoState==6) cangof = 1; else cangof = 0; if(CanGoState==0||CanGoState==1||CanGoState==3||CanGoState==5) cangol = 1; else cangol = 0; if(CanGoState==0||CanGoState==1||CanGoState==2||CanGoState==4) cangor = 1; else cangor = 0; if(ant[AntNow].food) type = SMELL_TYPE_HOME; else type = SMELL_TYPE_FOOD; msf = GetMaxSmell(type,xxx,yyy,ddir); msl = GetMaxSmell(type,xxx,yyy,TurnLeft(ddir)); msr= GetMaxSmell(type,xxx,yyy,TurnRight(ddir)); maxms = MaxLocation(msf,msl,msr); /* maxms - 1 - msf is MAX 2 - msl is MAX 3 - msr is MAX 0 - all 3 number is 0 */ testdir = NULL; switch(maxms) { case 0: /* all is 0, keep testdir = NULL, random select dir */ break; case 1: if(cangof) testdir = ddir; else if(msl>msr) if(cangol) testdir = TurnLeft(ddir); else if(cangor) testdir = TurnRight(ddir); break; case 2: if(cangol) testdir = TurnLeft(ddir); else if(msf>msr) if(cangof) testdir = ddir; else if(cangor) testdir = TurnRight(ddir); break; case 3: if(cangor) testdir = TurnRight(ddir); else if(msf>msl) if(cangof) testdir =ddir; else if(cangol) testdir = TurnLeft(ddir); break; default:break; } /* of maxms */ randnum = random(1000); if(randnum<SMELL_DROP_RATE*1000||testdir==NULL) /* 1. if testdir = NULL, means can not find the max smell or the dir to max smell can not go then random select dir 2. if ant error, don’t follow the smell, random select dir */ { randnum = random(100); switch(CanGoState) { case 0: if(randnum<90) testdir = ddir; else if (randnum>=90&&randnum<95) testdir = TurnLeft(ddir); else testdir = TurnRight(ddir); break; case 1: if(randnum<50) testdir = TurnLeft(ddir); else testdir = TurnRight(ddir); break; case 2: if(randnum<90) testdir = ddir; else testdir = TurnRight(ddir); break; case 3: if(randnum<90) testdir = ddir; else testdir = TurnLeft(ddir); break; case 4: testdir = TurnRight(ddir); break; case 5: testdir = TurnLeft(ddir); break; case 6: testdir = ddir; break; case 7: testdir = TurnBack(ddir); break; default:testdir = TurnBack(ddir); } /* of can go state */ } return(testdir); }
int GetMaxSmell(int type,int xxx,int yyy,int ddir) { int i,j; int ms; /* MAX smell */ ms = 0; switch(ddir) { case UP: for(i=xxx-ANT_EYESHOT;i<=xxx+ANT_EYESHOT;i++) for(j=yyy-ANT_EYESHOT;j<yyy;j++) { if(!JudgeCanGo(i,j)) continue; if((i==food.xxx&&j==food.yyy&&type==SMELL_TYPE_FOOD)|| (i==home.xxx&&j==home.yyy&&type==SMELL_TYPE_HOME)) { ms = MAX_SMELL; break; } if(IsTrace(i,j)) continue; if(Smell[type][i][j]>ms) ms = Smell[type][i][j]; } break; case DOWN: for(i=xxx-ANT_EYESHOT;i<=xxx+ANT_EYESHOT;i++) for(j=yyy+1;j<=yyy+ANT_EYESHOT;j++) { if(!JudgeCanGo(i,j)) continue; if((i==food.xxx&&j==food.yyy&&type==SMELL_TYPE_FOOD)|| (i==home.xxx&&j==home.yyy&&type==SMELL_TYPE_HOME)) { ms = MAX_SMELL; break; } if(IsTrace(i,j)) continue; if(Smell[type][i][j]>ms) ms = Smell[type][i][j]; } break; case LEFT: for(i=xxx-ANT_EYESHOT;i<xxx;i++) for(j=yyy-ANT_EYESHOT;j<=yyy+ANT_EYESHOT;j++) { if(!JudgeCanGo(i,j)) continue; if((i==food.xxx&&j==food.yyy&&type==SMELL_TYPE_FOOD)|| (i==home.xxx&&j==home.yyy&&type==SMELL_TYPE_HOME)) { ms = MAX_SMELL; break; } if(IsTrace(i,j)) continue; if(Smell[type][i][j]>ms) ms = Smell[type][i][j]; } break; case RIGHT: for(i=xxx+1;i<=xxx+ANT_EYESHOT;i++) for(j=yyy-ANT_EYESHOT;j<=yyy+ANT_EYESHOT;j++) { if(!JudgeCanGo(i,j)) continue; if((i==food.xxx&&j==food.yyy&&type==SMELL_TYPE_FOOD)|| (i==home.xxx&&j==home.yyy&&type==SMELL_TYPE_HOME)) { ms = MAX_SMELL; break; } if(IsTrace(i,j)) continue; if(Smell[type][i][j]>ms) ms = Smell[type][i][j]; } break; default: break; } return(ms); } int IsTrace(int xxx,int yyy) { int i; for(i=0;i<TRACE_REMEMBER;i++) if(ant[AntNow].tracex[i]==xxx&&ant[AntNow].tracey[i]==yyy) return(1); return(0); } int MaxLocation(int num1,int num2,int num3) { int maxnum; if(num1==0&&num2==0&&num3==0) return(0); maxnum = num1; if(num2>maxnum) maxnum = num2; if(num3>maxnum) maxnum = num3; if(maxnum==num1) return(1); if(maxnum==num2) return(2); if(maxnum==num3) return(3); } int CanGo(int xxx,int yyy,int ddir) /* input: xxx,yyy - location of ant ddir - now dir output: 0 - forward and left and right can go 1 - forward can not go 2 - left can not go 3 - right can not go 4 - forward and left can not go 5 - forward and right can not go 6 - left and right can not go 7 - forward and left and right all can not go */ { int tx,ty,tdir; int okf,okl,okr; /* forward can go ? */ tdir = ddir; tx = xxx; ty = yyy; switch(tdir) { case UP: ty–; break; case DOWN: ty++; break; case LEFT: tx–; break; case RIGHT: tx++; break; default: break; } /* of switch dir */ if(JudgeCanGo(tx,ty)) okf = 1; else okf = 0; /* turn left can go ? */ tdir = TurnLeft(ddir); tx = xxx; ty = yyy; switch(tdir) { case UP: ty–; break; case DOWN: ty++; break; case LEFT: tx–; break; case RIGHT: tx++; break; default: break; } /* of switch dir */ if(JudgeCanGo(tx,ty)) okl = 1; else okl = 0; /* turn right can go ? */ tdir = TurnRight(ddir); tx = xxx; ty = yyy; switch(tdir) { case UP: ty–; break; case DOWN: ty++; break; case LEFT: tx–; break; case RIGHT: tx++; break; default: break; } /* of switch dir */ if(JudgeCanGo(tx,ty)) okr = 1; else okr = 0; if(okf&&okl&&okr) return(0); if(!okf&&okl&&okr) return(1); if(okf&&!okl&&okr) return(2); if(okf&&okl&&!okr) return(3); if(!okf&&!okl&&okr) return(4); if(!okf&&okl&&!okr) return(5); if(okf&&!okl&&!okr) return(6); if(!okf&&!okl&&!okr) return(7); return(7); } int JudgeCanGo(int xxx,int yyy) /* input: location to judeg output: 0 — can not go 1 — can go */ { int i,j; if(xxx<=0||xxx>MAXX) return(0); if(yyy<=0||yyy>MAXY) return(0); if(block[xxx][yyy]) return(0); return(1); } int TurnLeft(int ddir) { switch(ddir) { case UP: return(LEFT); case DOWN: return(RIGHT); case LEFT: return(DOWN); case RIGHT: return(UP); default: break; } /* of switch dir */ } int TurnRight(int ddir) { switch(ddir) { case UP: return(RIGHT); case DOWN: return(LEFT); case LEFT: return(UP); case RIGHT: return(DOWN); default: break; } /* of switch dir */ } int TurnBack(int ddir) { switch(ddir) { case UP: return(DOWN); case DOWN: return(UP); case LEFT: return(RIGHT); case RIGHT: return(LEFT); default: break; } /* of switch dir */ }
written by Minidxer \\ tags: ACO, ant, colony, optimization, 原理, 源代码, 算法, 蚁群算法
Related Post
什么是Silverlight(转载)一、什么是Silverlight
究竟什么是Silverlight?对不同的角色,Silverlight的定义或许会不一样。
对于互联网用户来说,Silverlight是一个安装简单的插件程序。用户只要安装了这个插件程序,就可以在Windows和Macintosh上多种浏览器中运行相应版本的Silverlight应用程序,享受视频分享、在线游戏、广告动画、交互丰富的网络服务等等。
对于开发设计人员而言,Silverlight是一种融合了微软的多种技术的Web呈现技术。它提供了一套开发框架,并通过使用基于向量的图像图层技术,支持任何尺寸图像的无缝整合,对基于ASP.NET、AJAX在内的Web开发环境实现了无缝连接。Silverlight使开发设计人员能够更好的协作,有效地创造出能在Windows和Macintosh上多种浏览器中运行的内容丰富、界面绚丽的Web应用程序——Silverlight应用程序。
简而言之,Silverlight是一个跨浏览器、跨平台的插件,为网络带来下一代基于.NET媒体体验,和丰富的交互式应用程序。对运行在Macintosh和Windows上主流浏览器,Silverlight提供了统一而丰富的用户体验。通过Silverlight这个小小的浏览器插件,视频、交互性内容,以及其他应用能完好的融合在一起。
二、Silverlight对视频媒体的支持
Silverlight为用户提供了低成本、高质量的流媒体解决方案。它采用荣获Emmy奖的Windows Media技术,使同等质量的视频传输流量下降了约46%,并与现有的Windows Media流量配置方案兼容。如果采用下一代Windows Server (Longhorn)系统中的IIS媒体包,流量还可能会进一步下降。
Silverlight的安装包本身已经包含了Windows Media的解码技术。因此,在客户端的操作系统中,不需要安装任何Windows Media Player等软件,就可以播放 WMV,VC-1,WMA和MP3等多种从高清质量到移动设备的视频以及音频。
Silverlight还提供了新的基于视频和动画的广告策略方案,可以在视频上增加视频、动画或其他交互性内容,使视频动画同步播放而不影响视频质量。
三、Silverlight与Web服务
作为一个客户端的插件,Silverlight对于服务端没有任何要求。无论是Windows+IIS+SQL Server+ASP.NET的WISA架构,或是Linux+Apache+MySql+PHP的LAMP架构,或者其他CGI架构,都可以使用Silverlight,而不用作特别配置。Silverlight还可以和现有的网站设计融洽共处。
Silverlight支持LINQ和LINQ to XML等技术,以及JSON,RSS,POX,REST等常见协议,从而可以方便的获得数据,实现服务与数据的混合。Silverlight的页面描述采用了基于文本的XAML文件格式,可以实现搜索引擎优化,使富交互式应用程序的内容能被索引并搜索到。而通过Windows Live提供的Silverlight Streaming,可以快速发布并集成软件服务和富媒体的内容。
![]() 四、Silverlight的开发与设计
Silverlight基于.NET框架提供了灵活的编程模型。Silverlight 1.1包含了WPF(Windows Presentation Foundation)的一个子集,利用Microsoft .NET Framework 3.0中的呈现技术 XAML使Silverlight和基于Windows应用程序的表现层保持一致。从版本1.1开始,Silverlight的开发支持JavaScript, .NET托管语言和动态语言等多种编程语言。
Silverlight还提供了一系列工具。通过Microsoft Expression Studio,设计人员可以创建出交互式的用户接口和富媒体体验,为视频媒体进行编码和发布,并创建出符合W3C标准的网络站点。而对于开发人员,Microsoft Visual Studio 2008提供了丰富编程语言支持,强大的跨平台调试功能。并通过Microsoft Intellisense协助开发人员进行客户端和服务端的快速编码开发。因此,无论是开发人员和设计人员,都可以运用已有的技巧和工具,将Silverlight集成到现有的网络应用中。
五、Silverlight的实际应用
虽然Silverlight目前还处于测试版本阶段,它已和国内外多家公司建立了合作关系。比如美国最大的棒球联盟MLB已采用Silverlight播放其网站上的部分视频。为20th Centry Fox、Sony Pictures Television等著名国际公司提供网络电视服务的Maven Networks也将把Silverlight带入自己的网络电视平台。作为2008年奥运会官方互联网赞助商的搜狐公司也与微软合作,打算使用Silverlight来完成互联网上的奥运火炬传递项目。相信不久,随着Silverlight 1.0的正式发布,互联网用户将会有更多的机会体验到Silverlight所带来的精彩的媒体体验和丰富的交互性内容。
六、Silverlight的相关支持
1.版本:Silverlight目前推出了1.0 RC和1.1 Alpha两个版本。Silverlight 1.0版本重点重点在于丰富的界面及视频体验,支持JavaScript的编程开发;而Silverlight 1.1除了包含Silverlight 1.0的特性之外,还支持对.NET托管语言以及动态语言进行Silverlight应用程序开发的。
2.操作系统:Silverlight目前所支持的操作系统包括:Windows Vista,Windows XP,Windows Server 2003,Mac OS X 10.4,以及Mac OS X Leopard;Silverlight 1.1即将支持Windows 2000操作系统。
3.浏览器:Silverlight目前支持的浏览器包括IE 6,IE 7,Firefox 2.0,Firefox 1.5,Safari 2.0。Silverlight 1.1即将支持Opera浏览器。
4. 编程语言:Silverlight 1.0支持JavaScript,而Silverlight 1.1目前支持Visual C#, Visual Basic, Jscript和IronPython,很快将支持Ruby以及VBx的编程开发。
下图给开发人员提供了更完整的参考:
七、其他参考资料
关于更多Silverlight的内容,可以访问以下站点:
1.Silverlight全球官方社区 http://www.silverlight.net
2.Microsoft Silverlight官方主页 http://www.microsoft.com/silverlight
3.Microsoft Silverlight开发中心 http://msdn.microsoft.com/silverlight
Tags: 走近Silverlight 什么是RIA?RIA(Rich Internet Application)介绍文章来源: 文章作者: 2007-10-05
目前的大部分 WebGIS 都已经使用了 Ajax ,下一步的发展方向是什么呢? IT 技术的发展是 GIS 的重要推动力量,让我们来看看 MS,Google,Adobe 等领导者的动向,也许能够获得很多启发。 关键词:MS SliverLight,Adobe Apollo,Google Gear
RIA是Rich Internet Applications的缩写,翻译成中文为富因特网应用程序(Macromedia中文网站翻译为Rich Internet应用程序)
传统网络程序的开发是基于页面的、服务器端数据传递的模式,把网络程序的表示层建立于HTML页面之上,而HTML是适合于文本的,传统的基于页面的系统已经渐渐不能满足网络浏览者的更高的、全方位的体验要求了,这就是被Macromedia公司称之为的“体验问题”("Experience Matters"),而富因特网应用程序(Rich Internet Applications,缩写为RIA)的出现也就是为了解决这个问题。
“富”的概念包含两方面,分别是数据模型的丰富和用户界面的丰富。数据中的“富”意思是用户界面可以显示和操作更为复杂的嵌入在客户端的数据模型,它可以操作客户端的计算和非同步的发送接收数据。这种模式相对于传统的HTML页面的优点是程序运行于客户端,并且程序更多的是和用户进行交互,同时更少的和服务器进行交互。平衡客户端和服务器端的复杂的数据模型可以让你有更大的空间去创建更高效和更具有交互性的网络应用程序。“富”同样也描述了全面提升的用户界面,HTML只给用户提供了非常有限的界面控制元素,而富因特网应用程序(RIA)的用户界面提供了灵活多样的界面控制元素,这些控制元素可以很好的与数据模型相结合。传统的因特网模型使用线性的设计,提供给用户一些选择然后用户发送选择结果给服务器,这种单一的模式不符合应用程序的灵活交互的要求和用户的意愿。频繁的服务器请求和页面刷新有很多的缺点,包括页面打开缓慢和降低网络带宽。如果采用富客户界面,可以从以前的服务器响应影响整个界面,转移到只有收到请求的应用程序部分才会做出相应的变化。这本质上意味着界面被分解成许多独立的模块,这些模块都会对收到的信息做出相应的反应,有些会和服务器端进行交互,有些是这些模块之间的通信。 说了这么多,可能比较抽象,但如果说Adobe Applo(FLASH), SilverLight(WPF)等,大家其实已经或多或少都听说了,如今,一个新的竞争者Google Gear又加入了这场大战,让我们觉得RIA的世纪很快就会到来,Web终于迎来了等待已久的技术革新。
虽然现在Google Gear的功能比较薄弱,只有3个看似比较鸡肋的features,但我相信,很快,google会给它们自己的这个RIA平台加入更多platform indepdent的功能,使其发展成为一套完整的能够承载大型RIA应用的framework。 字串7 个人认为,按照相同重量级的对手之间的竞争态势来看,现在真可谓是天下三分:MS SliverLight,Adobe Apollo,Google Gear。
优势:凭借MS强大的捆绑能力,毫无疑问,短时间内SliverLight会成为互联网上普及程度仅次于Flash Player的第二大“插件”。由于MS对windows的掌握程度,很容易在SilverLight中加入很多其他RIA平台中无法具备的能力,如Powerful 3D accelerate,集成WCF的通讯能力等等与windows紧密相关的能力。
劣势:由于SliverLight的强大的Windows相关的能力,很难在非Win平台上大有作为,非win平台的SliverLight很可能就是被阉割过的Compact版本,所以cross platform无从谈起。同时,由于MS在Web领域的积累不够,短时间内无法出现能够体现RIA优势的应用,导致SliverLight缺少Kill app的支撑,让Developer信心不足;并且SliverLight对于现有的应用没有考虑任何的可移植性,新的XAML,新的C#,VB.net等等这一切,都让原本的Web Frontend Engineer无法在短时间内选择SliverLight作为RIA开发的第一平台。
Google Gear: 优势:Google作为一个实实在在的Internet公司,对于Web产品以及技术的理解是前无古人的。Gear很好的作为一个已有Web Broswer的Plugin而存在,真正的体现了“RIA是Web的一种延伸”这句话。Google并不急于开发一种承载RIA的特殊浏览器,甚至一个基于Google Service的特殊操作系统;而是实实在在的将RIA这种变革带伴随着的技术升级的阵痛减到了最小的程度,让现有已经存在的Web application能够基于Gear开发一些更多的feature,保护现有Web application的投资,采用一种和蔼可亲的方式将RIA的承载平台贯彻到每家每户。而不会说:“你只要不下载我的runtime,对不起,您根本无法使用这个应用程序”。这样的做法,对于开发者和用户来说,都是乐于让人接受的事实。 字串8 劣势:正因为Google作为一个Internet公司,所以他失去了Desktop的话语权,导致Google的任何一个产品都只能考虑从Web通过浏览器一步一步的爬到Desktop上来;同时由于Google Gear对于cross platform的支持考虑,所以只能使用一些平台无关的api,同时,无法改变的是,基于浏览器的javascript interpreter确实非常低效,导致Gear很难让用户感觉到如同SliverLight能够提供的那种惊艳的感觉,取而代之的还是稍显死板生硬的加强版Web application。现阶段Gear的不完善性,比起SliverLight与Apollo来说还是太过幼稚,只能通过时间来弥补。 字串1 Adobe Apollo: 优势:凭借Flash的表现能力,PDF的普及程度,可以说我们需要的RIA特性都包含在了Apollo之中,虽然现在Apollo还处于Alpha阶段,但是由于世界范围内众多Flash Player与Web developer的支持,Apollo还真是一点都不愁不红。或许对于开发者来说,心底的呼声就是:“我们一直想要一个这样的东西呢!” Flash/Xhtml+javascript这两种比较成熟的技术,Adobe在外面包了一层Apollo的皮,这就能够圆满的完成Web application -> RIA application的进化;这样的进化成本较低,效果较为明显,所以不难解释Apollo是如此的收到欢迎。再加上Flex这个Adobe的后期之秀,Adobe不仅要让Flash爬到桌面来,而且还要于SliverLight展开竞争;同样的MXML v.s. XAML ,c#/.net language v.s. actionscript3,势必非要争出个你死我活。
劣势:我真是想不出Apollo的劣势,因为通过Apollo的相关技术,我无法推导出Apollo有什么错。如果非要说一个的话,还是cross platform带来的对于hardware acclerate方面的牺牲,似乎这不是劣势。唯一担心的就是Apollo与MS的Sliverlight在Desktop展开正面冲突,其结果是否会由于技术无关的因素而吃亏,不得而知……或许如果Apollo能够作成Google Gear那样的浏览器插件,就真的是完美了。
PS:其他的相关RIA平台,由于重量级不够,没有列入详细的介绍;如Sun JavaFX, Mozilla FireFox3等等。有兴趣的读者,可以自己搜寻相关资料。
2007-09-02 11:36:37
By Mr. Vaibhav V. Gadge (vaigadge@in.ibm.com), 软件工程师, IBM
Rich Internet Application (RIA) 超出了 HTML 提供的传统用户界面 (UI) 控件的标准有限集合,比如文本框、复选框或单选按钮。RIA 为用户提供了丰富得多的控件集合,以及一种更加高级的服务器交互机制。使用 RIA,当从浏览器提交数据时,用户不必刷新页面;他们可以仅刷新页面的一部分,具有更好的错误处理,等等。
本文内容包括:
术语 “Rich Internet Application” 已经出现几年了,但该概念还被称为:
Internet 是信息的巨大来源,许多技术在努力以高级和用户友好的方式改进 Web 上的信息传递和存储性能。在大多数 Web 应用程序中,大量处理发生在服务器端,只有用户交互发生在客户机端。从而使服务器承担了沉重的数据和处理负载,以及网络通信中不断增加的依赖性。
传统的基于客户机-服务器的架构具有高的灵活性和丰富性,但随着 Web 的成长而日渐消亡。一个原因是缺乏客户机应用程序的一致性和标准化。现在,勿庸置疑,浏览器是已经被人们普遍接受的 Web 工具。但是,它缺乏智能处理。所以责任在于可以交付更丰富的用户体验并能在客户端进行简单处理的客户机应用程序。RIA 提供了设计更好、更快、更吸引人并更无限可用的用户体验的机会 —— 全部在浏览器中实现。
致力于 Web 和 internet UI 层的开发人员通常在 UI 层上进行试验,尝试可以在最少外部支持下有效工作的各种 RIA 工具。但是,在多数情况下,浏览器需要一些支持以使插件、扩展或下载在浏览器内部无缝工作。
本文讨论有助于为业务案例确定最佳 RIA 选择的工具和参数。本文不可能讨论 RIA 的所有因素,但我将重点介绍您在评估 RIA 技术时审核的一些重要特性。
评估 RIA 技术时,需要考虑下列因素:
刷新页面的一块而不是整个页面有非常显著的好处,因为它直接依赖于网络流量。刷新一块使得应用程序更快、更可用并使用户具有更好的视觉体验。它还有助于更好地管理错误。
假设用户在网页上执行一个操作或第一个任务,并且数据在后台提交给服务器。然后用户在同一页面上继续执行另一个任务。同时,来自第一个任务的反馈已经返回并更新同一页面的某个部分。因此,如果这样设计网页,则会使工作和任务更有效率。
本节讨论当前 UI 技术提供的一些不同选项。
Laszlo 是领先的开放源码平台,用于在 Web 中使用 Flash 来开发和交付 RIA。Flash 播放器最初具有一个小插件以在浏览器中运行 Flash 文件。因为其高可靠性和兼容性,它被扩展用于创建闪烁的动画图片。后来的版本合并了一些重要的脚本兼容性、与服务器的数据交换,Flash 6 添加了双向音频和视频通信。
Laszlo 已经扩展了该丰富性,使用脚本语言来生成 Flash 并交付给浏览器。它提供了一个用于构建 RIA 的开发源码 XML 本地平台。
它只需要在任何浏览器上安装 Flash 5.x+。脚本以一种叫做 LZX 的基于 XML 的语言编写。LZX 是一种面向对象的基于标记的语言,使用 XML 和 Javascrīpt 语法创建动态生成的 Flash 文件。服务器上的 LZX 编译器编译 LZX 文件并将 Flash 发送到浏览器中。实际的数据交换是以 XML 形式进行的,LZX 控件使用 XPath 来表示 XML。事件也很容易与控件绑定。每个控件定义一组可以从父事件继承事件的事件。清单 1 中的示例展示了如何使用事件。
您将发现 Laszlo 易于学习、开发新组件、组件化并与任何 Web 应用程序集成。与其他 RIA 工具相比,它具有丰富的组件库。
LZX 能够让 HTTP 和 Web 服务使用 SOAP 和 RPC 协议在后台请求服务器,而无需刷新页面。插件已经就绪,可以将任何 Web 应用程序文件与 Laszlo 库集成。当前,基于 Eclipse 的 IDE 可供开发使用。还有一些工具可用于在客户端的 LZX 中进行调试。有趣的是,它们还提供了 Lzunit 框架以用于测试 Laszlo 应用程序。
最近,Laszlo 宣布了支持使用相同的现有框架将应用程序以 DHTML 交付给浏览器。这使您可以选择配置时希望将应用程序交付为 DHTML 还是 Flash。Laszlo 还扩展了对 Ajax 社区和多个设备交付的支持。
图 1 展示了 Laszlo 和 Dojo 的示例。
XML 用户界面语言 (XUL) 是 Mozilla 的基于 XML 的跨平台语言,用于描述应用程序的用户界面。它提供了可用于页面中的现成组件库。目前,它仅应用于基于 Gecko 的浏览器中,比如 Mozilla Firefox 或 Netscape 6 以上版本。
XUL 使用基于 XML 的标记语言描述用户界面控件。它提供了各种流行的富 Internet 控件,比如菜单、选项卡、树和弹出菜单。XUL 使用文档对象模型 (DOM) 存储节点树。加载了所有 XUL 文件之后,XUL 将所有标记解析并转换为层次文档结构的节点。然后可以使用此 DOM 结构、DOM 结构的方法以及 XUL 函数提供的其他方法来检查并修改数据。您始终可以从 Javascrīpt 访问并操作 DOM,并使之像典型的 HTML 控件一样易于处理。每个控件和每个节点都具有多个属性来定义其外观和结构。
从远程位置访问时,浏览器像处理 HTML 或其他浏览器内容一样处理 XUL 文件。但是,当它们作为扩展而本地安装在其 chrome 系统的浏览器中时,条目将收到访问系统和书签的特殊权限。在这种情况下,它可以执行其他的特权操作。
Mozilla 浏览器本身也是一组软件包,其中包括 XUL 文件、Javascrīpt 和样式表,但它是相当大的而且非常复杂的扩展。
XUL 使用 eXtensible Bindings Language (XBL) 进行绑定。每个控件可以使用 Mozilla 的 XBL 被绑定。XUL 使用 RDF 格式,可用于存储资源。可以使用其他格式的数据,并从中创建 RDF 数据,该数据将绑定到 XUL 格式。
因为 XUL 类似于 XML 文件,所以可以使用 IDE 的任何文本编辑器或 XML 编辑器。因为相同的底层代码处理所有 XUL 文件、HTML 和 SVG,所以可以使用 CSS 属性设置 XUL 文件的样式。它对定位具有内置支持,因为所有文本内容在浏览器中是保持分离的。
皮肤 在 Mozilla 中由 CSS 文件组成,定义浏览器的用户界面。可以为不同的外观修改和创建皮肤,而无需更改代码。它类似于通过添加功能来扩展浏览器 API 的功能。
如果在 Mozilla Firefox 中运行 清单 2 中的文件,它将呈现一个文本框和按钮。
XForms 1.0 提供了一种新的用于联机交互的平台独立标记语言。W3C 已经出现了用于实现 XForms 的规范,而且 XForm 被认为是 HTML 形式的继任者。
XForms 独立于表示设备。无需对传统浏览器、PDA 移动电话、语言浏览器、甚至一些更奇怪的新兴客户机(比如 instant messenger)进行任何更改,就可以传递 XForms。这使得 XForms 成为更吸引 RIA 的工具。
在 XForms 中,实际数据(XML 表单定义)与表单表示分离。这种设备独立的 XML 表单定义叫做 XForms 模型,可以用于许多标准的或专用的用户界面。
XForms 用户界面提供了一组标准的可视控件,旨在于替换当今的 XHTML 表单控件。它们可用于 XHTML SVG 或其他组、语言浏览器组中,还可以独立开发 XForms 的用户界面组件。XForms 模型被引用在每个 XForms 控件中以呈现数据。它遵循 XPath 以引用 XML 中的元素。提交数据时,它只能提交已填充的 XML 数据模型。
XForms 使用 XML 事件来处理事件和动作。XML 事件指定事件、观察者和处理程序。正如 清单 3 所示, 可以将 XForms 与 AJAX 集成。当前,在 W3C 中,可以找到 20 多个 XForms 示例实现。许多供应商,其中包括 IBM,已经开发了 XML 的 XForms 引擎(参阅 参考资料 中的 XML Forms Package)。Mozilla 已经宣布在 Mozilla 运行的所有平台上支持 XForms。要查看 XForms 实现的优秀示例,请参阅 参考资料。
清单 3 展示了一个简单的 XForms 示例,显示了一个用 FormFaces™ 实现呈现的文本框和按钮。
Dojo 是用 JavaScrip 编写的开放源码 DHTML 工具包。Dojo Toolkit 提供了一组核心库,和一组丰富的不同的软件包库,每个库提供特定的函数。Dojo 提供较低级的 API 来编写可移植的 Javascrīpt 并简化复杂的脚本。可以很容易很快地原型化交互小部件和动画转换。它提供了事件系统、I/O 软件包和一般语言增强的库。可以用 Dojo 编写脚本,并根据您的需要包括任意多个可用的 API。
Dojo 还提供了一组可直接用于任何应用程序中的小部件库。可以使用其中一些核心小部件作为 UI 控件,比如菜单小部件、选项卡集、树小部件等等。还有一般函数,比如布局小部件、日期选择器、SVG 小部件等等。
Dojo 基于单个标记语言构建,提供了声明和使用响应 DHTML 界面组件的简单方法。清单 4 展示了一个简单的 Dojo 组件示例,它是 HTML 页面中一个面向用户的特殊按钮。
Dojo 工具包还包括一些调试选项。AJAX Toolkit Framework (ATF) 可用作功能强大的 IDE。这是 IBM 的 Emerging technology Toolkit (ETTK) 的一部分,是一组特殊的新兴技术。ATF 主要基于 Eclipse Web 工具项目,允许支持 DOM 浏览、Javascrīpt 调试等等。
最近,Dojo Foundation 宣布了与 Laszlo 的合作协议。按照该协议,您可以在 Laszlo 的开放源码项目中使用 Dojo Toolkit。同样,Laszlo 将将库贡献给 Dojo Foundation,从而促进开放源码社区的发展。
Macromedia Flex 是另一种基于 Flash 的用户界面。它提供位于应用服务器顶层的 Flex 表示服务器,并从该服务器动态生成 Flash 文件,然后交付给浏览器。这些 Flash 文件在浏览器的 Flash 播放器内部执行,并允许用户交互、执行操作、甚至生成 SOAP、HTTP 或 AMF 请求以连接回服务器。
布局和 UI 组件在一种基于 XML 的语言 MXML 中定义。Flex 为可视组件、容器以及远程服务对象和数据模型提供了丰富的 MXML 扩展类。它还与控件进行数据绑定,并访问服务器端数据。
ECMA 脚本语言 (Actionscrīpt 2) 嵌入在 MXML 中以处理事件、系统事件或构造复杂的数据模型。这是一种面向对象的语言,类似于 Javascrīpt 和 ECME 脚本。与 XForms 一样,Flex 保持数据模型、数据表示、数据验证器和数据服务分离(类似于 MVC 样式)。
到达 MXML 的所有请求都通过 Flex 编译器进行处理,该编译器编译 MXML 并生成 SWF,然后将其高速缓存,直到它被修改并最终交付给浏览器为止。
任何 XML 编辑器都可用于编写 MXML 脚本,但 Macromedia 还提供了一个特殊的 IDE 进行 Flex 应用程序开发,叫做 Flex Builder 1.5。它的优点是与 Flex 服务器集成。它还提供了一些组件,允许连接服务器、执行正常的 HTTP 调用、连接远程 Java™ 对象并从浏览器本身与 Web 服务交互。它可以与现有的 J2EE 和 .NET 应用程序模型集成。
清单 5 展示了 Macromedia Flex 代码的一个示例。
Macromedia Flex 看起来类似于 Laszlo。二者都是丰富的功能强大的基于 Flash 的应用程序。Laszlo 位于 Flash 引擎外,所以性能可能有所欠缺,但它具有其他优点。
下表比较了上文讨论过的五种技术以及 Altiolive(一种丰富的企业应用程序)。
我们已经讨论了五种技术,当然还有其他一些技术。许多公司使用各种技术提供了非常特别的 RIA 原型。尽管一一讨论这些技术超出了本文范围,但下面这些技术值得一看:
本文介绍了 RIA,讨论了当前的 UI 技术,并推荐了其他技术。我希望工具比较将帮助您根据需要作出一个正确的选择。每种技术都有不同的优点,从而基于您的需要为开发人员提供了丰富的控件集合。
本文讨论的技术为用户带来一些新奇的东西,并提供了更丰富的用户体验。您现在可以跨越浏览器并呈现给 PDA、跨平台的移动设备,并用音频、视频、图像和动画来丰富用户体验。RIA 几乎包含了 XML,因此 XML 无疑是优胜者。
将来,我预计 RIA 将会在 Web UI 转换到下一级别中扮演重要的角色,并帮助准备支持 Web 2.0。
学习
Vaibhav V. Gadge 是位于印度 Bangalore 的 IBM Software Lab 的一名软件工程师。他目前效力于 Websphere Product Center 的 Portal 团队。他是 Java 认证专家,具有多个平台上 Java、J2EE 和基于 Web 技术方面的大约五年的技术经验。他拥有从 Nagpur University 获得的电子工程学士学位。可以通过 vaigadge@in.ibm.com 与 Vaibhav 联系。
2008-03-24 什么是 Adobe AIR什么是 Adobe AIR Adobe Integrated Runtime (AIR) 是一个跨操作系统的运行时,利用现有的Web开发技术(Flash,Flex,HTML,JavaScript,Ajax)来构建富Internet应用程序并部署为桌面应用程序。 AIR 支持现有的Web技术如Flash,Flex,HTML,JavaScript和AJAX,可以用你最熟练的技术来开发您所见过的最具用户体验的RIA程序,例如,一个AIR程序可以使用如下一种或多种组合技术构建:
作为结果,AIR 应用程序可以是:
(HTML, JS, CSS) 或 PDF
用户使用AIR 应用程序的方式和传统桌面程序是一样的,当运行时环境安装好后,AIR 程序就可以其他桌面程序一样运行了。 因为AIR 是应用程序运行时环境,因此她很小且对用户来说不可见。运行时环境提供了一套一致的跨操作系统平台和框架来开发和部署应用程序,因此你的程序不必到每个平台上进行测试,在一个平台上开发好就可以在其他平台上运行了,这有很多好处:
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1777609 常青发表于 2007年09月08日 23:05:00 2008-03-16 什么是Web 2.0开发者在线 Builder.com.cn 更新时间:2007-09-07作者:Tim O'Reilly 来源:互联网周刊
本文关键词: web 2.02001年秋天互联网公司(dot-com)泡沫的破灭标志着互联网的一个转折点。许多人断定互联网被过分炒作,事实上网络泡沫和相继而来的股市大衰退看起来像是所有技术革命的共同特征。股市大衰退通常标志着蒸蒸日上的技术已经开始占领中央舞台。假冒者被驱逐,而真正成功的故事展示了它们的力量,同时人们开始理解了是什么将一个故事同另外一个区分开来。
“Web 2.0”的概念开始于一个会议中,展开于O'Reilly公司和MediaLive国际公司之间的头脑风暴部分。所谓互联网先驱和O'Reilly公司副总裁的戴尔·多尔蒂(Dale Dougherty)注意到,同所谓的“崩溃”迥然不同,互联网比其他任何时候都更重要,令人激动的新应用程序和网站正在以令人惊讶的规律性涌现出来。更重要的是,那些幸免于当初网络泡沫的公司,看起来有一些共同之处。那么会不会是互联网公司那场泡沫的破灭标志了互联网的一种转折,以至于呼吁“Web 2.0”的行动有了意义?我们都认同这种观点,Web 2.0会议由此诞生。 在那个会议之后的一年半的时间里,“Web 2.0”一词已经深入人心,从Google上可以搜索到950万以上的链接。但是,至今关于Web 2.0的含义仍存在极大的分歧,一些人将Web 2.0贬低为毫无疑义的一个行销炒作口号,而其他一些人则将之理解为一种新的传统理念。 本文就是来尝试澄清Web 2.0本来意义。 在我们当初的头脑风暴中,我们已经用一些例子,公式化地表达了我们对Web 2.0的理解:
这个列表还会不断继续下去。但是到底是什么,使得我们认定一个应用程序或一种方式为作所谓“Web 1.0”,而把另外一个叫做“Web 2.0”呢?(这个问题尤为紧迫,因为Web 2.0的观念已经传播的如此广泛,以至于很多公司正在将这个词加到他们的行销炒作中,但却没有真正理解其含义。同时这个问题也尤为困难,因为许多嗜好口号的创业公司显然不是Web 2.0,而一些我们认为是Web 2.0的应用程序,例如Napster和BitTorrent,甚至不是真正适当的网络程序!)我们首先来探讨一些原则,这些原则是通过Web 1.0的一些成功案例,以及一些最为有趣的新型应用程序来体现的。 1. 互联网作为平台 正如许多重要的理念一样,Web 2.0没有一个明确的界限,而是一个重力核心。不妨将Web 2.0视作一组原则和实践,由此来把距离核心或远或近的网站组成为一个类似太阳系的网络系统,这些网站或多或少地体现着Web 2.0的原则。 http://blog.agent.csie.org/wp-content/web2mememap.jpg 图1为Web 2.0的“模拟图”,该图是在名为“O'Reilly的朋友”(Friend Of O’reilly, FOO)的会议的一个研讨会上产生的。这个图基本上仍处于演化阶段,但已经描绘出了 从Web 2.0核心理念中衍生出的许多概念。
例如,在2004年10月的第一次Web 2.0的会议上,约翰·巴特利(John Battelle)和我在我们各自的开场白中列举了一组初步的原则。 这些原则中的第一条就是“互联网作为平台”。这也曾是Web 1.0的宠儿网景公司(Netscape)的战斗口号,而网景在同微软的大战中陨落了。此外,我们早先的Web 1.0的楷模中的两个,DoubleClick和Akamai公司,皆是将网络当作平台的先驱。人们往往不认为这是一种网络服务,但事实上,广告服务是第一个被广泛应用的网络服务,同时也是第一个被广泛应用的混合处理(mashup),如果用另一个近来流行的词来说的话。每个旗帜广告(banner ad)都是用来在两个网站之前无缝合作,向位于另外一台计算机上的读者传递一个整合好的页面。 Akamai也将网络看作平台,并且在一个更深入的层次上,来搭建一个透明的缓存和内容分发网络,以便降低宽带的拥塞程度。 虽然如此,这些先驱提供了有益的对比,因为后来者遇到同样问题的时候,可以将先驱们的解决方案进一步延伸,从而对新平台本质的理解也更为深刻了。DoubleClick和Akamai都是Web 2.0的先驱,同时我们也可以看到,可以通过引入更多Web 2.0的设计模式,来实现更多的应用。 让我们对这三个案例中的每一个都作一番深究,来探讨其间的一些本质性的差别。 Netscape 对 Google 如果Netscape可以称为Web 1.0的旗手,那么Google几乎可以肯定是Web 2.0的旗手,只要看看他们的首次公开上市(IPO)是如何地揭示了各自的时代就清楚了。所以我们就从这两个公司和其定位的差别入手。 Netscape以传统的软件摹本来勾勒其所谓“互联网作为平台”:他们的旗舰产品是互联网浏览器,一个桌面应用程序。同时,他们的战略是利用他们在浏览器市场的统治地位,来为其昂贵的服务器产品建立起市场。从理论上讲,在浏览器中控制显示内容和程序的标准,赋予了Netscape一种市场支配力,如同微软公司在个人计算机市场上所享受的一样。很像当初“自行的马车”(horseless carriage)将汽车描绘为一种熟知事物的延伸,Netscape曾推销一种网络桌面(webtop)来替代传统的桌面(desktop),并且计划借助信息更新,以及由购买了Netscape服务器的信息提供者来推送的各种小程序,来开发推广这种网络桌面。 最终,浏览器和网络服务器都变成了“日用品”,同时价值链条也向上移动到了在互联网平台上传递的服务。 作为对比,Google则以天生的网络应用程序的角色问世,它从不出售或者打包其程序,而是以服务的方式来传递。客户们直接或间接地为其所使用的服务向Google付费。原有软件工业缺陷荡然无存。没有了定期的软件发布,只需要持续的改善。没有了许可证或销售,只需要使用。没有了为了让用户在其设备上运行软件而不得不进行的平台迁移,只需要搭建宏大的、由众多个人计算机组成的、可伸缩的网络,其上运行开源操作系统,及其及自行研制的应用程序和工具,而公司之外的任何人则永远无法接触到这些东西。 在其底层,Google需要一种Netscape从未需要过的能力:数据库管理。Google远远不只是一个软件工具的集合,它是一个专业化的数据库。没有这些数据,那些工具将毫无用武之地;没有这些软件,数据也将无可控制。软件许可证制度和对应用程序接口(API)的控制——上一个时代的法宝——已经毫不相关了,因为Google的软件只需要执行而从不需要分发,也因为如果不具备收集和管理数据的能力,软件本身就没有什么用处了。事实上,软件的价值是同它所协助管理的数据的规模和活性成正比的。 Google的服务不是一个简单的服务器,虽然其服务是通过大规模的互联网服务器集合来传递的;其服务也不是一个浏览器,虽然这种服务是被用户在浏览器中体验到的。Google的旗舰产品——搜索服务,甚至不托管它让用户来搜寻的内容。很像一个电话通话过程,不仅发生在通话的两端,而且发生在中间的网络上。作为用户和其在线体验的一个中介,Google作用于浏览器、搜索引擎和最终的内容服务器之间的空间中。 虽然Netscape和Google都可以被描述为软件公司,但显然Netscape可以归到Lotus,Microsoft,Oracle,SAP,以及其他发源于上个世纪八十年代软件革命的那些公司所组成的软件世界。而Google的同伴们,则是像eBay,Amazon,Napster,及至DoubleClick和Akamai这样的互联网公司。 DoubleClick对Overture和AdSense 同Google类似,DoubleClick是一个名副其实的互联网时代的孩子。它把软件作为一种服务,在数据管理方面具有核心竞争力,并且正如上文所述,它是一个早在连网络服务的名字还不曾有的时候,就已然开始其服务的先驱。然而,DoubleClick最终还是被其商业模式局限住了。它所贯彻的是九十年代的互联网观念。这种观念围绕着出版,而不是参与;围绕着广告客户,而不是消费者,来进行操纵;围绕着规模,认为互联网会被如MediaMetrix等网络广告评测公司尺度下的所谓顶级网站所统治。 结果是,DoubleClick得意地在其网站上引用道:“超过2000种的成功应用”。而相对比的是,Yahoo!公司的搜索市场(从前的Overture)和Google的AdSense产品,已经在为几十万的广告客户服务。 Overture和Google的成功源自于对克里斯·安德森(Chris Anderson)提到的所谓“长尾”的领悟,即众多小网站集体的力量提供了互联网的大多数内容。DoubleClick的产品要求一种签订正式的销售合同,并将其市场局限于很少的几千个大型网站。Overture和Google则领会到如何将广告放置到几乎所有网页上。更进一步地,它们回避了发行商和广告代理们所喜爱的广告形式,例如旗帜广告和弹出式广告,而采用了干扰最小的、上下文敏感的、对用户友好的文字广告形式。 Web 2.0的经验是:有效利用消费者的自助服务和算法上的数据管理,以便能够将触角延伸至整个互联网,延伸至各个边缘而不仅仅是中心,延伸至长尾而不仅仅是头部。 毫不奇怪,其他Web 2.0的成功故事也显示着同样的轨迹。eBay扮演着一个自动的中间媒介的角色,使个体之间发生的几个美元的偶然性的交易成为可能。Napster(虽然已经出于法律原因而关闭)将其网络建立在一个集中的歌曲数据库之上,但是它让每一个下载者都成为一台服务器,从而使其网络逐渐扩大。 Akamai 对 BitTorrent 同DoubleClick类似,Akamai的业务重点面向网络的头部,而不是尾部;面向中心,而不是边缘。虽然它服务于那些处于网络边缘的个体的利益,为他们访问位于互联网中心的高需求的网站铺平了道路,但它的收入仍然来自从那些位于中心的网站。 BitTorrent,像P2P风潮中的其他倡导者一样,采用了一种激进的方式来达到互联网去中心化(internet decentralization)的目的。每个客户端同时也是一个服务器;文件被分割成许多片段,从而可以由网络上的多个地方提供,透明地利用了网络的下载者来为其他下载者提供带宽和数据。事实上,文件越流行下载得越快,因为有更多的用户在为这个文件提供带宽和各个片段。 BitTorrent由此显示出Web 2.0的一个关键原则:用户越多,服务越好。一边是Akamai必须增加服务器来改善服务,另一边是BitTorrent用户将各自的资源贡献给大家。可以说,有一种隐性的“参与体系”内置在合作准则中。在这种参与体系中,服务主要扮演着一个智能代理的作用,将网络上的各个边缘连接起来,同时充分利用了用户自身的力量。 2. 利用集体智慧 在诞生于Web 1.0时代并且存活了下来,而且要继续领导Web 2.0时代的那些巨人的成功故事的背后,有一个核心原则,就是他们借助了网络的力量来利用集体智慧: --超级链接是互联网的基础。当用户添加新的内容和新的网站的时候,将被限定在一种特定的网络结构中,这种网络结构是由其他用户发现内容并建立链接的。如同大脑中的神经突触,随着彼此的联系通过复制和强化变得越来越强,而作为所有网络用户的所有活动的直接结果,互联的网络将有机地成长。 --Yahoo!是第首例伟大的成功故事,诞生于一个分类目录,或者说是链接目录,一个对数万甚至数百万网络用户的最精彩作品的汇总。虽然后来Yahoo!进入了创建五花八门的内容的业务,但其作为一个门户来收集网络用户们集体作品的角色,依然是其价值核心。 --Google在搜索方面的突破在于PageRank技术,该技术令其迅速成为搜索市场上毫无争议的领导者。PageRank是一种利用了网络的链接结构,而不是仅仅是使用文档的属性,来实现更好的搜索效果的方法。 --eBay的产品是其全部用户的集体活动,就向网络自身一样,eBay随着用户的活动而有机地成长,而且该公司的角色是作为一个特定环境的促成者,而用户的行动就发生在这种环境之中。更重要的是,eBay的竞争优势几乎都来自于关键性的大量的买家和卖家双方,而这正是这一点使得后面许多竞争者的产品的吸引力显著减低。 --Amazon销售同Barnesandnoble.com等竞争者相同的产品,同时这些公司从卖方获得的是同样的产品描述、封面图片和目录。所不同的是,Amazon已然缔造出了一门关于激发用户参与的科学。Amazon拥有比其竞争者高出一个数量级以上的用户评价,以及更多的邀请来让用户以五花八门的方式,在近乎所有的页面上进行参与,而更为重要的是,他们利用用户的活动来产生更好的搜索结果。Barnesandnoble.com的搜索结果很可能指向该公司自己的产品,或者是赞助商的结果,而Amazon则始终以所谓“最流行的”打头,这是一种实时计算,不仅基于销售,而且基于其他一些被Amazon内部人士称为围绕着产品“流动”(flow)的因素。由于拥有高出对手一个数量级的用户参与,Amazon销售额超出竞争对手也就不足为奇了。 现在,具备了这种洞察力,并且可能会将之延伸开来的那些创新型的公司,正在互联网上留下他们的印迹。 维基百科全书(Wikipedia)是一种在线百科全书,其实现基于一种看似不可能的观念。该观念认为一个条目可以被任何互联网用户所添加,同时可以被其他任何人编辑。无疑,这是对信任的一种极端的实验,将埃里克·雷蒙德(Eric Raymond)的格言(源自开放源码软件的背景之下):“有足够的眼球,所有的程序缺陷都是肤浅的”(with enough eyeballs, all bugs are shallow)运用到了内容的创建之中。维基百科全书已然高居世界网站百强之列,并且许多人认为它不久就将位列十强。这在内容创建方面是一种深远的变革。 像del.icio.us(美味书签)和Flickr这样的网站,其公司已经在近期获得了广泛的关注,并且已经在一种被人们成为“分众分类”(folksonomy,有别于传统分类法)的概念上成为先行者。“分众分类”是一种使用用户自由选择的关键词对网站进行协作分类的方式,而这些关键词一般称为标签(tags)。标签化运用了像大脑本身所使用的那种多重的、重叠的关联,而不是死板的分类。举一个经典的例子,在Flickr网站上,一幅小狗照片可能被加上“小狗”和“可爱”这样的标签,从而允许系统依照用户行为所产生的自然的方式来进行检索。 协作式垃圾信息过滤产品,例如Cloudmark,就聚集了电子邮件用户们对于“一封邮件是或者不是垃圾邮件”的众多相互独立的决策,从而胜过了依赖于分析邮件本身的那些系统。 伟大的互联网成功者并不主动地到处推销其产品,这几乎成为公理。他们采用“病毒式营销”(viral marketing)的方式,也就是说,一些推介会直接从一个用户传播到另外一个用户。如何一个网站或产品依赖广告来进行宣传,你几乎可以断定它不是Web 2.0。 即便许多互联网基础设施本身,包括在大多数网络服务器中用到的Linux,Apache,MySQL,以及Perl,PHP或Python代码,也都依靠开放源码的对等生产(peer-production)的方式。其中包含了一种集体的、网络赋予的智慧。在SourceForge.net网站上列有至少10万种开放源码软件项目。任何人都可以添加一个项目,任何人都可以下载并使用项目代码。 同时,由于作为用户使用的结果,新的项目从边缘迁移到中心。一个对软件的有机的接受过程几乎完全依靠病毒式营销。同时,作为用户应用的结果,新的项目从边缘迁移到中心,这是一种几乎完全依靠病毒式营销的,有机的软件采用过程,。 经验是:源于用户贡献的网络效应,是在Web 2.0时代中统治市场的关键。
博客和大众智慧 Web 2.0时代一项最受追捧的特性就是博客的兴起。个人主页从互联网早期就已经存在了,而个人日记和每日发表观点的专栏就更渊源久远了,那么到底有什么让人大惊小怪的呢? 归根底地,博客只是一种日记形式个人网页。但正如里奇·斯格仁塔(Rich Skrenta)指出的,博客的按时间顺序来排列的结构“看起来像是一个微不足道的变化,但却推动着一个迥然不同的分发、广告和价值链。” 其中一大变化就是一项称为RSS的技术。RSS是自早期计算机高手们认识到CGI(公共网关接口)可用来创建以数据库为基础的网站以来,在互联网根本结构方面最重要的进步。RSS使人们不仅仅链接到一个网页,而且可以订阅这个网页,从而每当该页面产生了变化时都会得到通知。斯格仁塔将之称为“增量的互联网”(incremental web)。其他人则称之为“鲜活的互联网”(live web)。 当然,现在所谓“动态网站”(即具有动态产生的内容的、由数据库驱动的网站)取代了十年前的静态网站。而动态网站的活力不仅在于网页,而且在链接方面。一个指向网络博客的链接实际上是指向一个不断更新的网页,包括指向其中任何一篇文章的“固定链接”(permalinks),以及每一次更新的通知。因此,一个RSS是比书签或者指向一个单独网页的链接要强大得多。 RSS同时也意味着网页浏览器不再只是限于浏览网页的工具。尽管诸如Bloglines之类的RSS聚合器(RSS aggregators)是基于网络的,但其他的则是桌面程序,此外还有一些则可以用在便携设备上来接受定期更新的内容。 RSS现在不仅用于推送新的博客文章的通知,还可以用于其他各种各样的数据更新,包括股票报价、天气情况、以及图片。这类应用实际上是对RSS本源的一种回归:RSS诞生于1997年,是如下两种技术的汇合:一种是戴夫·温纳(Dave Winer)的“真正简单的聚合”(Really Simple Syndication)技术,用于通知博客的更新情况;另一种是Netscape公司提供的“丰富站点摘要”(Rich Site Summary)技术,该技术允许用户用定期更新的数据流来定制Netscape主页。后来Netscape公司失去了兴趣,这种技术便由温纳的一个博客先驱公司Userland承接下来。不过,在现在的应用程序实现中,我可以看出两者共同的作用。 但是,RSS只是令博客区别于同普通网页的一部分原因。汤姆·科特斯(Tom Coates)这样评论固定链接的重要性: “现在它可能看上去像是一项普普通通的功能,但它却有效地将博客从一个易于发布(ease-of-publishing)的现象,进一步转变为互相交叉的社区的一种对话式的参与。这是首次使得对其他人的网站上的很特定的帖子表态和谈论变得如此地容易。讨论出现了,聊天也出现。同时,其结果是出现了友谊或者友谊更加坚定了。固定链接是第一次也是最为成功的一次在博客之间搭建桥梁的尝试。” 在许多方面,RSS同固定链接的结合,为HTPP(互联网协议)增添了NNTP(新闻组的网络新闻协议)的许多特性。所谓“博客圈”(blogosphere),可以将其视作一种同互联网早期的、以对话方式来灌水的新闻组和公告牌相比来说,新型的对等(peer-to-peer)意义上的等价现象。人们不仅可以相互订阅网站并方便地链接到一个页面上的特定评论,而且通过一种称为引用通告(trackbacks)的机制,可以得知其他任何人链接到了他们的页面,并且可以用相互链接或者添加评论的方式来做出回应。 有趣的是,这种双向链接(two-way links)曾是象Xanadu之类的早期超文本系统的目标。超文本纯粹论者已然将引用通告颂扬为向双向链接迈进了一步。但需要注意的是,引用通告不是一个真正的双向链接,确切地讲是一种(潜在地)实现了双向链接效果的对称式单向链接。其间的区别看起来可能很细微,但实际上却是巨大的。诸如Friendster, Orkut和LinkedIn那样的社交网络系统(social networking systems),需要接受方做出确认以便建立某种连接,从而缺少像互联网架构本身那样的可伸缩性。正如照片共享服务Flickr网站的创始人之一卡特里纳·费克(Caterina Fake)所指出的,注意力仅在碰巧时才礼尚往来。(Flickr因此允许用户设置观察列表,即任何用户都可以通过RSS来订阅其他所有用户的照片流。注意的对象将会被通知,但并不一定要认可这种连接。) 如果Web 2.0的一个本质是利用集体智慧,来将互联网调试为一种所谓的全球的大脑,那么博客圈就是前脑中喋喋不休的呓语,那种我们整个头脑中都能听到的声音。这可能并不反映出大脑的往往是无意识的深层结构,但却是一种有意识的思考的等价物。作为一种有意识的思考和注意力的反映,博客圈已经开始具有强有力的影响。 首先,因为搜索引擎使用链接结构来辅助预测有用的页面,作为最多产和最及时的链接者,博客们在修整搜索引擎结果方面充当着一种不成比例的角色。其次,因为博客社区是如此多地自相引用,关注其他博客的博客们开阔了他们的视野和能力。此外,评论家们所批判的“回音室”(echo chamber)也是一种放大器。 如果只是一种放大器,那么撰写博客将会变得无趣。但是像维基百科全书一样,博客将集体智慧用作一种过滤器。被詹姆士·苏瑞奥维奇(James Suriowecki)称为“大众智慧”(the wisdom of crowds)的规律起了作用,并且就像PageRank技术所产生的结果胜过分析任何单一文档一样,博客圈的集体关注会筛选出有价值的东西。 虽然主流媒体可能将个别的博客视为竞争者,但真正使其紧张的将是同作为一个整体的博客圈的竞争。这不仅是网站之间的竞争,而且是一种商业模式之间的竞争。Web 2.0的世界也正是丹·吉尔默(Dan Gillmor)的所谓“个人媒体”(We,the media)的世界。在这个世界中,是所谓“原本的听众”,而不是密实里的少数几个人,来决定着什么是重要的。 3. 数据是下一个Intel Inside 现在每一个重要的互联网应用程序都由一个专门的数据库驱动:Google的网络爬虫, Yahoo!的目录(和网络爬虫),Amazon的产品数据库,eBay的产品数据库和销售商,MapQuest的地图数据库,Napster的分布式歌曲库。正如哈尔·瓦里安(Hal Varian)在去年的私人对话中谈到的,“SQL是新的HTML”。数据库管理是Web 2.0公司的核心竞争力,其重要性使得我们有时候称这些程序为“讯件”(infoware)而不仅仅是软件。 该事实也引出了一个关键问题:谁拥有数据? 在互联网时代,我们可能已经见到了这样一些案例,其中对数据库的掌控导致了对市场的支配和巨大的经济回报。当初由美国政府的法令授权给Network Solutions公司(后被Verisign公司收购)的对域名注册的垄断,曾经是互联网上的第一个摇钱树。虽然我们在争论通过控制软件的API来形成商业优势在互联网时代会变得困难得多,但是对关键数据资源的控制则不同,特别是当要创建这些数据资源非常昂贵,或者经由网络效应容易增加回报的时候。 注意一下由MapQuest, maps.yahoo.com,maps.msn.com,或者maps.google.com等网站提供的每张地图下面的版权声明,你会发现这样一行字“地图版权NavTeq,TeleAtlas”,或者如果使用的是新的卫星图像服务,则会看到“图像版权Digital Globe”的字样。这些公司对其数据库进行了大量的投资。(仅NavTeq一家,就公布投资7.5亿美元用于创建其街道地址和路线数据库。Digital Globe则投资5亿美元来启动其自有卫星,来对政府提供的图像进行改进。)NavTeq竟然已做了很多模仿Intel的耳熟能详的Intel Inside标识的事:例如带有导航系统的汽车就带有“NavTeq Onboard”的印记。数据是许多此类程序事实上的Intel Inside,是一些系统的唯一的信息源组件,这些系统的软件体系多数是开放源码的,也有商业化的。 当前竞争火热的网络地图(web mapping)领域显示着,对拥有软件核心数据的重要性的疏忽大意,将最终削弱其竞争地位。MapQuest在1995年率先进入地图领域,随后是Yahoo!,再后来是Microsoft,而最近Google也决定挺进这一市场,他们可以轻松地通过对同一数据的授权来提供一个具有竞争力的程序。 然而,作为对比的是Amazon.com的竞争地位。像Barnesandnoble.com这样的竞争者一样,其原始数据库来自于ISBN注册商.R. Bowker。但是同MapQuest不同,Amazon大力增强其数据,增加出版商提供的数据,例如封面图片,目录,索引,和样张材料。更重要的是,他们利用了其用户来评注数据,以至于十年之后,是Amazon而不是Bowker,成为图书文献信息的主要来源,一个学者、图书管理员和消费者的参考书目来源。Amazon还引入了其专有的标识符,即ASIN,该标识符在ISBN存在时与之对应,而当产品不带有ISBN时,就创建出一个等价的命名空间。Amazon从而有效地“吸收和拓展了”其数据提供商。 设想如果MapQuest也已做了同样的事情,利用他们的用户来评注地图和路线,添加新的价值层面。那么对仅仅通过授权使用基础数据来进入这一市场的其他竞争者,将造成远远大得多的困难。 近期Google地图的引入,为应用程序销售商和其数据提供商之间的竞争,提供了一个活生生的实验室。Google的轻量型编程模型已经引发了不计其数的增值服务的出现,这些服务以数据混合的方式,将Google的地图同其他可以通过互联网访问的数据源相结合。保罗·拉特马赫(Paul Rademacher)的housingmaps.com是这种混合的一个上佳范例,其网站将Google的地图同Craigslist的公寓出租,以及住宅购买数据相结合,来创建一种交互式的房屋搜索工具。 目前,这些混合大多是由程序高手们实现的创新性的实验产品。但是企业行动将紧随其后。并且,人们已经可以从至少一类开发者中发现这一点。Google已经将数据源提供者的角色从Navteq那里夺走,并且将自己定位为一个令人喜爱的中介者。在以后几年里,我们将会看到数据提供商和程序销售商之间的斗争,因为两大阵营都认识到了,特定的数据类别在作为搭建Web 2.0程序的积木时是多么的重要。 这场竞赛已经涉及到拥有特定类别的核心数据:位置、身份、公共事件日历、产品标识和命名空间等。在许多情况下,在那些创建数据需要巨额成本的地方,也可能存在一种如同Intel Inside方式一样凭借单一数据源来所有作为的机遇。其他情况下,胜者将是那些通过用户聚合来达到临界规模,并且将聚合的数据融入系统服务中的公司。 比如,在身份标识领域,PayPal,Amazon的一键式,以及拥有数百万用户的交流系统,都有可能成为创建整个网络范围的身份标识数据库的正当竞争者。(关于此,Google最近使用手机号码作为Gmail账号标识的尝试,可能就是朝借鉴和拓展电话系统所迈出的一步。)同时,像Sxip这样的创业公司,正在探索联合身份标识的可能性,以寻求一种“分布一键式”,从而提供一个无缝的Web 2.0标识子系统。在日历领域,EVDB则是通过维基式参与体系来搭建世界上最大的共享日历的一种尝试。虽然评判者尚在观望着任何一个特定创业公司或方式的成功是否,但很显然,这些领域的标准和解决方案,有效地将某些数据转变为“互联网操作系统”(internet operating system)的可靠的子系统,并将促成下一代的应用程序。 关于数据,必须注意一个进一步的方面,那就是用户关心其隐私和对自己的数据的权限。在许多早期的网络程序中,版权只被松散地执行。例如,Amazon宣称对任何提交到其网站的评论的所有权,但却缺少强制性,人们可以将同样的评论转贴到其他任何地方。然而,随着很多公司开始认识到,对数据的掌控有可能成为他们首要的竞争优势来源,我们将会看到在此类控制方面强度更大的尝试。 正如专有软件的增长而导致自由软件运动一样,在下一个10年中我们会看到专有数据库的增长将导致自由数据运动。在像维基百科全书这样的开放数据项目、创作共用(Creative Commons)、以及像Greasemonkey(让用户决定如何在其计算机上显示数据)这样的软件项目中,我们可以看到这种对抗势头的前兆。
4. 软件发布周期的终结 如上文在对Google和Netscape的比较中谈到的,互联网时代软件的代表性特征就是它应该被作为服务来交付。这种事实导致这类公司的商业模式上很多根本性的变化。 1. 运营必须成为一种核心竞争力。Google或者Yahoo!在产品开发方面的专门技术,必须同日常运营方面的专门技术相匹配。从软件作为制造品到软件作为服务的变化是如此地根本,以至于软件将不再能完成任务,除非每日加以维护。Google必须持续抓取互联网并更新其索引,持续滤掉链接垃圾和其他影响其结果的东西,持续并且动态地响应数千万异步的用户查询,并同步地将这些查询同上下文相关的广告相匹配。 所以,Google的系统管理、网络、和负载均衡技术,可能比其搜索算法更被严加看管,也就不足为奇了。Google在自动化这些步骤上的成功是其同竞争者相比更有成本优势的一个关键方面。 同样也不足为奇的是,像Perl、Python、PHP、和当前的Ruby这样的脚本语言在Web 2.0公司中扮演着重要角色。Sun公司的第一个网管哈桑·施罗德(Hassan Schroeder)曾对Perl有一个著名的形容:“互联网的管道胶带”(the duct tape of the internet)。事实上,动态语言(常常被称为脚本语言,并被软件制品时代的软件工程师所贬低),是系统和网络管理员,以及创建可经常更新的动态系统的程序开发者们所喜爱的工具。 2. 用户必须被作为共同开发者来对待,这是从对开放源码开发实践的一种反思中得出的(即便所涉及的软件不太可能以开放源码授权方式来发行)。开放源码的格言“早发布并常发布”(release early and release often)事实上已经演变成一种更为极端的定位“永远的测试版”(the perpetual beta)。其中产品在开放状态下开发,新的功能以每月、每周、甚至每天的速度被加入进来。Gmail、Google Maps、Flickr、del.icio.us,和其他类似的服务,可能会在某个阶段打着测试版的标识多年。 故此,实时地监测用户行为,来考察哪些新特性被使用了,以及如何被使用的,将成为另外一种必须的核心竞争力。一位工作于一个主要在线服务网络商的开发者评论道:“我们每天在网站的某些部分提供两到三个新的特性,而且如果用户不采用它们,我们就将其撤掉。如果用户喜欢它们,我们就将其推广到整个网站。” Flickr的总开发师卡尔·亨德森(Cal Henderson),近来透露了他们是如何在短至每半个小时就部署一个新版本的。显而易见,这是同传统方式有天壤之别的开发模式。虽然不是所有的网络程序都以像Flickr这样的极端方式来开发,但几乎所有网络程序都有一个同任何PC或者客户-服务器时代截然不同的开发周期。正因如此,ZDnet杂志才论断Microsoft不会打败Google:“Microsoft的商业模式依赖于每个人在每两到三年都升级他们的计算环境。Google的模式则依靠任何人每天在其计算环境中自行探索新东西。” 虽然Microsoft已经体现了从竞争中学习并最终做得最好的强大能力,但是毫无疑问这一次的竞争要求Microsoft(可以扩展到任何现存的软件公司)来成为一种在深入层面上显著有别的公司。天生的Web 2.0公司在享受自然而然的优势,因为它们不需要去摆脱陈旧的模式(及其相应的商业模式和营收来源)。 5. 轻量型编程模型 一旦网络服务的观念深入人心,大型公司将以复杂的网络服务堆栈来加入到纷争之中。这种网络服务堆栈被设计用来为分布式程序建立更可靠性的编程环境。 但是,就像互联网成功正是因为它推翻了许多超文本理论一样,RSS以完美的设计来取代简单的实用主义,已经因其简单性而成为大概是应用最广泛的网络服务,而那些复杂的企业网络服务尚未能实现广泛的应用。 类似地,Amazon.com的网络服务有两种形式:一种坚持SOAP(Simple Object Access Protocol,简单对象访问协议)网络服务堆栈的形式主义;另一种则简单地在HTTP协议之外提供XML数据,这在轻量型方式中有时被称为REST(Representational State Transfer,代表性状态传输)。虽然商业价值更高的B2B连接(例如那些在Amazon和一些像ToysRUs这样的零售伙伴之间的连接)使用SOAP堆栈,但是根据Amazon的报道,95%的使用来自于轻量型REST服务。 同样的对简易性的要求,可以从其他“朴实的”网络服务中见到。Google近来的Google地图的推出就是一个例子。Google地图的简单AJAX(Javascript和XML的结合)接口迅速被程序高手们破译,被随即进一步将其数据混合到新的服务之中。 地图相关网络服务已经存在了一段时间,例如像ESRI那样的GIS(地理信息系统),以及从MapQuest和Microsoft的MapPoint。但是Google地图以其简洁性而让世界兴奋起来。虽然从前销售商所支持的网络服务都要求各方之间的正式约定,但Google地图的实现方式使数据可以被捕获,于是程序高手们很快就发现了创造性地重用这些数据的方法。 这里有几条重要的经验: 1. 支持允许松散结合系统的轻量型的编程模型。由企业开发的网络服务堆栈的复杂设计是用来促成紧密结合的。虽然这在许多情况下是必须是,但是许多最重要的应用程序可以事实上保持松散结合,甚至是脆弱的结合。Web 2.0的理念同传统的IT的理念迥然不同。 2. 考虑聚合(syndication)而不是协调(coordination)。简单的网络服务,例如RSS和基于REST的网络服务,是用来向外聚合数据,但并不控制其达到连接的另外一端时发生的事情。这种想法是互联网本身的基础,一种对所谓端到端原则的反映。 3. 可编程性和可混合性设计。像最初的互联网一样,RSS和AJAX这样的系统,都有此共同点:重用的障碍非常低。许多有用的软件事实上是开放源码的,而即便它不是,也没有许多东西来保护其知识产权。互联网浏览器的“查看源文件”选项,使得许多用户可以复制其他任何用户的网页;RSS被设计得使用户能够在需要的时候查看所需要的内容,而不是按照信息提供者的要求;最成功的网络服务,是那些最容易采纳未被服务创建者想到的新的方向。同更普遍的“保留所有权利”(all rights reserved)相比,随着创作共用约定而普及的“保留部分权利”(Some Rights Reserved)一词成为一个有益的指路牌。 装配中的创新 轻量型商业模型是对轻量型编程和轻量型结合的一种自然产物。Web 2.0的理念善于重用。一种像housingmaps.com这样的新服务,是通过将两个现存服务抓取到一起来简单地创建起来的。Housingmaps.com还没有商业模式(目前为止),但对于许多小规模的服务,Google的AdSense(或Amazon的associates fees计划,或者两者都是)为同类服务提供了营收模式。 这些案例为Web 2.0的另外一个关键原则提供了启发,我们将之称为“装配中的创新”。当商品组件充裕时,你可以通过以新颖的或者有效的方式来装配这些组件来创建价值。很像PC革命为硬件商品装配提供了许多创新的机会,其中像Dell这样的公司创造了这种装配的科学,并从而打败了那些商业模式上要求产品开发方面的创新的公司,我们相信Web 2.0为各个公司提供了,通过在利用和整合由其他人提供的服务方面逐渐完善,来赢得竞争的机会。 6. 软件超越单一设备 另外一个值得一提的Web 2.0特性是Web 2.0已经不再局限于PC平台这样一个事实。在对Microsoft的告别建议中,长期的Microsoft开发者戴夫·斯塔兹(Dave Stutz)指出:“超越单一设备而编写的有用软件将在未来很长一段时间里获得更高的利润”。 当然,任何的网络程序都可被视为超越单一设备的软件。毕竟,即便是最简单的互联网程序也涉及至少两台计算机:一个负责网络服务器,而另一个负责浏览器。而且就如我们已经探讨过的,在将网络作为平台的开发中,把这个概念拓展到由多台计算机提供的服务而组成的合成应用程序中。 但是如同Web 2.0的许多领域一样,在那些领域中“2.0版的事物”(2.0-ness)并不是全新的,而是对互联网平台真正潜能的一种更完美的实现,软件超越单一设备这一说法赋予我们为新平台设计程序和服务的关键性的洞察力。 迄今为止,iTunes是这一原则的最佳范例。该程序无缝地从掌上设备延伸到巨大的互联网后台,其中PC扮演着一个本地缓存和控制站点的角色。之前已经有许多将互联网的内容带到便携设备的尝试,但是iPod/iTunes组合却是这类应用中第一个从开始就被设计用于跨越多种设备的。TiVo则是另外一个不错的例子。 iTunes和TiVo也体现了Web 2.0的其他一些核心原则。它们本身都不是网络程序,但都利用了互联网平台的力量,使网络成为其体系中无缝连接的、几乎不可察觉的一部分。数据管理显然是它们所提供的价值的核心。它们也是服务,而非打包的程序(虽然对于iTunes来说,它可以被用作一个打包的程序来仅仅管理用户本地的数据)。不仅如此,TiVo和iTunes都展示了一些集体智慧的方兴未艾的应用。虽然对于每个情况,其实验都是同网络IP入口的周旋。iTunes中只有有限的参与体系,虽然近来增加的播客(podcasting)将这一规则规律性了不少。 这正是我们希望看到伟大变革的Web 2.0领域中的一个,随着越来越多的设备正连接到这个新的平台中来。当我们的电话和汽车虽不消费数据但却报告数据时,可能会出现什么样的程序呢?实时的交通监测、快闪暴走族(flash mobs)、以及公民媒体,只不过是新平台的能力的几个早期警示。
7. 丰富的用户体验 最早可以追溯到1992年魏裴(Pei Wei)开发的Viola浏览器,互联网就被用来在网页浏览器中传送“小程序”(applet)和其他一些活动内容。1995年Java的引入就是围绕着这样的小程序的传送。JavaScript和后来的DHTML都被作为轻量型方式引入,来为客户端提供可编程性和丰富的用户体验。几年以前,Macromedia缔造出“丰富的互联网应用程序”(Rich Internet Applications)一词(该词也被Flash的竞争者开放源码的Laszlo系统使用),以便凸显Flash不仅可传送多媒体内容,而且可以是GUI(图形用户界面)方式的应用程序体验。 然而,互联网传递整个应用程序的潜能在Google引入Gmail之前,一直没有成为主流,紧接着就是Google地图程序,一些基于互联网的带有丰富用户界面以及PC程序等同的交互性的应用程序。在网络设计公司Adaptive Path的耶希•詹姆斯•加莱特(Jesse James Garrett)的一个讨论会论文中,Google所使用的这组技术被命名为AJAX。他写道: Ajax不是一项技术。它其实是几项技术,每项技术自身都很繁荣,它们以强有力的全新方式结合起来。Ajax涵盖: -- 运用XHTML和CSS实现基于各种标准的展示。 -- 运用文档对象模型(Document Object Model)实现动态显示和交互。 -- 运用XML和XSLT实现数据交换和操作。 -- 运用XMLHttpRequest实现异步数据检索。 -- JavaScript将所有这些绑定到一起。 AJAX也是Web 2.0程序的一个关键组件,例如现在归属Yahoo!的Flickr,37signals的程序basecamp和backpack,以及其他Google程序,例如Gmail和Orkut。我们正在步入一个史无前例的用户界面创新阶段,因为互联网开发者们终于可以创建,像本地基于PC的应用程序一样丰富的网络程序了。 有趣的是,许多现在正被探索的功能已经存在了很多年了。90年代后期,Microsoft和Netscape,都对现在终于被认识到的那些功能有所洞察,但是它们对于所要采用的标准的争斗,使得实现跨浏览器的应用程序变得困难。仅在当初Microsoft确定无疑地赢得了浏览器之战的时候,而且那时事实上只需要针对一个浏览器标准,编写这种程序才成为可能。同时,虽然Firefox在浏览器市场中重新引入了竞争,但至少在目前我们还没有看到对互联网标准的破坏性的争夺以至于我们倒退到90年代。 在接下来的几年中,我们会看到许多新的网络程序,不仅确实是新颖的程序,而且是对PC程序丰富的网络再现。到目前为止,每个平台的变革也都为改变那些在旧平台中占主导地位的程序的领导地位创造了机会。 Gmail已经在电子邮件中提供了一些有意思的创新,将互联网的力量(随处可访问、深层的数据库能力、可搜索性)与在易用性方面同PC界面接近的用户界面相结合。同时, PC平台上的其他邮件程序,正在从另一端通过增添IM和呈现能力,来蚕食着这一领域。我们离集成通信客户端有多少远呢?这些集成通信客户端应是整合了电子邮件、即时通信和手机,并且应使用VoIP以便向网络程序的丰富功能中添加语音能力。这种竞赛已经开始。 我们也很容易看到Web 2.0是如何重新打造地址簿的。一个Web 2.0风格的地址薄将把PC或电话上的本地地址簿,仅仅当作一种你显式要求系统记忆的联系人的缓存。同时,一个基于互联网的Gmail风格的异步代理,将保存发送或者接收的每个消息,每个电子邮件地址和每个使用过的电话号码,并且创造出社交网络的启发性算法,来决定当一个答案不能在本地缓存中找到时,应该提供哪个作为替代。在缺少答案的情况下,该系统会查询更广阔的社交网络。 一个Web 2.0的字处理程序将会支持维基风格的协作编辑,而不仅仅是处理独立的文档。但是该程序也会支持我们期望在基于PC的字处理器中得到的那种丰富格式。Writely是这种程序的一个优秀范例,虽然它尚未引起广泛关注。 此外,Web 2.0革命不会局限于PC程序。例如,在CRM这样的企业级应用程序中,Salesforce.com展示了网络是如何被用来以服务的方式来传递软件的。 对新的进入者来说,竞争机会在于充分开发Web 2.0的潜能。成功的公司将创建可以向其用户学习的程序,利用可供参与的体系来建立一种决定性的优势,不仅在软件的界面方面,而且在共享数据的丰富程度方面。 Web 2.0公司的核心竞争力 在探索上述七大原则的过程中,我们已经强调了Web 2.0的一些主要特性。我们探讨的每一个例子都体现着这些原则中的一个或多个,但是可能不满足其他的原则。因此,让我们通过总结我们认为是Web 2.0公司核心竞争力的一些方面,来结束本文。 -- 服务,而不是打包的软件,具有高成本效益的可伸缩性。 -- 控制独特的、难以再造的数据源,并且用户越多内容越丰富。 -- 把用户作为共同开发者来信任。 -- 利用集体智慧。 -- 通过客户的自服务来发挥长尾的力量。 -- 软件超越单一设备。 -- 轻量型用户界面、开发模式、和商业模式。 今后一个公司要宣称是“Web 2.0”,就要将其特性同上述列表相测试。越符合就越名副其实。不过要记住,在某一个领域的卓越表现,可能会比对七大原则中的每个都浅尝则止,要更为有效。
奥莱理媒体公司(O'Reilly Media Inc.) 主席兼CEO 提姆·奥莱理(Tim O'Reilly)授权刊登, 美国密西根大学资深软件分析师玄伟剑提供全文翻译。 节略版请参见1121期杂志
Mashup -- SOA 的发展之路: Web 2.0 和基础概念 2008-03-12 埃及的诸神(带图)埃及的诸神(带图)阿蒙神 ![]() ![]() 阿蒙神标志,AMON (Amen, Amun, Ammon, Amoun) ![]() 象征:公牛, 牧羊或是鹅,他是底比斯的守护神。通常他具有人的模样,被认为是最原始的创始神。 追溯到埃及第七王朝阿蒙神在底比斯不过是地位一般的神而已。但是当底比斯的王子征服了他的对手成为埃及的统治者,并且把他们的城市变为埃及的新首都时,阿蒙神就成为了埃及最主要的神祗。很可能就是在那个时期他被称为我们后来所说的“众神之王”。 在埃及阿蒙神享有很高的政治地位,同时他也受普通百姓的喜欢。他被认为是穷人的大臣,他保护弱者,主持正义。向阿蒙神请求帮助的人先必须证明自己的价值或是承认自己的罪行。通常,神的力量可以为法老的统治添加光环。然而,当阿蒙神开始普及时,他的祭司却拥有了与日俱增的影响力和财富。因此,他们开始尝试涉足于政治领域。当埃及女王在阿蒙神的祭司中寻找支持者时,她称阿蒙神为她的父亲,并且以阿蒙神的名义为自己修建庙宇。具有讽刺意义的是,这样的政治策略却毁坏了阿蒙神的声望。在萨特摩西思四世时期,埃及皇室开始了一场用更纯净的方式对太阳神表示崇敬的运动。这样的情景在阿克海那顿统治时到达了顶点。 根据后来的传统,阿蒙神是自己创造自己的神。他的妻子是穆特女神,他的儿子是月亮之神空斯。 拉神 ![]() ![]() 拉神标志,RE (Ra) ![]() 象征:为凤凰,金字塔,太阳。在第五王朝时期拉神被认为是正式的神祗。传说中,是拉神创造了人类,埃及人称曾自己为拉神的牛犊。拉神(Re)这个名字寓意为"创造的力量",更准确的解释是“创造者”。在埃及早期历史中,拉神和荷鲁斯神是相区别的。荷鲁斯神代表天空的崇高,通常是鹰或是鹰头人身为化身。而拉神则被称为地平线上的荷鲁斯,由此不难看出,二者同样都显示了古埃及人对太阳的崇拜。 太阳代表着火,埃及人认为要想在天堂和冥间游走必须要有一条船,而拉神就乘着这样的一艘船。拉神在旅途中有很多陪伴者,一些神帮助他驾驶船只以确保旅行的顺利。拉神和迈特神站在荷鲁斯神的两边,荷斯掌舵,他是这艘船的船长。在船头,两只领航的鱼分别叫做"Abtu" 和 "Ant".其他的乘客还有:Geb, Hu, Sia 和 Hike . 夜晚的时候,Upuaut神就勇敢的站在船头。 然而,此次旅途并不是一帆风顺的。怪物Sebau, Nak, 和Apep会想方设法的阻止这艘船。其中Apep是最强大的一个,他是黑暗的化身 。拉神必须在每天早上他从东方出现之前打败他。Apep被描绘为毒蛇或是鳄鱼。当Apep得逞时,暴风雨就会来临,当他完全吞没船只时,日食就会出现。 一本名为《打倒Apep》的书中具体介绍了击败Apep的方法和咒幅,在底比斯神庙人们每天都要颂读此书。后来的一段时期,当伊希斯和奥西里斯在声望上超过拉神时,他仍然保留着“伟大的上天之神”的称号。 赛克美特 ![]() ![]() 克美特标志,SEKHMET (Sekhet, Sakhmet, Nesert) ![]() 象征:母狮面容、眼镜蛇等。 祭祀中心在孟菲斯。 赛克美特是母狮头的女神,主司战争和破坏。她是普塔哈神的妻子。她被造成拉神眼睛里的火。拉神创造她是作为武器利用男人的软弱去攻击男人。在一次赛克美特释放能量造成的极大破坏之后,埃及人惧怕她再次施行破坏,于是发展了精细的祭祀以期赛克美特平息怒火。在典礼上出现了超过700尊女神的雕像。祭祀活动持续很久,埃及人对赛克美特的祭祀活动似乎没有总结的一天。 赛克美特通常被描述成母狮头的女性,她的名字“Sekhmet”来源于“sekhem”字根,这个字代表强大、有势力和强烈。 赛克美特常被认为是和巴斯泰托女神一样的地位。她们分别称为西方和东方的女神。她俩的头像也常常被描述为狮头。但巴斯泰托穿着绿色衣服,赛克美特身穿红色。 奥西里斯 ![]() ![]() 奥西里斯标志,OSIRIS (Asar, Wesir, Ausar, Unnefer) ![]() 象征:手持王杖和连枷、带着假胡子,被描述成木乃伊国王的形象。 他是地下世界之神和复活之神。 丰饶之神,文明的赐予者。冥界之王,执行人死后是否可得永生的审判。一般在壁画中,若脸上涂有绿色颜料,则表示在复活中或已经复活。它的崇拜仪式起于阿拜多斯(Abydos),因此那里有许多它的神庙。它变得受欢迎是在中王国以后,十八王朝时它可能是最广泛被崇拜的神祇,同时,持续到晚期埃及。奥西里斯,是象征地球和农业的神明,每年的干旱被视为他的死亡,而每年尼罗河的泛滥及谷类的生长则象征着他的重生。他被认为是为埃及带来文明的贤明的君王。 奥西里斯是Nut和Geb神的长子,也是Seth, Nephthys 和依西斯的兄长。他娶了他的妹妹依西斯。他也是Horus 和Anubis的父亲。 最古老的宗教书中提到奥西里斯是冥界之王,还试图让读者理解,他曾经以作为Geb的第一个孩子的形式生活在地球,最独特的埃及之王,奥西里斯在Geb退位后继承了王位。那个时候埃及人还非常野蛮原始,奥西里斯看到这样的情况非常焦虑。于是,他来到人群中并教他们哪些东西可以食用,教他们农艺,如何崇拜神明,并且给了他们法律。Thoth 协助他创造了艺术和科学并为万物命名。因此,奥西里斯被认为是埃及最仁慈、有说服力的国王。奥西里斯周游其他国家,让Isis 成为他的辅政者,传授他的教义。 在奥西里斯离开埃及的时期,Isis被Seth 企图谋权夺位并对她虎视眈眈的双重阴谋所困扰。很快,当奥西里斯返回埃及,在他在位28年,月的第17天时,Seth和72名谋反者杀害了他。并且把他锁进棺材扔进了尼罗河, Isis,在她妹妹的协助下,奇迹般的找到了奥西里斯的尸体,得知奥西里斯的尸体找到后,Seth赶去把奥西里斯的尸体割成14块并分洒在埃及各地。Isis再次寻找并把尸体收集起来,并寻找到他的生殖器(一开始被至今仍被诅咒的尼罗河的鱼吃掉了)。Isis神奇的把奥西里斯重新收集好,并使他复活,但奥西里斯复活的时间只够她怀上儿子Horus公子,未来的国王。 Seth当然不想把埃及王权交给年轻的Horus,因此神的法庭召开会议讨论谁是合法的国王。会议持续了80年,最后还是Isis凭借智慧使自己的儿子赢得了王位。奥西里斯后来成为了冥界之王。由他来执行人死后是否可得永生的审判。他教授人们在地球上以一种正确的生活态度活着,死后要用适当的丧葬仪式埋葬。他的地位被认为在Nun神之下。 作为冥界之王的奥西里斯获得了极大的声望。它的崇拜仪式起于阿拜多斯(Abydos),因此那里有许多它的神庙。它变得受欢迎是在中王国以后,十八王朝时它可能是最广泛被崇拜的神祇,同时,持续到晚期埃及。 奥西里斯被杀和他的妻子寻找尸体的神话明显的说明埃及人相信有来世。 荷鲁斯神 ![]() ![]() ![]() 荷鲁斯神的标志:HORUS (Hor, Heru, Her) ![]() 象征物:鹰, 公牛,双桂冠。 荷鲁斯神是长着鹰头的埃及神。埃及的统治者常常把自己与荷鲁斯神联系起来。人们认为法老是荷鲁斯神在世间的化身,所以他成为了埃及最重要的神祗之一。 埃及法老都是拉神(太阳神)的追随者,所以作为法老化身的荷鲁斯神也便与太阳有了联系。 如果你试图解决埃及不同部分之间对神的争议,其结果是你能发现最少有15个荷鲁斯神(Horus)的形态。根据受欢迎程度,他们可以被简单得分为两类:太阳神和Osirian神。如果,他是奥塞里斯神的儿子,那么他就是Osirian;否则,他就是 太阳神。荷鲁斯神的父亲Osiris死后,他的母亲伊希斯神奇迹般的生下了他。他由他母亲在漂浮的小岛上抚养大。他也曾陷入他坏叔叔Seth 制造的一系列危险之中,不过他的妈妈一直保护着他,使他化险为夷。当荷鲁斯还是个孩子的时候就以Harpokrates而闻名,“婴儿荷鲁斯”被描绘成由伊希斯喂养的孩子。据说,他腰部以下都发育不良。这可能是因为他出生时他爸爸就去世了,也可能因为他是个早产儿。Harpokrates被描绘为一个坐着吮吸大拇指的孩子。在他的额头上有皇室的王官和毒蛇的标记。后来,他被人们视为新生的太阳。Harmakhis,“地上的荷鲁斯神”。他代表升起的太阳,是复活和永生的标志。Haroeris,年长的荷鲁斯神,这是荷鲁斯神最早的形态之一,也是南部埃及的守护神。他被认为是太阳的化身,有时,人们也称他为Hathor的丈夫,Osiris和Seth兄弟。他被描绘为鹰头人身的形象,有时还带一顶王冠。 伊西斯 ![]() ![]() 伊西斯的标志:ISIS ![]() 象征符号:王冠、鸢、蝎子、sistrum、tiet。信奉中心:Heliopolis。伊西斯(Isis)是奥塞里斯(Osiris)的妹妹,也是她的妻子,是努特(Nut,天空女神)和格伯(Geb,大地之神)的女儿,荷鲁斯(Horus)的母亲。赛思(Seth,谋杀奥塞里斯的凶手)和娜芙提斯(Nephthys,城堡之神)也是她的兄妹。伊西斯被描绘成头戴秃鹰装饰并长有羊角(有时在其羊角下还写有她名字的符号),双角之间还有太阳光盘的形象。偶尔,她也会戴着有羽毛的南北双王冠,或一对公羊角装饰。当伊西斯被描绘成一位普通的女人而非女神形象时,她则佩戴普通头饰,但点缀有蛇形标志。金字塔的铭文上记载有,当这位奥塞里斯的王后还在帮助她的丈夫辅政的时候,就已经预知到她的丈夫将要被谋害。奥塞里斯被谋杀后,伊西斯不屈不挠的寻找着丈夫的遗骸,她找遍了奥塞里斯可能被埋葬或被抛尸的地方。终于,她通过自己的法术使奥塞里斯复活,并怀孕生下了他们的儿子荷鲁斯。伊西斯是神与人之间的使者,起着至关重要的作用。法老王被视为是她的儿子,人间的荷鲁斯神。金字塔上的铭文镌刻着法老王吸吮伊西斯的乳汁的字样,那里有很多伊西斯怀抱荷鲁斯的雕塑和壁画,风格和形象也随着法老的交替而改变。伊西斯在荷鲁斯年幼的时候一直保护他,以防他受到那位一直想斩草除根的舅舅同时也是叔父的赛思的谋害,因为赛思一直害怕长大成人后的荷鲁斯来报杀父之仇。在死亡之书中,伊西斯被看作是生命的赋予者和死者食物的供给者,她也是审判死者的神祇之一。她的另一项任务是,保护伊姆赛特(Imsety),他是荷鲁斯的四个儿子之一,专门负责看管死者的肝脏。伊西斯是一位伟大的魔法师,以擅长使用法术闻名。例如,她创造了眼镜蛇,并利用蛇的毒液来迫使拉神说出自己秘密的名字。在埃及史上,伊西斯一直是最伟大的女神。她是最爱助人的女神,并且是以爱拥抱万物的母亲。伊西斯还是贤妻良母的最佳典范,因此埃及人最尊崇她。她的崇拜范围遍布整个埃及,最远到达英国。古典作家将她与珀尔塞福涅(Persephone,冥后)、特提斯(Tethys)、雅典娜(Athene)等相提并论,就象奥塞里斯与哈德斯(Hades,冥王)、酒神狄厄尼索斯(Dionysos)与其它地方的神等同视之一样。事实上,基督徒将她的一些特质影射在圣母玛莉亚的身上,就像一位充满爱的、坚强的母亲,伊西斯的这些特质吸引了西方的人们也来崇仰她。伊西斯哺育荷鲁斯的形象,毫无疑问地,激发了许多圣母与圣婴画像的灵感。 [ 本帖最后由 阿伟 于 2007-9-19 17:41 编辑 ] 人物:22年前的天才程序员,今天在干什么?人物:22年前的天才程序员,今天在干什么?void | 28 二月, 2008 20:08 1986年,Susan Lammers采访了计算机行业的先锋,19位著名的程序员和软件设计师,汇集成一本书《Programmers At Work》。这些人中包括了Charles Simonyi,比尔盖茨,Andy Hertzfeld,Ray Ozzie等等。22年后过去了,昔日意气风发的英雄,今日又在干什么?Leonard Richardson整理了一份简单介绍,讲述了他们的近况。 想考程序员的看看程序员
发表于:2008年3月8日 21时38分3秒
本文链接:http://user.qzone.qq.com/714396522/blog/1204983483
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|