??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
W一个步骤是?jng)场调研Q技术和?jng)场要结合才能体现最大h(hun)倹{?/span>
W二个步骤是需求分析,q个阶段需要出三样东西Q用戯图,数据词典和用h作手 册?/span>
用户视图是该软g用户Q包括终端用户和理用户Q所能看到的面样式Q这里面包含?/span> 很多操作斚w的流E和条g?/span>
数据词典是指明数据逻辑关系q加以整理的东东Q完成了(jin)数据词典Q数据库的设计就完成 ?jin)一半多?/span>
用户操作手册是指明了(jin)操作程的说明书?/span>
h意,用户操作程和用戯图是由需求决定的Q因此应该在软g设计之前完成Q完?/span> q些Q就为程序研发提供了(jin)U束和准lI很遗憑֤多公叔R不是q样做的Q因果颠倒,?/span> 序不分,开发工作和实际需求往往因此产生隔阂p的现象?/span>
需求分析,除了(jin)以上工作Q笔者以Z为项目设计者应当完整的做出目的性能需求说?/span> 书,因ؓ(f)往往性能需求只有懂技术的人才可能理解Q这需要技术专家和需求方Q客h 公司?jng)场部门Q能够有真正的沟通和?jin)解?/span>
W三个步骤是概要设计Q将pȝ功能模块初步划分Qƈl出合理的研发流E和资源要求?/span> 作ؓ(f)快速原型设计方法,完成概要设计可以进入编码阶D了(jin)Q通常采用q种Ҏ(gu)是因?/span> 涉及(qing)的研发Q务属于新领域Q技术主h员(sh)上来无法l出明确的详l设计说明书Q但?/span> q不是说详细设计说明书不重要Q事实上快速原型法在完成原型代码后Q根据评结果和 l验教训的ȝQ还要重新进行详l设计的步骤?/span>
W四个步骤是详细设计Q这是考验技术专家设计思维的重要关卡,详细设计说明书应当把 具体的模块以最Q干净Q的方式 ( 黑箱l构Q提供给~码者,使得pȝ整体模块化达到最 大;一份好的详l设计说明书Q可以ɾ~码的复杂性减低到最低,实际上,严格的讲详细 设计说明书应当把每个函数的每个参数的定义都精_l的提供出来Q从需求分析到概要 设计到完成详l设计说明书Q一个Y仉目就应当说完成了(jin)一半了(jin)。换a之,一个大型Y 件系l在完成?jin)一半的时候,其实q没有开始一行代码工作?/span>
那些把作软g的程序员单理解ؓ(f)写代码的Q就从根子上犯了(jin)错误?jin)?/span>
W五个步骤是~码Q在规范化的研发程中,~码工作在整个项目流E里最多不?x)超q?/span> 1/ 2 Q通常?/span> 1/3 的时_(d)所谓磨刀不误砍柴功,设计q程完成的好Q编码效率就?x)极大?/span> 高,~码时不同模块之间的q度协调和协作是最需要小?j)的Q也怸个小模块的问题就?/span> 能媄(jing)响了(jin)整体q度Q让很多E序员因此被q停下工作等待,q种问题在很多研发过E中?/span> 出现q。编码时的相互沟通和应急的解决手段都是相当重要的,对于E序员而言Q?/span> bug ?/span> q存在,你必Lq面对这个问题,大名鼎鼎的微软,可曾有连l三个月不发补丁的时?/span> 吗?从来没有Q?/span>
W六个步骤是试
试有很多种Q?/span>
按照试执行方,可以分ؓ(f)内部试和外部测?/span>
按照试范围Q可以分为模块测试和整体联调
按照试条gQ可以分为正常操作情冉|试和异常情况试
按照试的输入范_(d)可以分ؓ(f)全覆盖测试和抽样试
以上都很好理解,不再解释?/span>
MQ测试同h目研发中一个相当重要的步骤Q对于一个大型YӞ 3 个月?/span> 1 q的?/span> 部测试都是正常的Q因为永q都?x)又不可预料的问题存在?br />
完成试后,完成验收q完成最后的一些帮助文档,整体目才算告一D落Q当然日后少 不了(jin)升Q修补等{工作,只要不是想通过一锤子买卖骗钱Q就要不停的跟踪软g的运?/span> 状况q持l修补升U,知道q个软g被彻底淘Cؓ(f)止?/span>
写这些步骤算不上卖弄什么,因ؓ(f)实话讲我手边是一本《Y件工E》,在大学里q是计算 Z业的必修评Q但是我知道很多E序员(sh)乎从来都只是热衷于什么?/span> 30 天精?/span> VC 》之 cȝQ他们有些和我一h击队?gu)nQ没有正规学q这个专业,q有一些则早就在够学 分后把q些真正有用的东西还l了(jin)老师?/span>
|上现在也很躁Q一?/span> coding fans 乱嚷Ph视听Q实际上真正的技术专家很在 |上乱发帖子的,如笔者这样不知天高地厚的Q其实实在是不上什么高手,只不q看?/span> 惯这U对技术,对程序员的误解和胡说Q只好挺w而出Q做拨ؕ反正之言Q也希望那些q?/span> 沉迷于一些错误h士的 coding fans 们能认真x(chng)Q走到正途上Q毕竟那些聪明的头脑q?/span> q远没有发挥应有的h(hun)倹{?/span>
(tng)
W一、需求分析能?/span>
对于E序员而言Q理解需求就可以完成合格的代码,但是对于研发目的组l和理者, 他们不但要理解客户需求,更多时候还要自行制定一些需求,Z么这么说呢?
一般而言Q进行研发Q务,也许是客h出需求,也许是市(jng)场和营销部门提出的需求,q?/span> 时候对于研发部门,他们看到的不是一个完整的需求,通常而言Q该需求仅仅是一些功?/span> 上的要求Q或者更正规些,可能获得一个完整的用户视图Q但是这都不够,因ؓ(f)客户׃ 非技术因素多一些,他们可能很难提出完整和清晎ͼ或者说专业性的性能需求,但是对于 目l织者和规划者,他必能够清醒认识到q些需求的存在q在完成需求分析报告的?/span> 候适当的提出,同时要完整和清晰的体现在设计说明书里面,以便于程序员~码时不?x)?/span> 去这些准则?/span>
W二、项目设计方法和程处理能力
E序设计者必能够掌握不于两到三种的项目设计方法(比如自顶至下的设计方法,?/span>如快速原型法{等Q,q能够根据项目需求和资源搭配来选择合适的设计Ҏ(gu)q行目?/span>整体设计?/span>
设计Ҏ(gu)上选择不当Q就?x)耽误研发周期Q浪费研发资源,甚至影响研发效果?/span>
一个程序设计者还需要把很多功夫用在程囄设计和处理上Q他需要做数据?hu)图以确?/span>数据词典Q他需要加工逻辑图以Ş成整体的pȝ处理程?/span>
一个流E有问题的系l,q代码多漂亮,每个模块多精_(d)也不?x)成Z个好的系l?/span>当然Q做好流E分析ƈ选择好项目设计方法,都需要在需求分析能力上h_的把握?/span>
W三、复用设计和模块化分解能?/span>
q个g又是老调重谈Q前面基本素质上不是已经说明?jin)这个问题吗Q?/span>
作ؓ(f)一个从事模块Q务的E序员,他需要对他所面对的特定功能模块的复用性进行考虑Q?/span>而作Z个系l分析h员,他要面对的问题复杂的多,需要对整体pȝ按照一U模块化?/span>分析能力分解为很多可复用的功能模块和函数Qƈ针对每一模块形成一个独立的设计需求。D个例子,好比是汽车生产,最早每辆汽车都是独立安装的Q每个部仉是量w定?/span>的,但是后来不一样了(jin)Q机器化大生产了(jin)Q一个汽车厂开始通过水U来生汽RQ独?/span>部g开始具有一定的复用性,在后来标准化成ؓ(f)大趋势,不同型号Q品牌甚至不同厂商的汽R部g也可以进行方便的换装和升U,q时候,汽R生的效率达到最大化。Y件工E?/span>也是同样的道理,一个成熟的软g行业Q在一些相关项目和pȝ中,不同的部件是可以?/span>意换装的Q比如微软的许多桌面软gQ在很多操作模块Q如打开文gQ保存文件等{)(j)?/span>是复用的同一套功能模块,而这些接口又通过一些类库提供给?jin)桌面应用程序开发者方?/span>挂接Q这是复用化的模块设计明显的一个佐证?/span>
一个大型的Q错l复杂的应用pȝ分解成一些相对独立的Q具有高度复用性的Qƈ能仅仅依靠几个参数完成数据联pȝ模块l合Q是作ؓ(f)高E序员和pȝ分析员(sh)Ҏ(gu)重要?/span>工作Q合适的目设计Ҏ(gu)Q清晰的程图,是实现这一目标的重要保证?/span>
W四、整体项目评估能?/span>
作ؓ(f)pȝ设计人员Q必能够从全局出发Q对目又整体的清醒认识Q比如公司的资源?/span>|是否合理和CQ比如工E进度安排是否能最大化体现效率又不至于无法按期完成。评估项目整体和各个模块的工作量Q评估项目所需的资源,评估目可能遇到的困难,都需要大量的l验U篏Q换a之,q是一U不断ȝ的篏计才能达到的境界。在西方一些Y?/span>pȝ设计的带头h都是很年长的Q比?/span>4Q?/span>50岁,甚至更老,他们在编码方面已l远q不如年Mh那样zȝQ但是就目评估而言Q他们几十年的经验积累就是最重要和宝늚?/span>富。中国缺q么一代程序员Q主要还?sh)是~那U年U的E序员,而是那种q纪的程序员?/span>本上都是研究单位作出来的Q都不是从专业的产品化Y件研发作出来的,他们没有能积?/span>那种产品化研发的l验Q这也是没有办法的事情?/span>
W五、团队组l管理能?/span>
完成一个项目工E,需要团队的齐心(j)协力Q作为项目设计者或研发的主hQ就应当有能力最大化发挥团队的整体力量,技术管理由于其专业性质Q不大同于一般的Z理Q因里面设计?jin)一些技术性的指标和因素?/span>
首先是工作的量化Q没有量化就很难做到合适的l效考核Q而程序量化又不是单的代码行数可以计算的,因此要求技术管理h员需要能真正评估一个模块的复杂性和工作量?/span>
其次是对团队协作模式的调_(d)一般而言Q程序开发的协作通常分ؓ(f)组q行Q小l有?/span>E序员方式的Q也有民L式的Q根据程序员?sh)间的能力水q_距,以及(qing)Ҏ(gu)目研发?/span>需求,选择合适的l队方式Qƈ能将责权和成员的工作d紧密l合Q这h能最大发?/span>l队的效率?/span>
一个代码水q高的hQ未必能成ؓ(f)一个合格的目研发ȝQ这斚w的能力欠~往往是容易被忽视的?/span>
商和课本的问题,q是在于一个程序员在积累经验,逐步提升的时候没有意识到应当思考哪斚w的东西,没有有意识的项目的l织和复用设计进行揣摩,没有l常性的文档?fn)惯和ȝ?/span>惯,不改变这些,我们的合格的目设计者还是非常欠~?/span>
另外Qؓ(f)防止有无聊的人和我较真,补充一点,本文针对目标是作商业化的软g目和工E,那些U研机构的编E高手,比如法高手Q比如图象处理高手,他们的工作是研究?/span>题而非直接完成商业软gQ当然最l间接成为商业品,比如微Y研究院在作的研究?/span>题)(j)Q因此他们强调的素质可能是另外的东西Q这些hQ专Ӟ(j)Qƈ不能说是E序员,?/span>能用E序员的标准去衡量?/span>
来自 : 中国源码下蝲?/span> Q?/span> http://www.downcode.com Q?/span> E序员是一U技术工作,?/span> IT 的发展中有相当重要的CQ从底层g通讯协议的徏立, 到数据传输层的处理,到操作系l的Q到数据库^台的Q一直到应用层上各种?/span> 据营销q_的搭建,E序员在里面都扮演着举轻重的角色ƈ?/span> IT 事业的发展做Z(jin)巨大 的A(ch)献?/span>
中国有很多精于编码的人,但是中国软g行业Q尤其是|络应用开发方面误区很大,很难 形成有规模的软g开发力量和产品能力Q不但比国差距甚远Q和印度相比也是颇有?/span> 如。这些问题(sh)是在于中国程序员的智商和工作努力状况Q也不是在于国家和民间对开?/span> 的投入程度,而是很大E度上,有一些对技术,对程序开发,寚w目设计方面的思想?/span> 区,q些误区Q导致了(jin)软g行业的品化能力不Q缺乏规模化和大型复用系l研发能 力,可以_(d)改变认识误区Q是解决软g行业作坊模式和个体英雄模式所带来的局限?/span> 的重要工作?/span>
中国有很多小朋友Q他?/span> 18,9 岁或 21,2 岁,通过自学也写?jin)不代码,他们有的代码写?/span> 很漂亮,一些技术细节相当出众,也很有钻研精,但是他们被一些错误的认识和观点左 叻I~Z对系l,对程序的整体理解能力Q这些hQ一个网上的朋友说得很好Q他们实?/span> 上只是一?/span> Coding fans Q压Ҏ(gu)有资格称为程序员Q但是据我所知,不少网l公司的 CTO 是q样?/span> coding fans, 拿着吓h的工资,做着吓h的项目,目的结局通常也很?/span> 人?/span>
E序员基本素质:(x)
作一个真正合格的E序员,或者说是可以真正合格完成一些代码工作的E序员,应该h的素质?/span>
1 Q团队精和协作能力
把它作ؓ(f)基本素质Qƈ不是不重要,恰恰相反Q这是程序员应该具备的最基本的,也是最重要的安w立命之本。把高水q程序员说成独行侠的都是在呓语,M个h的力量都是有 限的Q即便如 linus q样的天才,也需要通过l成强大的团队来创造奇q,那些遍布全球 的ؓ(f) linux 写核?j)的高手们,没有协作_是不可想象的。独行侠可以作一些赚qY 件发点小财,但是一旦进入一些大pȝ的研发团队,q入商业化和产品化的开发Q务,~?/span> 乏这U素质的人就完全不合g(jin)?/span>
2 Q文档习(fn)?/span>
说高水^E序员(sh)来不写文档的肯定是^臭未q的毛孩子,良好的文档是正规研发程中非帔R要的环节Q作Z码程序员Q?/span> 30 Q的工作旉写技术文档是很正常的Q而作为高U?/span> E序员和pȝ分析员,q个比例q要高很多?/span>
~Z文档Q一个Y件系l就~Z生命力,在未来的查错Q升U以?qing)模块的复用时就都?x)?/span> 到极大的ȝ(ch)?/span>
3 Q规范化Q标准化的代码编写习(fn)?/span>
作ؓ(f)一些外国知名Y件公司的规矩Q代码的变量命名Q代码内注释格式Q甚臛_套中行羃q的长度和函数间的空行数字都有明规定,良好的编写习(fn)惯,不但有助于代码的UL?/span> U错Q也有助于不同技术h员(sh)间的协作?/span>
有些 coding fans 叫嚣高水q程序员写的代码旁h从来看不懂,q种叫嚣只能证明他们自己压根不配自称E序员。代码具有良好的可读性,是程序员基本的素质需求?/span>
再看看整?/span> linux 的搭建,没有规范化和标准化的代码?fn)惯Q全球的研发协作是绝对不可想象的?/span>
4 Q需求理解能?/span>
E序员需要理解一个模块的需求,很多朋友写E序往往只关注一个功能需求,他们把性能指标全部归结到硬Ӟ操作pȝ和开发环境上Q而忽视了(jin)本n代码的性能考虑Q有人曾 l放a说写一个广告交换程序很单,q种Z来不知道在百万甚臛_万数量的访问情 况下的性能指标是如何实现的Q对于这L(fng)E序员,你给他深蓝那套系l,他也做不出太极链的ƈ访能力。性能需求指标中Q稳定性,q访支撑能力以及(qing)安全性都很重要,作ؓ(f)E序员需要评估该模块在系l运营中所处的环境Q将要受到的负荷压力以及(qing)各种潜在的危险和恶意d的可能性。就q一点,一个成熟的E序员至需?/span> 2 ?/span> 3 q的目研发和跟t经验才有可能有?j)得?/span>
5 Q复用性,模块化思维能力
复用性设计,模块化思维是要程序员在完成Q何一个功能模块或函数的时候,要多想一些,不要局限在完成当前d的简单思\上,x(chng)看该模块是否可以qq个pȝ存在Q?/span>是否可以通过单的修改参数的方式在其他pȝ和应用环境下直接引用Q这样就能极大避免重复性的开发工作,如果一个Y件研发单位和工作l能够在每一ơ研发过E中都考虑?/span>q些问题Q那么程序员׃?x)在重复性的工作中耽误太多旉Q就?x)有更多旉和精力?/span>入到创新的代码工作中厅R?/span>
一些好的程序模块代码,即便?/span>70q代写成的,拿到现在攑ֈ一些系l里面作为功能模?/span>都能适合的很好,而现在我看到的是Q很多小公司软g一升或改q就动辄全部代码?/span>写,大部分重复性工作无谓的费?jin)时间和_֊?/span>
E序员应具备的素质中
6Q测试习(fn)?/span>
作ؓ(f)一些商业化正规化的开发而言Q专职的试工程师是不可的Q但是ƈ不是说有?jin)?/span>职的试工程师程序员可以不q行自测QY件研发作Z工E而言Q一个很重要的特点就是问题发现的早Q解决的代h(hun)p低,E序员在每段代码Q每个子模块完成后进?/span>认真的测试,可以尽量将一些潜在的问题最早的发现和解冻Iq样Ҏ(gu)体系l徏讄?/span>率和可靠性就有了(jin)最大的保证?/span>
试工作实际上需要考虑两方面,一斚w是正常调用的试Q也是看程序是否能在正?/span>调用下完成基本功能,q是最基本的测试职责,可惜在很多公司这成了(jin)唯一的测试Q务,实际上还差的q那Q第二方面就是异常调用的试Q比如高压力负荷下的E_性测试,?/span>h在的异常输入情况下的试Q整体系l局部故障情况下该模块受影响状况的测试,?/span>发的异常hd资源时的模块E_试{等。当然ƈ不是E序员要对自q每段代码?/span>需要进行这U完整测试,但是E序员必L醒认识自q代码d在整体项目中的地位和各种性能需求,有针Ҏ(gu)的q行相关试q尽早发现和解决问题Q当然这需要上面提到的需求理解能力?/span>
7Q学?fn)和ȝ的能?/span>
E序员是人才很容易被淘汰Q很Ҏ(gu)落伍的职业,因ؓ(f)一U技术可能仅仅在三两q内h领先性,E序员如果想安n立命Q就必须不断跟进新的技术,学习(fn)新的技能?/span>
善于学习(fn)Q对于Q何职业而言Q都是前q所必需的动力,对于E序员,q种要求更加高?jin)?/span>
但是学习(fn)也要扑֯目标Q一些小coding fans们,他们也|z乐道于他们的学?fn)能力,一?x)学会(x)?jin)aspQ一?x)儿学?x)?/span>phpQ一?x)儿学?x)?/span>jspQ他们把q个作ؓ(f)炫耀的资本,盲目的追逐一些肤的Q表面的东西和名词,做网l程序不懂通讯传输协议Q做应用E序不懂中断向量处理Q这L(fng)技术h员,不管掌握?jin)多所谓的新语aQ永q不?x)有质的?/span>高?/span>
善于ȝQ也是学?fn)能力的一U体玎ͼ每次完成一个研发Q务,完成一D代码,都应当有目的的跟t该E序的应用状况和用户反馈Q随时ȝQ找到自q不Q这样逐步提高Q?/span>一个程序员才可能成长v来?/span>
一个不具备成长性的E序员,即便眼前看是个高手,也不要选用Q因Z落伍的时?/span>马上到?jin)?/span>
Sergey Dmitriev, JetBrains
本文blog来源Q?a >http://www.uuzone.com/blog/oiunt/891/
现在是Y件开发中开始下一ơ技术革命的时候了(jin)Q而这ơ革命的轮廓正变得越来越清晰。下一代编E范型也在接q我们,但仍然没有完全成形-Q不同的部分有不同的名称QIntentional programming, MDA, generative programming, {等Q我把把所有这些新Ҏ(gu)归ƈZ个名字:(x) ‘language-oriented programming’(面向语言的编E)(j), 而本文将阐述q种新的~程范型的主要原?/p>
今天L的编E方法有一些内在的假定像脖子上的索一h梏着我们Q尽大部分E序员还没有意识到它Q即使算上在~程领域取得的所有进步,我们也仍然处于石器时代;我们有我们信赖的x(chng)Q面向对象编E)(j)Q能够满x(chng)们的需要,但是当用它来对付最困难的问题时Q它?x)裂成碎屑;Z(jin)越矛_前进Q我们必驯服烈火,只有q样Q我们才能铸造出新的工具Q激发一个创作的新时代,和新技术的爆发
我将讨论~程的局限,它强q程序员像计机一h考,而不是o(h)计算机像E序员(sh)h考;q是严重的,Ҏ(gu)蒂固的局限,需要花费巨大的努力d服它Q当我说q将是编E中下一个大的范型{换时我ƈ没有自命不凡Q我们需要彻底重新定义我们编写程序的Ҏ(gu)
本文中,我表qC(jin)我的观点和我当前在Language Oriented Programming (LOP)上的工作Q首先我展C目前主编E方法的错误Q然后我?x)用示例来解释LOP的概念,它们Z我已有的一个LOP的实玎ͼ(x)the Meta Programming System (MPS). 本文有意只是l你一个对LOP的惊鸿一瞥,目的是激发你对这个思想的兴,q希望能够得到反馈和讨论
理想的,做一个程序员意味着我可以对计算机做M事情Q我有完全的自由Q完全的控制Q但实际上,今天的程序员只有非常受限的自由;当然Q我实可以在计机上做M事情Q但其中一些事情花费了(jin)我许多年的努力,而它们实际上只需要少的多的时_(d)一定有什么事情不对劲
E序员被限制是因Z们深׃赖于那些他们不能L改变的编E基设施Q编E语a和开发环境;如果我需要一些语a的扩展,我只能等待语a的设计者去更新它;如果我需要我的IDE有一些额外的强大功能Q我只能{待供应商来d新特性;是q些依赖限制?jin)我完全的自由;当然Q我可以写我自己的编译器和IDEQ实际上Q这也是我启动了(jin)IntelliJ IDEA的原因,因ؓ(f)我厌倦了(jin)依赖现有的弱qJava IDEQ但是,q会(x)p大量的时间和努力Qƈ且显而易见,对大部分E序员来说是不可行的Q理Z的自由和实际的自׃间存在巨大的差异Q下文中当我谈到自由Ӟ我指的是实际的自?/p>
获得自由的途径是减我们的依赖层次Q例如,Java的一个主要目标是减少Ҏ(gu)作系l的依赖Q给开发者在不同操作pȝ上部|的自由Q因此,Z(jin)在语a和环境之上获得自由,我们需要减对它们的依?/p>
Z么这是一个问题呢QQ何general-purpose的语aQ像Java和C++Q给?jin)我们用计算机做M事情的能力;q是事实Q至理Z是这P但是Qgeneral-purpose的语a向于如同后面我讲到的般生产效率低下;作ؓ(f)一U替代,我们可以使用domain-specific languagesQDSLsQaka ‘little languages’)(j)Q它们被_ֿ(j)设计成在特定问题域具有高度生产率Q比如用SQL~写数据库查询;DSLs的强大之处,领域相关Q也正是它们的弱处,因ؓ(f)M真实世界中的E序都会(x)包括许多不同的领?/p>
general-purpose ?domainspecific 之间Qƈ不是对立的;我需要所有的自由Q我希望能够做Q何事情,同时有很高的生效率Q目前ؓ(f)止还没有什么好Ҏ(gu)能够做到q点Q理x(chng)况下Q我能够为程序的各个特定部分使用不同的语aQ而它们能够融z的一起工作,q且开发环境会(x)完全支持q些语言Q包括重构,代码补全Q导航,以及(qing)L语言h的所有其它生产力工具
Z(jin)获得q种独立性,我需要有创徏、重用、修改语a和环境的自由Qؓ(f)?jin)ɘq种自由是可行的Q它需要很Ҏ(gu)的被获得Q如果我们解决了(jin)易于q行语言和环境的开发的问题Q对E序员来说将是一个巨大的q步Q这是Language Oriented Programming的切入点
要理解Language Oriented Programming是什么,让我们首先看一下今天的L~程Ҏ(gu)Q它基本上是q样Q?/p>
思考:(x) 你需要编E解决一个问题,因此你在你的头脑里Ş成了(jin)如何解决q个问题的概忉|?/p>
选择Q?/b> 你选择?jin)某Ugeneral-purpose的语a来编写解x(chng)?/p>
~程Q?你通过你的概忉|型艰隄映射到编E语a来编写解x(chng)?/p>
~程q一步是瓉所在,因ؓ(f)大部分情冉|不是容易的和自然的Q这U方法在E序员表辑֤杂的设计斚w已经被证明是低效的;相对的,下面是LOP的工作方式:(x)
思考:(x) 你需要编E解决一个问题,因此你在你的头脑里Ş成了(jin)如何解决q个问题的概忉|?/p>
选择Q?你选择?jin)某些特定的DSLs来编写解x(chng)?/p>
创徏Q?如果没有合适的DSL适合你的问题Q你便创ZUDSL来适应你的问题
~程Q?你通过你的概忉|型相对直接的映射到DSLs来编写解x(chng)?/p>
现在Q编E这一步is much less of a 瓉?jin),因?f)DSLs大大化了(jin)如何问题翻译成某种计算够理解的东西Q看h困难已经单的转移C(jin)“创建”这一步,然而,通过联合使用工具支持和将LOP应用到自w,ɘq一步更加简?/p>
LOP 背后的动机基本是q样的:(x)我想用我正试图解决的问题相关的概念和意图的词汇来工作Q而不是被q将我的思想译成某Ugeneral-purpose的语a所能理解的概念Q比如:(x)c,Ҏ(gu)Q@环,条gQ等{?..Q;Z(jin)辑ֈq个目标Q我需要用domain-specific languagesQ怎样得到它们呢?创徏它们Q?
我已l开始开发一个通用的^収ͼthe Meta Programming SystemQ来设计domainspecific languagesQ带有工h持和开发环境;它将允许E序员像现在~写E序一样容易的来定义语aQ这个^台将完全支持LOPQ给E序员(sh)ؓ(f)E序的每一部分选择使用最合适的语言的自由,而不是将他们l在某种固定的general-purpose的编E语a?/p>
MPS 只是Language Oriented Programming的一个示例,管我在q里使用MPS来做CZQ而实际上LOP可以用许多不同的Ҏ(gu)来实玎ͼ你自己就可能知道一些替代方法;LOP 的概念不{同于它的实玎ͼ像OOP的概念不{同于Java或C++或Smalltalk一?/p>
你知道这则古老的谚语Q?If it ain't broke, don't fix it". L~程Ҏ(gu)很明显不完整Q我见过它带来的很多问题Q而大部分滋生于这样一个事实:(x)general-purpose的语a没有一U方法来完全支持L的领域,同样也没有一U统一的domain-specific language;下面是将被LOP解决的主编E中三个最p糕的问题:(x)
Time Delay to Implement Ideas
Ҏ(gu)来说Q最严重的问题是Q在我确切的知道如何解决一个问题,和我通过一个程序成功的向计机传达解决Ҏ(gu)之间Q有一个很长的旉差;我可以用几个时的时间向另外的程序员解释问题和解x(chng)案,而将解决Ҏ(gu)~码到计机中将p长的多的旉Q这是因为对另外的程序员Q我可以使用表达能力非常丰富的自然语aQ而对计算机,我只能用某U表达能力差很多的general-purpose的编E语aQ今天的~程语言只能表达几十U概念,而自然语a能够z的表达千万U概念;因此Q向另外的程序员解释问题Q我可以表达很高层的思想Q而对计算机,我必表达每一步的每一个细?/p>
在主编E中Q大部分花在“编E”上的时_(d)实际上是在寻扄~程层次的抽象的术语来表达自然语a的概늚Ҏ(gu)Q而这是很困难的,没多创造性的Q或多或是一U时间的费
举个例子Q今天大量的开发时间花费在面向对象的设计(OODQ上Q在E序员表辄、ѝ关联等斚wq确实是一U还有创造性的q程Q这实늚目的是用面向对象的术语,如类和方法,来表辄序;OOD的过E是必要的,因ؓ(f)诸如cdҎ(gu){是面向对象语言能够理解的仅有的抽象Q它看v来是必要和有创造性的Q但是用Language Oriented ProgrammingQOODҎ(gu)׃需?/p>
Understanding and Maintaining Existing Code
下一个问题是理解和维护现存(sh)码;不管它是另一个程序员写的q是我写的,问题都一P因ؓ(f)general-purpose的语a需要我把高层的领域概念译Z层的~程语言Ҏ(gu),在最l的E序中,很多高度概括的视角、蓝N丢失?jin);当我在以后重新翻阅程序时Q我不得不通过逆向工程来了(jin)解我最初的意图是什么,我头脑中的模型是什么;臛_Q我必须在脑中重新建造最初在译到general-purpose的编E语a的过E中丢失的信?/p>
解决q个问题的传l方法是写注释或其它形式的文档来记录设计信息和模型信息,已经有几个方面的因素证明?jin)这是一U脆q解决Ҏ(gu)Q至包括编写这些辅助文档的成本、以?qing)文档和代码逐渐不同步的势Qƈ且,q有一个没被广泛认识到的事实,是文档q不能直接连接到它所记录的概念;注释和源代码被绑定到同一个地方,但是概念可能在源代码的多个地方被表达Q其它类型的文档d从源代码中分d来,只能间接的引用源代码Q理x(chng)况下Q代码应该是自我描述的,我应该只阅读代码本n来理解代码,而不是什么注释和外部的文?/p>
Domain Learning Curve
W三个主要的问题是对语言q行领域相关的扩展;例如Q在OOP中扩展语a的主要方法是使用cdQ问题是cd不是用领域概늛关的术语来表辄Q而是用低层的 general-purpose的抽象诸如类和方法等来表达;因此Q库很少能够直接表述领域概念Q它们必d入额外的枝节Q如一个类的运行时行ؓ(f)Q来完成到领域概늚映射Q两个很好的常见例子是GUI库和Database?/p>
学习(fn)q些cd不是一简单的dQ即使你是个领域专家Q因Z领域到语a的映不是直接的Q你必须学习(fn)q种映射Q这意味着一个陡峭的学习(fn)曲线Q通常我们试图用大量的指南和文档来解决q个问题Q但是学?fn)这些将p大量旉Q当一个类库变得复杂的时候,它也变得更难以学?fn),E序员将因此失去学习(fn)它的动机
甚至当掌握了(jin)q种复杂的映之后,依然q(sh)(x)很容易的误用cdQ因为开发环境(像编译器和编辑器Q不能帮助你正确的用类库,对这些工h_(d)调用一个GUI 对象的方法和调用一个DB对象的方法是一L(fng)Q它们都只是对象上的Ҏ(gu)调用Q没有Q何更多的意思;C哪些cdҎ(gu)应该被调用,以什么顺序被调用Q等{,都是使用者的责Q
甚至即你既是领域专家又是类库的使用专家Q也仍然有用类库编写的E序十分冗长的问题;相对单的领域概念需要复杂的措施来正的调用Q例如,M用过Swing的开发者都清楚q一点;~写单的E序已l花费太长的旉?jin),复杂的程序甚x(chng)p?/p>
What Is a Program in LOP?
今天Q百分之?ji)十九(ji)的E序员认为编E就是编写一串计机能够执行的指令集Q我们被教育说计机建立在图灉|模型之上Q因此它们用指o(h)集的术语来“思考”;但是q种~程的观Ҏ(gu)有缺L(fng)Q它h?jin)编E的目的和手D;我将Z演示LOPZ么优?sh)传l编E方法,但首先我必须澄清以下事实Q一个LOP的程序,不是一串指令集Q那么它是什么呢Q?/p>
当我有一个问题要解决Q我在头脑中思考解x(chng)案,q个解决Ҏ(gu)用单词、标记、概c(din)思想Q或者Q何你喜欢的称呼来表述Q它是我头脑中如何解决问题的模型Q我几乎从未把它们想象成一堆指令集Q而是我正在工作的领域中特定的h内在联系的概늚集合Q例如,当我思考GUI领域Ӟ我想象“这个按钮到那边去,q个输入域到q边来,q个l合框里面需要有一些数据的列表”;我甚臛_是在头脑中把它画出来Q根本不用Q何言?/p>
我之所以认U意忉|型是一U解x(chng)案是因ؓ(f)我能够用_的细节向另一个程序员解释q个模型Q他能够坐下来~写一个解册个问题的E序Q比如用 JavaQ;我不需要非得用~程语言的术语来解释q个Ҏ(gu)Q它可以是Q意Ş式;比如Qؓ(f)?jin)解释如何布局一个GUI的窗体,我只需要画?gu)个窗体;如果l画有够的l节Q绘Lw就代表?jin)解x(chng)案;q种领域相关的表q应该就是程序。换句话_(d)应该有一U方法允许我们用这U表qC为真正的E序Q而不仅仅是与其它E序员(sh)的手段Q于是这便导Z(jin)我对E序非正式的定义Q一个程序是M对一个问题无歧义的解x(chng)案,或者,更精一点:(x)一个程序是Ҏ(gu)个领域的某个问题的解x(chng)案的M使用领域相关概念表达的,_定义的模?/p>
q就是我认ؓ(f)E序员应该拥有创Z们自q语言的自q主要原因Q这样他们就能够用更加自然的形式来表达解x(chng)案;General-purpose的语a是无歧义的,但是太冗余和易于出错Q自然语aQ如pQ表达能力十分丰富,但目前它难以使用因ؓ(f)它太不精太不Ş式化?jin);我们需要能够容易的创徏形式化的Q精定义的Q领域相关的语言Q因此Language Oriented Programming不只是~写E序Q还包括创徏用来~写E序的语aQ我们的E序被~写的更接近问题域而不是计机指o(h)集领域,因此它们非常容易的被编?/p>
Programs and Text
Z?fn)惯性的认ؓ(f)E序是作为文本来存储的,也就是说Q一个字节流Qؓ(f)什么不应该是呢Q毕竟有无数的工h~辑、显C、操作文本;今天的编E语a的核?j)部分是文法器,解析器,~译器和面向行的调试器;但是E序的文本只是程序的一U表现Ş式;E序不是文本Q强行把E序塞到文本里引起了(jin)大量你可能还?sh)知道的问题Q我们需要一U不同的Ҏ(gu)来存储ƈ和我们程序一起工?/p>
当编译器~译源代码时Q它把文本解析成UC抽象语法?wi)的树(wi)状l构Q当E序员阅L代码Ӟ他们在脑中做了(jin)本质上相同的事情Q我们仍然不得不考虑E序的树(wi)状结构;q就是ؓ(f)什么我们要有花括号Q方括号Q圆括号{;q也是ؓ(f)什么我们需要格式化和羃q代码和遵守~码规范Q因样就能够更容易的阅读源代?/p>
我们Z么用文本存储呢Q因为当前,阅读和编辑程序最方便和最通用的方法还是用文本编辑器Q但是我们会(x)为此付出代h(hun)Q因为程序的文本表示有重大的~点Q其中最重要的是Z文本的编E语a非常难于扩展Q如果程序以文本的Ş式存储,你就?x)需要一个无歧义的文法器来解析程序;当ؓ(f)语言加入新特性时Q维护语a无二义性的扩展变得日益困难Q我们将需要发明更多类型的括号、操作符、关键字、顺序规则、嵌套,{等Q语a的设计者们p?jin)无数时间来思考语法,q试囑֏现扩展语a的新Ҏ(gu)
如果我们打算让创a变得Ҏ(gu)Q我们就需要将E序的表C和存储从程序本w分dQ我们应该直接将E序存(sh)ؓ(f)l构图,因ؓ(f)q允许我们对语言做Q何我们喜Ƣ的扩展Q有Ӟ我们甚至Ҏ(gu)不需要考虑文本存储Q今天的一个很好的例子是Excel spreadsheet.癑ֈ之九(ji)十九(ji)的hҎ(gu)不需要处理存储格式,当这成ؓ(f)问题时M(x)有各U导入导出功能可用;今天我们使用文本的真正原因是我们没有比文本编辑器更好的编辑器Q但是我们可以改变这一?/p>
问题是文本编辑器很愚蠢,q且不知道如何与E序的图状结构一起工作;但是使用正确的工P~辑器将能够直接和图状结构一起工作,q且能够让我们自q使用M~辑器提供的我们喜欢的可视化表现形式Q我们可以把E序做成文本、表、图、树(wi)、或其它M形式Q我们甚臌Z同目的用不同的表现形式Q比方说Q图形化表示用来览Q文本化表示用来~辑Q我们能够ؓ(f)代码的不同部分用领域相关的表示Q比如ؓ(f)数学公式使用囑Ş化的数学W号Qؓ(f)图表使用囑Ş化的图表Qؓ(f) spreadsheets使用行和列,{等Q我们能够ؓ(f)问题域用最合适的表现形式Q可以是文本Q但不限于文本;最好的表现形式依赖于我们如何思考问题域Q表现Ş式的灉|性也我们的编辑器比以往更加强大Q因Z同的表现形式有不同的方式ȝ辑它?/p>
What Is a Language in LOP?
最后,我应该阐明我认ؓ(f)的“语a”是什么;在LOP中,一U语a是通过三个主要的要素来定义的:(x)l构、编辑器、和语义Q结构定义了(jin)抽象语法、支持的概念、以?qing)如何安排它们;~辑器定义了(jin)具体的语法,如何描绘和编辑语aQ语义定义了(jin)行ؓ(f)Q它如何被解释,?或它如何被{换成可执行代码;当然Q语aq可以有其它斚wQ比如约束和cdpȝ
我已l解释了(jin)Z么我们需要容易的创徏新的语言Q但是,我们如何才能让它Ҏ(gu)呢?如果你turn aroundq个问题Qƈ且把Language Oriented Programming应用于它自nQ你?x)很快看到答案;This calls for a little self-referential bootstrapping, which can seem tricky, but be patient. 一旦你理解?jin)这个,你将得到LOP真正的力量(一个LOP的元层次Q?/p>
回顾一下LOP的理念:(x)使创建DSLs更容易,而这些DSLsɾ~写E序更容易;但就像我已经说明的,LOP中的‘程序’不局限的意味着你用q的典型?“一堆指令集”的E序Q对某个领域中某个问题(sh)Q何无二义性的解决Ҏ(gu)都是‘程序’;因此如果你设想一下“创建新语言”这个领域,那么q个领域中的‘程?’,本n是一U新语言的定义,可以作ؓ(f)一个解x(chng)案来思考,像M其它领域的解x(chng)案一P
因此Q应用LOP的思想Q“创建新语言”更Ҏ(gu)的方法,是创徏一U特定的专注于“创建新语言”这个领域的DSLQ通过应用q些language- building DSLQ我们可以刉新语言更容易;让我们看几种language-building语言的例子,使你更好的理解它们是如何工作的;q里只是一个概qͼ以后的文章我?x)更详细的描q它?/p>
Structure Language
最最,我们需要定义新语言的‘结构’;q是我们何以能够~写“精定义”的E序的原因;语言的结构ƈ不意味着它的文本形式的文法-Q像我提到过的,q种语言甚至Ҏ(gu)没有文本表C只有图形化表示
在实践LOP的时候,大部分情况下Q你?x)工作在两个层次的编E中Q元层次和程序层ơ;你在元层ơ中定义语言Q在E序层次中编写程序;当定义一U新语言的结构时Q你?x)用一Ulanguage-structure DSL来定义你的新语言Q而这Ӟ你将同时工作在这Ulanguage-structure DSL的程序层ơ和新语a的元层次?/p>
在MPS 中,E序层次的每个节炚w有一U“类型”,单的q接到元层次的另一个节点;E序层次的这个节点被UCq种cd的一个“实例”;元层ơ中的“类型”节点则定义?jin)这U类型的实例能够拥有的关pd属性;描述q种元层ơ语al构的语aQ就被简单的UCؓ(f)“Structure Language?/p>
用Structure Language定义一U语a的抽象语法,你应该只是枚举这U语a所有的cdQ类型简单的表示?jin)这U语a支持的特性或者概念;每个概念应该用它的名字、实例的内部属性、实例与其它节点之间的关p(通常是连接)(j)来定?/p>
存在两种可能的关联;W一U是cM聚合的关联,它Ş成了(jin)概念模型的父子树(wi)l构Q第二种是非聚合的,自由形式的关联,它可以连接到pȝ中Q何其它的节点Q关联有两个端点Q源和目标;兌有角Ԍ你可以定义每个角色的名称、每个端点的多重性,每个目标节点的类型;多重性可以是1, 0..1, 0..n, 1..n{,让你能够U束兌可以创徏多少q接Q关联的目标cd可以被用来约束哪些类型的节点可以被连接在一?/p>
因此Q用新语言~写E序包括Q创a中概늚实例、ؓ(f)实例的属性赋倹{根据语a概念定义的关pdE序中的节点q接在一P所有这些将?x)被强大的编辑器支持Q你能够Z的语a定义q种~辑?/p>
Editor Language
那么Q编写和操作概念模型的界面应该是什么呢Q我们的语言需要几U类型的~辑器,但是我们不想要一个通用的编辑器Q经验表明通用的编辑器不能像我们希望的那样有用Q我们希望快速的~写模型Q因此我们需要专为我们的语言概念定做的特D的~辑器;一定程度上Q编辑器是语a的一部分Q而我们的目标是容易的创徏新语aQ那么创建新的编辑器也应该很Ҏ(gu)Q本质上Q我们需要一U创建编辑器的语aQ在MPS中,它被UCؓ(f)Editor Language
当h们听我说我们的程序将存储为图形ƈ且我们需要特定的~辑器,我确信很多h认ؓ(f)我将要谈到图形编辑器Q事实不是这样子的;管E序是图形Ş式,~辑器却不一定非得将E序描绘成图形;事实上,只有数情况下图形编辑器才是有用的(也就是说Q当它合适的时候,比如Ҏ(gu)据库表)(j)Q相反,我们的Editor Language有更好的灉|来源Q讽刺的是,它来自文本编辑器
如果你用文本~辑器浏览一个典型的E序Q你可以惌~辑器被分成?jin)矩形单元;一些单元包含必需的标识如关键字、花括号、圆括号{,其它的单元包含用户定义的标识Q如cdҎ(gu)的名Uͼ大的单元由小的单元组成,像方法块包含语句Q而语句可能包含自q嵌套块;事实上,ML~程语言中Q何良好构造的E序都可以分解ؓ(f)矩Ş单元的集合;那么Q在Editor Language中,你不需要想象这些单元,因ؓ(f)~辑器就是简单的q形单元组成的
单元的用有一些有的优点Q首先,当直接工作在E序囑Ş而不是程序文本上Ӟ单元可以完美的模仿甚臌q标准的文本~辑器;W二Q单元不局限于文本Q你可以往单元里塞q颜色选择器、数学符受图表、矢量图、或M别的什么;最后,q种单元形式的layout是可选的Q程序员可以提供不同的机Ӟ单元形式?layout只是一U有用的~省讄
因此QEditor Language帮助你定义语a中每个概念对应的单元的layoutQ你可以定义哪些部分是不变的Q像括号或其它修饰符P哪些是可变的Q需要用户去定义的;Editor Language也帮助你在你自己的编辑器中加入强大的Ҏ(gu),像自动完成、重构、导航、语法加亮、错误加亮、以?qing)Q何其它你惛_的事情;因此你能够增加现在的~辑器如IntelliJ IDEA{拥有的功能C自己的语a中;q是可能的,因ؓ(f)E序和语a被构造ؓ(f)囑ŞQ而我们有专门的Editor Language帮助我们创造强大的~辑?/p>
Transformation Language
Structure Language和Editor Language已经共同提供?jin)一些功能,你能够用它们和其他h交流思想Q比如画UML图,或者编写其它类型的文档Q然而,大部分时间我们是惌我们的代码做点什么,因此Q我们必LCU方法让它能够执行;有两U主要的方式来做qg事情Q解释和~译
DSLs支持的解释方式帮助定义计机应该如何解释E序QDSLs支持的编译方式帮助定义如何ؓ(f)E序产生可执行代码;我将在以后的文章中讨论对解释方式的支持,现在我想说明一下MPS是如何支持编译方式的
~译意味着拿到源代码,q从中生某UŞ式的可执行代码;对于l果代码有多U可能的形式Qؓ(f)产生可执行代码,你可以生成本地机器码Q也可以生成虚拟机字节码Q或者,你可以生成另外一U语a的源代码Q比如JavaQC++Q,然后用现有的~译器{换ؓ(f)可执行代码;cM的,你甚臛_以生某U解释型语言的源代码Q用现有的解释器解释执行
Z(jin)避免处理q么q泛的目标格式,我们的方法是用MPS来做每一件事Q首先,你在MPS中用Structure Language定义一U目标语aQ这U目标语a和目标格式之间应该有直接的一对一的映;例如Q如果你的目标格式是机器码,你应该用MPS定义一U对应机器码的目标语aQ如果目标格式是Java源代码,你应该定义一U类Java的目标语aQ目标语a不必支持目标格式所有的功能Ҏ(gu),只ؓ(f)你需要的语言Ҏ(gu)进行简单的一对一的映即?/p>
那么现在Q编译分Z个阶D:(x)一个简单的从目标语a到最l结果的译Q一个更复杂的从最初的原始语言C间目标语a的{换;译阶段是微不道的Q因此我们把_֊集中于更有意思的转换阶段Q至,现在的问题简化ؓ(f)?jin)如何将模型从一U语a转换到另一U语aQ但是,有可能源语言与目标语a是完全不同的Q导致{换非常复杂,比如映射一个源节点到许多散布在目标模型中的目标节点Q我们想让定义{换尽可能的简单容易,因此我们需要一U模型{换DSL来帮助我们;在MPS中,q种 DSL被称为Transformation Language
代码生成有三U主要的Ҏ(gu)Q我们将l合使用它们来定义模型{换;W一U是遍历方式Q你枚D源模型中所有节点,(g)视每一个,q基于检视到的信息生成目标模型中的一些目标节点;W二U方式是使用模板和宏来定义如何生成目标语aQ第三种方式是用模式匹配来查找在源模型中的哪些节点上应用{?/p>
我们通过定义DSLs把这些方式结合v来以支持M一U方法;q些DSLs一起工作来帮助你定义从一U语a到另一U语a的{换;例如Q遍历方式激发了(jin) Model Query Language的灵感,它枚D节点和从概念模型中收集信息变得简单容易;你可以把它想象成某种针对概念模型的SQLQ做ZU额外的奖赏Q拥有一U强大的查询语言不只是对代码生成有用Q例如,能够使编辑器更聪明)(j)
Templates
模板Ҏ(gu)工作方式cMVelocity或者XSLTQ模板看h很像目标语言Q但是允怽在模板的M部分中添加宏Q宏本质上是当运行{换的时候被执行的代码段Q宏允许你检视源模型Q用Model Query LanguageQ,q用得到的信息Ҏ(gu)板进行“填I”,得到最l的目标代码
在图5中,你可以看Cؓ(f)概念“Property”生成Java代码的模板的定义Q模板ؓ(f)属性添加了(jin)field declarations, getters, setters{;q个模板是将代码从Structure Language转换为Java的生成器的一部分
既然模板看v来像目标语言Q你可以惌模板是用某种Z目标语言的特D的语言~写的;q也是它事实上的工作方式Q我们实际上使用一个生成器来ؓ(f)你生成模板语aQ而不是手工ؓ(f)每一U可能的目标语言创徏模板语言Q它基本上是复制目标语言Qƈd所有模板特定的Ҏ(gu),诸如宏等Q甚x(chng)板编辑器也是从目标语a~辑器生的Q因此你同样不需要处理代?/p>
当你使用一U模板语a的时候,你可以认为它是用目标语言~写的,只是某些部分的代码是参数化的Q或者是由宏来计的Q这U技术极大的帮助化了(jin)代码生成Q模板还可以用在其它d上,如重构、代码优化、还有更?..
Patterns
模型的模式匹配方法给我们一U作为Model Query Language的代替的查找模型的强大方法;你可以把模式惌成概忉|型的正则表达式;与模板方法类|我们Z源语a产生模式语言Q模式语a看v来像源语aQ只是添加了(jin)一些特性,来帮助你定义处理复杂源模型匹配的灉|的标准;你可以把q种Ҏ(gu)惌成一U强大的“查找替换”的技术;再一ơ,模式语言不只是对代码生成有用Q例如,它们在ؓ(f)源语a~辑器编写自动化的代码检查工h面非常有?/p>
CModel Query Language, template languages, 和pattern languages都由强大的编辑器支持其自动完成、重构、引用检查、错误勘?gu)、等{;即复杂的查询、宏、模式,都可以很Ҏ(gu)的编写;代码生成从来没有q么强大q?/p>
前面有关代码生成的章节带来了(jin)一些关于这些语a如何一起工作的有意思的问题Q事实上有几U方法能让语a一起工作;在MPS中,所有的概念模型都互相知晓;既然语言也是概念模型Q那么便意味着所有的语言都彼此知晓,可以潜在的被q接在一?/p>
语言彼此之间可以有不同的关系Q你能够通过扩展现存的语a来创建新语言Q承所有的概念Q修改其中的一些,q加入你自己的概念;一U语a可以引用其它语言中的概念Q你甚至能将一U语a插入到另一U语a中去Q我在以后的文章中讨论q一步的l节
我们支持Language Oriented Programming的系l需要比元编E能力更多的功能才能更有用;它应该提供程序员?sh)赖于当前的~程语言提供的所有事物:(x)集合Q用L(fng)面,|络Q数据库q接Q等{;E序员(sh)止是单单Z语言本n来选择语言Q例如,Java的大部分功能不是语言提供的,而是有成千上万的framework和API?JavaE序员选择Q他们买的不是Java语言Q而是整个Javaq_QMPS也将有一个它自己的支持^?/p>
在我q入l节前,我们先简要谈一下frameworksQ什么是frameworkQ在L的编E中Q它通常意味着一堆类和方法打包成的一个类库;让我们更q一点的观察q一点,看看在LOP的镜片下我们?x)看C?/p>
我们Z么想要把cdҎ(gu)打包成库呢?E序员(sh)(x)背诵他们的教授曾l告诉他们的Q“复用”;但这只是在原来的位置上留下了(jin)另一个问题:(x)我们Z么要复用cdQ答案是cd在解决特定类型的问题斚w很有用,如制作用L(fng)面,讉K数据库等{;你可以说cd对应着某个领域Q你瞧,我们看到?jin)联p,Class libraries are wannabe DSLs!q个(zhn)伤的事实真令我沮
今天的Domain-specific languages以类库的形式存在Q除?jin)它们不是语aQ没有语a的优势,q拥有类和方法所有的局限;特别的,cdҎ(gu)直接l定C(jin)特定的运行时行ؓ(f)Q而特定的q行时行为是不能修改和扩展的Q因为是提供“类”和“方法”的概念定义的;因ؓ(f)它们不是语言Q类库很被环境Q例如编译器和编辑器Q聪明的支持
我们应该忠于wannabe DSLsQ还是应该拥有当需要DSLs的时候用真正DSLs的自由?当然是自由;每个cd都是为我们的q_创徏一U完全的DSL的候选;例如QJDK的所有类库都应该是MPSq_上的DSLsQ其中一些DSL在现在刚开始的时候不是那么紧急需要,但其它一些从一开始就对^台的功能和可复用性有强烈的媄(jing)响;我将介绍随MPS提供的三U最重要的^台语aQThe Base Language, the Collection Language, and the User Interface Language
Base Language
我们首先需要的语言是对应最单编E领域的Q一Ugeneral-purpose的命令式~程Q这U简单的语言应该支持q乎通用的语aҎ(gu)诸如算术、条件、@环、函数、变量等{;在MPS中我们有q样一U语aQ它被称为Base Language
对这U语a的需求应该是很明昄Q例如,如果我们x(chng)两个数字加在一P我们应该能够单的说一句“a + b”就可以Q我们不需要到处去使用它,但几乎所有的E序都会(x)有一些组成部分用到它Q在那里Q它是完成工作最合适的工具
Base Language之所以如此命名,是因为它是很多需要基本编E支持如变量、语句、@环等的语a很好的基Q它能够以三U方式用:(x)你可以扩展它以创建出你自qZ它的语言Q你可以在你的程序中引用它的概念Q你q可以以Base Language生成你的代码Q将?x)有几种可用的生成器来将Base Language转换成其它语a如JavaQC++{;当然Q不是每U语a都需要用Base LanguageQ但是在很多情况下,它是一个很好的L(fng)
Collection Language
下一U我们需要的最重要的语a是和集合一起工作的语言Q对集合支持的需求是普遍存在的;每种主要的主语a都提供了(jin)寚w合某U类型的支持Q例如,在Java 中你有java.utilQ在C++中你有STLQ每个h都需要集合;如果每种DSL都提供自q寚w合的支持Q那么将?x)有a Babylon of不同的集合语aQ它们互不兼容;q就是ؓ(f)什么MPS必须提供一U每个h都用的单一的Collection Language的原?/p>
在很多主语a中,集合q语言Ҏ(gu)而是cdQ一个例子是Java的java.util包;q种支持技术上来说是存在的Q但它是不方便的Q杂qQƈ且易于出错的
YuckQ今天大部分的Java代码被一行接一行多余的、重复的处理集合的代码弄的杂乱无章;?昄?jin)一个例子,Collection Language是如何beats the tar out of a cd的;例子是一个计一l给定的点的convex hull的算法;更多关于Collection Language的细节会(x)在以后的文章中提?/p>
User Interface Language
User Interface Language是我们的q_中下一U最重要的DSLQ有的是,我前面提到的Editor Language能够另h信服的用来提供用L(fng)面,但是一U专为图形用L(fng)面设计的语言会(x)更灵z;q种语言带来的益处是巨大的;Java Swing代码是一个想成ؓ(f)DSL的类库的极好的例子:(x)功能有了(jin)Q但很容易被误用Qƈ且Swing的代码是d杂ؕ的;很多如今的开发环境都包含GUI builder来简化用L(fng)面的创徏QUser Interface Language把q项d带到一个更高的层次Q我在以后的文章中讨论更多l节
我已l能够听C些对LOP怀疑的反应Q“听h不错Q但是我们的目已经步入正轨Q现在切换到LOP是不可行的”,或者“听h不错Q但用一个像LOPq样的未l检验的Ҏ(gu)来启动一个现实生zM的项目风险太大了(jin)”,或者“听h不错Q但是它什么时候才能ؓ(f)它的黄金时期做好准备呢?别忘?sh)(jin)OOP用了(jin)20q才成ؓ(f)L?/p>
好消息是我们不需要一头扎q未知里Q你可以先用脚趾头试一下水Q你可以在你的项目中只是应用LOP的一块来看一下它有没有提供一些实际的好处Q然后如果你喜欢你可以用多一点;在不q的未来Q你可以在MPS里试验两个可能的LOP应用Q?
Using MPS on Java Applications
已经有一个IntelliJ IDEA的原型插件允怽在你的项目中包含MPS的概忉|型;当你~辑模型Ӟ模型?x)自动在后台被{换成Java源代码;因此Q你可以使用MPS来编?Java应用的部分模块,喜欢用多点就用多点,喜欢用少点就用少点;q意味着你得C(jin)MPS全部的力量,比如创徏和用特定DSLs的能力,做Q何你惌的语a扩展Q同时用定制的带有自动完成、错误加亮、重构功能的~辑器,{等Q插件将和IDEA紧密集成Q允怽在你的MPS模型中嵌入Java代码Q导航到嵌入或生成的Java代码Q甚臌行概念层ơ的调试Q就像IDEA中已l可用的JSP调试支持一P更多集成Ҏ(gu)正在计划中Q这是使用IDEA?Java开发者可用的一个重要的新工?/p>
Configuring and Scripting Your Applications
有一个我见过很多ơ的模式Q一个应用程序启动时需要某UŞ式的配置Q可能是一个简单的配置文gQ或者更完整的部|描q符文gQ最后,配置变的更复杂,应用E序最后需要一U脚本语aQ对于简单的配置文gQXML很流行;对于脚本语言Q你可以创徏自己的,或者借用一Ugeneral-purpose的脚本语aQ像VBScriptQPython/JyphonQTclQJavascriptQ或者LispQ这些方案中的每一U都臛_有一些主编E方法的标准~陷Q很长的实现旉Q陡峭的学习(fn)曲线Q难以扩展,匮乏的环境支持,{等
作ؓ(f)替代的,你能够用MPS创徏你自q配置/脚本语言Q你的应用程序的用户会(x)拥有一U易于用的、智能的~辑器来~写他们的脚本,包括语法加亮Q错误加亮,代码完成Q导航等Q只需p很少的时间来创徏q成这U语aC的应用中Qؓ(f)?jin)用这U应用,你可以分发MPS的运行时
LOP 和MPS背后的思想q不新鲜Q实际上已经出现过20q了(jin)QLanguage Oriented Programming本nq个词也已经提出臛_10q了(jin)Q新鲜的是这些思想一直在软g开发社区默默的渗透,而它们的时代最l到来了(jin)Q通过q篇文章Q我希望提供一颗种子,使这些思想能够产生新的讨论、意见、批评、实验、研I、和最l的真实生活中的目
q且Q因此,我邀(g)请你以Q何你能做到的方式参与到这U新的范型中来;在后面添加评论,或者发送Emaill我Q?a href="mailto:mps_article@jetbrains.com">mps_article@jetbrains.comQ在http://www.jetbrains.com/mps可找到更多,请关注更斎ͼ注意览从LOP的视点出发的|站Q杂志,博客Q书c等Qƈ思考事情到底能够多么简单;考虑一下你自己的项目,看看你有多频J的实际上在设计和用小的特定的用类和方法修补的语言Q你是怎么认ؓ(f)的呢Q我想知?/p>
当我LOP的概는在开发MPS自nӞ我已l看C(jin)Language Oriented Programming是如何彻底改qY件开发的W一手资料;MPS目前q没有ؓ(f)真实世界准备好,但它已经成功的达C(jin)目的Q也q(sh)然没有文档,除了(jin)q篇文章Q我很快的发布更多的文章,深入的探讨MPSQ还有,我计划下月试验着使MPS可下载,因此你的x(chng)要保持张开Q已l有其它的项目用了(jin)cM的方法,特别是来自Intentional Software ?Xactium
因此Q探险愉快,让我看看你能发现什?/p>
?
I would like to thank Rob Harwood for his help in editing this article. I would also like to thank the following people for their reviews, comments, and suggestions: Igor Alshannikov, Florian Hehlen, Jack Herrington, Guillaume
Laforge, Vaclav Pech, Thomas Singer, Dmitry Skavish,David Stennett, and Timur Zambalayev.
Sergey Dmitriev (http://www.sergeydmitriev.com) is the co-founder and CEO of JetBrains Inc.(http://www.jetbrains.com), makers of the IntelliJ IDEA Java IDE.
Articles:
[1] Donald E. Knuth. Literate programming. The Computer Journal, 27, 97-111, May 1984.
[2] M. Ward. Language Oriented Programming.Software - Concepts and Tools, 15, 147-161 1994,
http://www.dur.ac.uk/martin.ward/martin/papers/middle-out-t.pdf
Intentional Programming articles:
Charles Simonyi. The Death of Computer Languages, The Birth of Intentional Programming. 1995.
ftp://ftp.research.microsoft.com/pub/tr/tr-95-52.doc also
ftp://ftp.research.microsoft.com/pub/tr/tr-95-52.ps
John Brockman. Intentional Programming: A Talk With Charles Simonyi. Edge. 2000.
http://www.edge.org/digerati/simonyi/simonyi_p1.html
Microsoft Research. Intentional Programming.
http://www.cse.unsw.edu.au/~cs3141/ip.asf (video)
Charles Simonyi. Intentional Programming: Asymptotic Fun?http://www.hpcc.gov/iwg/sdp/vanderbilt/position_papers/simonyi.pdf
Books:
Krzysztof Czarnecki and Ulrich W. Eisenecker. Generative Programming: Methods, Tools and Applications.Addison-Wesley, 2000. ISBN: 0201309777.
Jack Herrington. Code Generation in Action. Manning, 2003. ISBN: 1930110979. http://www.codegeneration.net/cgia/
Xactium. Applied Metamodelling: A Foundation for Language Driven Development. 2004.
http://albini.xactium.com/content/index.php?option=com_remository&Itemid=28
Other Resources on the Web:
[3] Matt Quail. Totally Gridbag.
http://madbean.com/blog/2004/17/
Jack Herrington. Code Generation Network.
http://www.codegeneration.net/
[4] Intentional Software
http://www.intentsoft.com
[5] Xactium
http://www.xactium.com
Intentional Programming interviews
Sergey Dmitriev.
http://codegeneration.net/tiki-read_article.php?articleId=60
Charles Symonyi.
http://codegeneration.net/tiki-read_article.php?articleId=61
Krzystof Czarnecki.
http://codegeneration.net/tiki-read_article.php?articleId=64
Andy Evans.
http://codegeneration.net/tiki-read_article.php?articleId=68
See Also:
?a id="_254b74700f73c08_HomePageDays_DaysList__ctl0_DayItem_DayList__ctl0_TitleUrl" >Thinking in Current Paradigms, Platforms, Frameworks, and Libraries?
?a id="_254b74700f73c08_HomePageDays_DaysList__ctl1_DayItem_DayList__ctl0_TitleUrl" >Thinking in Current Programming Languages?/p>