时间很长;现在很短;距离很长;相遇很短
Programing
从Twitter等看企业软件架构(一)
Jun 28th
企业软件发展到现在,普遍面临的一个问题是自身积重难返。系统功能越来越多,数据存储到处都是,技术标准五花八门。几乎任何一个做实施的都头痛每天遇到的各种历史遗留问题。事情就是这样,企业软件已经是一个构造复杂的精密系统,无数的管道线路纠结在一起,牵一发而动全身,难以为继。
问题
看一下业务流程管理技术趋势图:
摆在面前的当务之急就是SOA化的系统结构,然而,除了在政府机构有比较好的案例意外,其他行业鲜有成功的事实,原因又在哪里呢?不负责任的分析一下,至少有以下几点:
对庞大的现有系统改造成本巨大,SOA是需要一个规模效应的,当系统间不断的整合才能发挥其低耦合的结构特,在此之前的投入往往会被看成是不值得的,这里有一个门槛效应。
业务和技术要求高,SOA不仅是一个技术课题,也是一个业务课题。当前大多数机构和组织的设计能力还不能达到全面应用的要求。软件架构往往在分布式和集中式之前博弈,分布式的高要求往往让很多项目选择折中的方案。“二步提交”等分布式系统特有的技术问题带来的风险考验开发人员的能力和系统的综合管理能力。
规格差异化,各厂商为了自己的利益,推广各自的方法论,互相之间缺乏沟通,壁垒明显,势必造成技术推广的困难。
巨大的挑战面前是巨大的市场,SOA默默挣扎了这么多年,依然坚挺,其背后是非常不错的理论架构。
一种思路
其实说穿了,SOA无非就是解决系统整合的方式,互联网是分布式系统的基础,而Web2.0是内容和服务整合最成功的例子。
翻开Twitter, FriendFeed, Facebook的API文档,绝对找不到一个ESB,SOA的名词,能看到的无非是JSON, XML, RSS, ATOM,或者单独说个REST。但是解决的问题和SOA是一样的,系统整合,标准协议,高可用性,服务寻址等等。但他们看起来很不规范。从某种意义上说,属于SCA(Service Component Architecture)的理念。
SCA与SOA最大区别就是给服务实现松绑,很多实现不需要再去应用个别高端厂商发明的WS-*,可以更灵活的应用互联网上被验证有效的方式。SCA保留了SOA理念中的核心,更加强调组件的概念,弱化技术性的限制。SCA是个非常复杂的主题,这里是一个相对容易理解的SCA白皮书。
比较一下几种格式,或许能看得更清楚:
| 数据格式 | 可读性 | 数据转换 | 扩展性 | 开发难度 |
| SOAP | 较差,所有格式中最复杂的 | 较容易,可以根据定义生成类型 | 可扩展,有一定难度 | 很高 |
| XML | 看设计能力 | 需自定义转换规则 | 任意扩展/或利用命名空间 | 较高 |
| JSON | 清晰易懂 | 没有类型定义,在强类型端处理困难 | 任意扩展,缺少规则 | 简单 |
| RSS/ATOM | 比较清晰 | RSS多种不同版本,ATOM相对统一一些,整体来说较简单 | 通过命名空间扩展 | 一般 |
| YAML | 可读性最好 | 可以容易的序列化与反序列化 | 任意扩展,缺少规范 | 简单 |
从以上比较不难看出,单纯从开发和功能上讲,新的YAML最有优势,也容易继续改良取长补短。而标准最多的SOAP实在是有点笨重,难以和新格式竞争。
未完待续
笔记:DSL之二 使用DSL
Jun 23rd
这篇笔记的内容来自MF http://martinfowler.com/dslwip/UsingDsls.html
领域特殊语言(Domain Specific Language)定义
a computer programming language of limited expressiveness focused on a particular domain.
关注特定领域表述有限的计算机程序语言
四个重要元素
- computer programming language:A DSL is used to humans to instruct a computer to do something, as well as helping communication between humans.
计算机语言 DSL帮助用户与计算机交互,同时辅助人与人的交流。 - language nature: A DSL is a programming language, and as such should have a sense of fluency where the expressiveness comes not just from individual expressions but also the way they can by composed together.
语言属性 DSL是一个程序语言,拥有流畅的表述形式,且能够组合完成逻辑。 - limited expressiveness: a general purpose programming language provides lots of capabilities, supporting varied data, control, and abstraction structures. All of this is useful but makes it harder to learn and use. A DSL supports a bare minimum of features needed to support its domain. You can’t build an entire software system in a DSL, rather you use a DSL for one particular aspect of a system.
有限的表述 与通用语言相比,DSL应当只对针对的领域做有限的支持,因此,不应当用DSL实现一个完整的应用。 - domain focus: a limited language is only useful if it has a clear focus on a limited domain. The domain focus is what makes a limited language worthwhile.
领域关注 当明确针对一个特定领域时,有限语言显得非常有用。
DSLs的边界
DSLs的边界很难明确定义,有些语言和工具,在针对特殊问题是表现了DSL的某种特性,但是他们并不能算做DSLs
If a uses a DSL for its purpose then it stays a DSL, but if someone uses a DSL in a general purpose manner, then it’s no longer a DSL (in this usage).
这种模糊并不关键,只要工具有用就行了,使用DSL的观点设计和使用软件,是否能够给软件工程带来总体上的优越性是我们主要关注的课题。
DSL片段与独立程序
DSL可以是一个独立的程序,构建于整体模型之上;也可以是一段执行片段,比如正则表达式,嵌入程序中的SQL等等。
使用DSL的理由
加快开发效率(Improving Development Productivity)
DSL产生了更加简洁,有效的代码,更好的遵守DRY原则,同时有限的语言也避免了很多程序错误的产生。
促进与领域专家的沟通 (Communication with Domain Experts)
这里不是说一个COBOL式的幻想,我们不主张让领域专家来用DSL编写业务规则,程序就能够运行。不过DSL简洁生动的语法,的确更容易被领域专家阅读和接受,从而缩小业务模型与程序模型之间的差距。
在执行上下文中改变 Change in Execution Context
在执行上下文中改变。从而极大的提高了系统的配置化程度,提升其应用功能价值。
可替换的计算模型 Alternative Computational Model
基于领域模型之上,可以更加灵活的设计计算模型,从而完成业务沉淀。
DSLs存在的问题
- 学习曲线
任何一项技术都是有难度的 - 构建花费
构建DSL要求更加精确,但其花费并不是在DSL,而在构建模型本身。 - 设计难度
DSL很难设计,因为它就像类库一样,因此,这种难度也不是DSL带来的,应当是问题域本身的难度。 - 新的DSL的学习难度
DSL构建出来的语言也是需要学习的,不过这取决于DSL本身的设计。 - DSL版本迁移
API已经有很多重构的工具和方法可以使用,DSL还缺乏这些东西,当然内置式的DSL完全可以用载体语言来实现。
DSLs生命周期
很多不同的方式:
Model –> API –> DSL
DSL –> senarios –> functions
Frameworks –> controllers –> DSL
笔记:DSL之一 简介
Jun 22nd
打算从今天开始,系统的学习一下DSL相关技术。
这个系列的所有文档都来自于MF的BLIKI中的Domain Specific Languages,其余文字都是对其的理解和整理。
关于什么是DSL,之前的文章有提到过。
简单的说
DSL与通用语言相区别,是为特定目的而生的语言,它并不是什么新东西,历史几乎和计算机的历史一样长。
DSL的应用广泛而常见,比如CSS,比如Wiki。DSL通过分析特定问题域提炼动态模型,从而标准化问题处理流程。
恩,先从MM图看起:

重点概念
DSL的类型
DSL可以分为内部DSL(Internal DSLs)和外部DSL(Internal DSLs),主要区别在于其与实现语言的关系。
内部DSL的语法是其实现语言的子集,典型的如Ruby;外部DSL通常是定制的特殊语法,如HQL。
Language Workbenches 也是DSL实现的方式之一,特定的平台有其特殊性。
API风格的区别
传统意义的程序语言,在实现具体逻辑的时候,往往是一种命令查询风格API ;而DSL通常是口语化接口。
程序比较,都用Java实现
命令查询风格
Event doorClosed = new Event("doorClosed", "D1CL");
Event drawOpened = new Event("drawOpened", "D2OP");
Event lightOn = new Event("lightOn", "L1ON");
Event doorOpened = new Event("doorOpened", "D1OP");
Event panelClosed = new Event("panelClosed", "PNCL");
Command unlockPanelCmd = new Command("unlockPanel", "PNUL");
Command lockPanelCmd = new Command("lockPanel", "PNLK");
Command lockDoorCmd = new Command("lockDoor", "D1LK");
Command unlockDoorCmd = new Command("unlockDoor", "D1UL");
State idle = new State("idle");
State activeState = new State("active");
State waitingForLightState = new State("waitingForLight");
State waitingForDrawState = new State("waitingForDraw");
State unlockedPanelState = new State("unlockedPanel");
StateMachine machine = new StateMachine(idle);
idle.addTransition(doorClosed, activeState);
idle.addAction(unlockDoorCmd);
idle.addAction(lockPanelCmd);
activeState.addTransition(drawOpened, waitingForLightState);
activeState.addTransition(lightOn, waitingForDrawState);
waitingForLightState.addTransition(lightOn, unlockedPanelState);
waitingForDrawState.addTransition(drawOpened, unlockedPanelState);
unlockedPanelState.addAction(unlockPanelCmd);
unlockedPanelState.addAction(lockDoorCmd);
unlockedPanelState.addTransition(panelClosed, idle);
machine.addResetEvents(doorOpened);
口语化风格
doorClosed. code("D1CL");
drawOpened. code("D2OP");
lightOn. code("L1ON");
panelClosed.code("PNCL");
doorOpened. code("D1OP");
unlockPanel.code("PNUL");
lockPanel. code("PNLK");
lockDoor. code("D1LK");
unlockDoor. code("D1UL");
idle
.actions(unlockDoor, lockPanel)
.transition(doorClosed).to(active)
;
active
.transition(drawOpened).to(waitingForLight)
.transition(lightOn). to(waitingForDraw)
;
waitingForLight
.transition(lightOn).to(unlockedPanel)
;
waitingForDraw
.transition(drawOpened).to(unlockedPanel)
;
unlockedPanel
.actions(unlockPanel, lockDoor)
.transition(panelClosed).to(idle)
;
DSLs实现模型
实现DSL,主要是针对特定问题域进行动态状态建模,模型可以是任意的:对象模型,结构化模型或者其他的任何实现模型;程序语言通常会很关注语法以及语义,DSLs中的建模主要就是为了建立问题域的描述语义。
DSLs实现方法
代码生成(Code-Generation)和解释运行(Interpretation)是DSL的两种实现方式,前者在编译时处理模型,后者在运行时应用模型。
从实现的角度来讲,前者更加快捷方便,而后者更加精致有效;短期看代码生成可以很快应用,长期看解释运行更能形成效益。