|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
数据挖掘有点高深的,主要估计就是使用一些算法提取一些实用的数据。学好数据挖掘的话可以应聘baidu或者google,但是一般人家对算法的要求听高的。你最好还是学点应用型的吧。这种主要是研究型的。比来范畴特定言语(DSL,DomainSpecificLanguages)这个话题对照抢手。这能够从Rails征象中看到。Rails的盛行和Rails上普遍利用的范畴特定言语(从如今起叫DSL),已引发了对DSL的普遍乐趣。
到如今为止开辟职员有如许的印象,创建一个DSL,你必要专业的编译器实际常识,了解Lex和Yacc的外部事情道理并必要投进大批的工夫来构建DSL。了局是少少数人乐意往实验,他们都是重新入手下手构建本人的言语。
这常常是本钱奋发。
同时,静态言语的喜好者能够绝不吃力的使用他们喜好的静态言语的静态特征来构建范畴特定言语。现实上,他们中的很多以这类体例构建的任何使用程序,都有着明显的庞大性。
这两种办法的不同有主要意义。第一种体例是创立属于本人的言语,就是所谓内部的DSL(ExternalDSL)。这是一个耗资伟大的项目,由于统统都要重新入手下手构建,必要思索运算符的优先级划定规矩、运转时类库、实行代码、毛病处置和I/O。第二种办法是使用和修正宿主言语,就是所谓外部的DSL(InternalDSL)。这些都简单构建和保护。你只必要思索怎样修正,一切的别的工具(一般是你不必体贴的)都已被宿主言语处置了。
另外一种做法是构建联贯接口(FluentInterface),把它叫做DSL。我以为这不是一种DSL,这类办法常常在言语的自在性方面遭到很年夜的限定。Java和C#就是很好的例子,包含Java6和C#3。你能够枚举很多言语方面的API,但这不克不及让我以为这是一个DSL。
在任何情形下,我的团体偏好是利用具有很高语法天真性的外部DSL。由于我基础上都是在CLR上事情,我想使用运转在这个平台上的宿主言语。它可让我重用年夜部分的利用CLR的常识,不要低估这方面的优点。在你的手中有一个熟习的情况长短常主要的。
在深切言语之前,看看事实甚么是“高语法天真性的言语”,怎样?为外部DSL供应一个优秀的宿主情况的言语必要具有哪些特征?
我必要有符合的手腕来表达我的设法。这能够经由过程有启示性的定名,表达特定域的观点,并一般和通用言语的做法纷歧样。你但愿可以创立一个第四代言语,这很简单做到。让我们从一个我们电子表格所利用的剧本如许复杂的DSL入手下手怎样?
你的义务就是创立乘法网格。- forxinrange(100):foryinrange(100):cell[x+1,y+1]=x*yformulax,100,sum(x1,x100)
复制代码 这是否是真的使人印象深入呢?这和编程言语几近完整一样,代码也是微乎其微。除和用Excel的主动化API做一样的事情外,更冗长。
注重到这就是我们所用到的一切代码。我们不必要一个类的界说,大概是一个主办法。这是一个没有任何语法累赘的可实行的DSL剧本。
假如后面的例子没有给你留下深入的印象,看看怎样界说定单扣头的营业划定规矩:- apply_discount_of5.percent:whenorder.Total>1000andcustomer.IsPreferredwhenorder.Total>10000suggest_registered_to_preferred:whenorder.Total>100andnotcustomer.IsPreferred
复制代码 这看起来和编程言语有很年夜分歧,它更像营业剖析师在Word文档中界说的营业划定规矩。
从我的角度来看,下面两个例子都是范畴特定言语。他们只是表达范畴的办法微风格分歧。这两个例子,我们实践上已从言语中移除和我们的范畴没有间接干系的工具。这使得我们能够专注于域,并但愿有优秀的工具来处置。
除域观点之外,没有任何工具能够和具有与域相婚配的语法是一样主要的。
当我们入手下手在CLR上研讨高语法天真性的言语的时分,我们有良多的选择。我们来评价几个言语。我们将从几个来自微软的言语入手下手。
C#——这是一个十分刚性的言语,范例界说,没有自力的办法/代码块,生硬的言语。一切这些特征使得C#不是一个DSL宿主言语的好选择。他也能够做到的,但它不如其他办法。
VB.Net——实在VB.Net更合适面向对象的言语,由于它利用了很多英文单词作为关头字和操纵符。使人遗憾的是它也是一个十分冗杂的言语,我们要削减冗余性合适我们的域观点。
JScript——这大概引来一片笑声,可是JScript是一个十分天真的言语,为很多事变供应了较好的语法。只需往看看所供应的一切Javascript类库。JScript供应了和Javascript不异的基本功效。固然如许,有一点不能不思索的是你能够做到像JQuery或Prototype那样多年夜的天真性。但是它不敷成熟,我不断定未来是甚么模样的。固然它在良多方面有天真的语法,给人有种编程言语的感到,这会让我在一个DSL中以为专心。
F#——这是一门由微软开辟的,未来会公布的函数式编程言语。F#撑持面向对象编程。我已大略的扫瞄过这门言语。固然F#的壮大功效使人印象深入,从我的角度来看,它看起来是BNF【译者注:BNF,Backus-NaurForm的缩写,巴科斯范式一种利用情势化标记来形貌给定言语的语法。】界说,其他甚么都不像。毫无疑问这是因为作者缺少函数式编程言语履历方面的成绩,可是我不但是思索它的可读性。
我们已看完微软开辟的言语。让我们看得更远些。据统计客岁CLR上运转的言语凌驾了一百种,以是我选择了两种我以为是DSL宿主言语的候选言语。
Nemerle是一个多范型的言语(面向对象和函数式),完整撑持编译器宏(厥后更多的是Lisp的变种,而不是C++),和很多其他的工具,这使得它是一个DSL很好的宿主言语。这不是我浏览Nemerle代码的复杂来由(常常是如许)。
Boo是一个基于Python语法的静态范例的面向对象的言语。它撑持宏(也是Lisp变种),有一个开放的编译器管道和更简单构建DSL的特征。Boo是我首选的用于构建DSLs的言语,可是为了包管客不雅性,我们必要在会商这个主题之前证实Boo有何等的壮大。
静态言语运转时(DLR)怎样呢?
到今朝为止我还没有会商静态言语运转时,这是一个在CLR之上撑持静态言语的微软项目(今朝撑持Ruby,Python和EcmaScript)。
更详细的来讲,当人们会商DLR的时分,他们是在会商IronRuby和IronPython。
Ruby是一门被证实十分合适写外部DSL的言语,在CLR上运转可使我们在熟习的情况下事情。
利用DLR作为一个DSL的平台固然是大概的,可是我最少在一段工夫内不利用它。DLR和IronRuby自己都仍是在开辟当中。我不以为微软对公布日期会有任何的答应,别的我没有发明Ruby能做的Boo做不了,我以为Boo的元编程基本功效十分天然和壮大。
“天然和十分壮大”是甚么意义?
让我们深切一点考察Boo。我说它有一个开放的编译器,我并非指它是开放源代码的(它是,可是和这个有关),我的意义你有举措深切到编译器的外部和在编译的时分打乱编译器的外部对象模子。这意味着我们能够以一种风趣的体例改动编译器的举动。
下面的两个代码示例都是Boo的DSL代码。
周全深切Boo的元编程基本功效超越了本文的局限,可是我能够用一个复杂的例子来展现它的能力。
CLR已有IDisposable的观点并共同using语句利用。如今我界说一个ITransactionable,将用它来界说一个事件的声明。- publicinterfaceITransactionable:defDispose():passdefCommit():passdefRollback():passmacrotransaction:return[|txasITransactionable=$(transaction.Arguments[0])try:$(transaction.Body)tx.Commit()except:tx.Rollback()raisefinally:tx.Dispse()|]
复制代码 只必要这个代码,我们就能够作为一个优等言语要从来利用该事件的声了然(实践上,这也恰是using语句在Boo的完成体例)。- transactionGetNewDatabaseTransaction():DoSomethingWithTheDatabase()
复制代码 如今,假如代码内里的事件抛出了一个非常,事件将主动回滚。假如它实行是乐成的,事件就主动提交。
不外这只是利用Boo的一个示例。并注重这里我先容的独一一个观点就是宏和风趣的标记[||]。没有更深切的会商,这唆使编译器在事件块外部的代码用宏的内容做了一个代码的交换。
很主要的是这已超出文本交换,我们间接修正AST(AbstractSyntaxTree,笼统语法树---编译器对象模子)。这是一个微乎其微(但很壮大)的例子。我们上面将切磋一个更庞大的场景,这将告知我们为何如许的辨别是主要的。
为了构建一个DSL,这个级其余功效仍是不敷的。你能够只利用Boo言语的语法而不利用元编程功效,相似于Ruby,有良多可选的语法,这在良多场景长短常有效的。举个例子来讲,我们能够欠亨过元编程创立不异的语法,可是使用Boo的这一特征,假如办法的最初一个参数是一个托付(闭包,块等等),能够给办法传送一个代码块。
好比:- deftransaction(txasITransactionable,transactionalActionasActionDelegate):try:transactionalAction()tx.Commit()except:tx.Rollback()raisefinally:tx.Dispse()
复制代码 我们仍旧可使用这代码,正如我们后面所用的:- transactionGetNewDatabaseTransaction():DoSomethingWithTheDatabase()
复制代码 从语法下去看,是没有不同的。不外这两个版本仍是有巨大的不同。CLR确保了假如try程序块可以乐成实行,就进进try程序块实行。这是using()语句准确实行的关头,其他的场景也是一样的。
第一个版本能够使用这个才能,第二个版本不克不及。(缘故原由是第二个版本是在运转时挪用办法,而第一个版本只是交换事件代码块失掉修正后的了局。)
我们还能够使用Boo的元编程做些甚么呢?相称多,关于这个内容能够写一本书(实践上我已写了这方面的一本书:-))。作为一个复杂的例子,而纷歧定是优秀计划的的最好例子,你能够修正言语的if语句的语义。
有一次我不能不如许做,我把if语句修正上面形式:为这个形式:- iffoo==nullorfooisaNullObject:#dosomething
复制代码 如今,当我们反省null的时分,我们也反省这个对象是不是是NullObject的实例,NullObject是我的使用程序中的一个自界说范例。这使得在我的使用程序以一种天然的体例利用NullObject形式。- val=NullObject()#setvaltoanewinstanceofNullObjectifval==null:#willbecompiledasval==nullorvalisaNullObjectprint"Valueisnull"else:print"Valueisnotnull"
复制代码 我们已扩大了言语以为一切承继自NullObject的对象作为null。
从久远来看,有才能往修正言语的基础构成部分是我的事情(和言语的利用)简单很多。
在持续下一步之前来看最初一个例子。我想告知你怎样在Boo使用程序中利用不到20行代码增加一个(复杂的)‘左券式计划’(类稳定式)。这是代码:- [AttributeUsage(AttributeTargets.Class)]classEnsureAttribute(AbstractAstAttribute):exprasExpressiondefconstructor(exprasExpression):self.expr=exprdefApply(targetasNode):typeasClassDefinition=targetformemberintype.Members:method=memberasMethodcontinueifmethodisnullblock=method.Bodymethod.Body=[|block:try:$blockensure:assert$expr|].Block
复制代码 用法以下:- apply_discount_of5.percent:whenorder.Total>1000andcustomer.IsPreferredwhenorder.Total>10000suggest_registered_to_preferred:whenorder.Total>100andnotcustomer.IsPreferred0
复制代码 如今任何把名字设置为null都将招致一个断言非常。这个手艺相称壮大和简单利用。我将前置前提的标志的完成留给读者。
这个例子也树模了间接利用编译器的对象模子(AST)的壮大。我们不范围于C++宏的文本交换,我们能够查询对象模子并以十分天然的体例修正它。那末如今我想你信任Boo是一个十分合适构建DSL的言语。我只是从外表上扫瞄了一下它的潜力,另有良多有待于你的探究。
其他几项上风:Boo是静态编译范例的言语,这意味着你的DSL具有尺度CLR代码的一切上风(立即编译器、渣滓接纳、调试等等)。从功能角度来看,你的使用程序代码和DSL代码没有任何区分。
因而基于Boo的DSL关于常常必要修正和必要高功能的代码是幻想的选择。在产物中不能不改动的如许的配合的需求常常推进人们利用基于XML的体系,划定规矩引擎等。即便没有思索完整“用XML编程”如许的争吵,这些选择都遭受了低功能的成绩。
创建一个利用一系列DSL剧本的体系很简单,从久远来讲,是要供应高功能和高度可保护性的体系。他还必要共同范畴驱动计划,由于有一个范畴特定言语更简单表达天然的域观点。
有几个公然的BooDSL。
我团体喜好的是Binsor。Binsor是一个CasteWindsorIoC容器的设置DSL,使得利用IoC的初级观点轻而易举。你必要懂得Binsor的更多信息能够经由过程会见Binsor2.0公布申明。别的用Boo的DSL是:
Specter是一个举动驱动开辟(BDD)框架,供应了一个十分天然的体例誊写规格并将规格转换为NUnit测试用例。
Brail是一个文本模板言语。
另有几个,可是利用它的人很少,并没有广为人知。
写一个DSL请求有一些开端常识,可是常识是很复杂和简单猎取的。一旦你有了这个基本常识,你就能够入手下手写一个DSL就像制造一个表单那末复杂。
实践上我已写了一个后端处置体系,年夜部分是从各类来历处置动静的DSL构成的。在这个体系中,我写DSL就像在我的体现层上写表单一样的。
整体来讲,Boo是一个用于构建DSL十分好的言语。利用Boo写DSL有助于下降本钱,没有功能和天真性方面的让步。别的,他还供应了自在的语法和天然的体例表达域的观点。
在最初停止时说一句,Boo也能够在Java上运转。
关于作者
OrenEini,也叫AyendeRahien,是一个履历丰厚的.NET开辟者和架构师。他也是好几个开源项目标奉献者,比方NHibernate和Castle。别的,Ayende是RhinoMocks、RhinoCommons和NHibernateQueryAnalyzer的开创人。关于Boo,Ayende创立了CastleMonoRail的模板言语Brail,设置CastleWindsorIoC容器的DSL,他还写了一本题目为《BuildingDomainSpecificLanguagesinBoo》的书。
检察英文原文:《BuildingDomainSpecificLanguagesontheCLR》。
来自:http://www.infoq.com/cn/articles/dsl-on-the-clr
有时也搞不懂应该学那种;主要看你以后去的那个公司是使用哪种了。就像王千祥的课上说的:企业应用现在主要就三层(其实也差不多就是MVC):表示层(主要使用html写的,很简单)、业务逻辑层(主要就是应用服务器的)。最后就是数据层(其实就是学习数据库) |
|