D2js 的邦联式架构
d2js 的接口单独看有点像小手工业者,每个人摆弄着自己的小功能,但是在 update 的一声号令下,它们也可以组合起来,发挥出整体的功效,变为流水线上的工人——这一切是自然而隐蔽的进行的,小手工业者不需要为进工厂而改变自己。
这是怎么做到的呢?
d2js 的接口可以通过浏览器地址栏调用。
以下面的接口为例:
d2js.exports.test = d2js.test = function(params){
return {result : params.a + params.b}
}
在浏览器地址栏输入:
http://localhost:8080/d2js/test.d2js?_m=test¶ms={%22a%22:1,%22b%22:2}

除了以json方式提供params,还可以分散在query string提供。
以该方式提供参数会视被为字符串:

需要在接口中做参数转换:
d2js.exports.test = d2js.test = function(params){
$V(this, params, {a: [T.int], b: [T.int]})
return {result : params.a + params.b}
}
d2js 接口加以导出即可通过浏览器直接访问,使用浏览器地址栏就可以随意注入参数进行测试,这为后端开发提供了很大便利。
作为普通函数,d2js 可以在其它函数中调用,如:
d2js.test2 = function(params){
var a = params.a, b = params.b
return this.test({a: a * a, b: b * b})
}
可以在另一个d2js中调用:
d2js.test2 = function(params){
var a = params.a, b = params.b
return this.callD2js('test.d2js', 'test', [{a: a * a, b: b * b}]);
}
可以使用表单调用:
<form method="post" action="test.d2js?_m=test">
a: <input type="number" name="a">
b: <input type="number" name="b">
<input type="submit">
</form>
也可以使用 ajax 调用:
$.get('test.d2js', {_m : 'test', params: JSON.stringify({a:2, b:3})},
function(s){
console.log(s)
});
用表单方式得到的是一个奇怪的 JSON 页面,不过这没有关系,通过一个简单的 wrapper 即可满足表单使用场景:
d2js.exports.formEntry =
d2js.formEntry = function(params){
var result = this[params._entry](params);
this.request.setAttribute('result', result)
this.request.servletContext
.getRequestDispatcher('/test.jssp')
.forward(this.request, this.response);
this.out.print('') //阻止输出{success:true}
}
用法:
<form method="post" action="test.d2js?_m=formEntry">
<input type="hidden" name="_entry" value="test">
a: <input type="number" name="a">
b: <input type="number" name="b">
<input type="submit">
</form>
test.jssp:
<html>
[%
var result = request.getAttribute('result')
%]
<body>
<h1>[%= result.result %]</h1>
</body>
<html>
如需完全满足表单式应用场景, formEntry 函数还需要进一步完善,如实现跳转词典等等。
d2js 接口支持 POST,PUT,GET,DELETE 语义,分别对应 modify, create, fetch, destroy 四个接口,也就是说,在上述配对情形中使用,可以不提供 _m 参数。
一个典型的 d2js 文件具有 crud 四接口:
d2js.fetch = function(){
sql{.
select .. from …
.}
return this.query(sql, params);
}
d2js.create = function(rcd){
this.insertRow('table', rcd)
}
d2js.modify = function(rcd){
this.updateRow('table', rcd)
}
d2js.destroy = function(rcd){this.deleteRow('table', rcd)
}
这四个接口都可以像上面一样独立使用。
不仅如此,create, modify, destroy 三接口还可以被前端聚合!
d2js 框架前端是一个主要为 DataTable 形态的数据结构。DataTable 可以改动多行,一起提交:
table.rows[0]._set('name', 'Jack')
table.rows[1]._set('name', 'Mike')
table.rows[2].remove();
table.addRow({name:'Mary'});
table.submit();
submit 函数调用时,上面代码中表的四行变动汇总为一个表变动信息,合并提交至 D2JS.prototype.update 函数,D2JS.prototype.update 函数根据行状态(edit,remove,new),调用相应的函数(modify, destroy, create)。该函数内为一个循环,处在一个事务中,一旦出错全体回滚。
此外,前端还支持表间关联,提交父表时,可连带提交子表。
提交多行的例子可参见 https://github.com/inshua/d2js 提供的示例。
下面是例子中提交的JSON数据:
{
"_m":"update",
"table":{
"name":"author",
"src":"/d2js/d2js-test/author.d2js",
"columns":[
...
],
"rows":[
{
"id":1,
"name":"曹雪芹",
"email":"caoxueqin@gmail.com",
"tel":"111222333",
"remarks":"曹雪芹先生是伟大的作家",
"gender":"M",
"info":{
"linkin":"123456aabb"
},
"_state":"edit",
"_idx":0,
"_origin":{
"id":1,
"name":"曹雪芹",
"email":"caoxueqin@gmail.com",
"tel":"111222333",
"remarks":"曹雪芹先生是伟大的作家",
"gender":"M",
"info":{
"linkin":"123456aa"
}
},
"_children":[
{
"name":"book",
"src":"/d2js/d2js-test/book.d2js",
"columns":[
...
],
"rows":[
{
"id":7,
"title":"红楼梦2",
"kind":"f",
"publish_date":"1977-02-03T00:00:00.000Z",
"isbn":"2323121",
"remarks":null,
"author":1,
"author_name":"曹雪芹",
"_state":"edit",
"_idx":0,
"_origin":{
"id":7,
"title":"红楼梦",
"kind":"f",
"publish_date":"1977-02-03T00:00:00.000Z",
"isbn":"2323121",
"remarks":null,
"author":1,
"author_name":"曹雪芹"
}
}
]
}
]
}
]
}
}
根据数据提到的 src,和行状态,D2JS.prototype.update 函数会为为执行相应入库动作。
可见,d2js 接口解耦程度极高,可聚可分,可联合作战,可独立作战,可用于 ajax 方式,表单方式、DataTable 方式,适合与各种前端模型混搭——当然,搭配 d2js 前端使用更珠联璧合。
这套架构可以称为邦联式架构,每个接口都是独立的能行驶职能的政权,但也可以随时结合为一个更大的政权结构。
D2js 的邦联式架构的更多相关文章
- C#实现插件式架构的方法
插件式架构,一种全新的.开放性的.高扩展性的架构体系.插件式架构设计近年来非常流行,基于插件的设计好处很多,把扩展功能从框架中剥离出来,降低了框架的复杂度,让框架更容易实现.扩展功能与框架以一种很松的 ...
- 转发-基于ASP.NET MVC 4/5 Razor的模块化/插件式架构实现
基于ASP.NET MVC 4/5 Razor的模块化/插件式架构实现 概述 在日常开发中, 我们经常谈起模块化/插件化架构,这样可既可以提高开效率,又可以实现良好的扩展性,尤其对于产品化的系统有 ...
- client-server model peer-to-peer architecture 主从式架构
w https://zh.wikipedia.org/wiki/主从式架构 主从式架构 (Client–server model) 或客户端-服务器(Client/Server)结构简称C/S结构,是 ...
- 基于ASP.NET MVC 4/5 Razor的模块化/插件式架构实现
概述 在日常开发中, 我们经常谈起模块化/插件化架构,这样可既可以提高开效率,又可以实现良好的扩展性,尤其对于产品化的系统有更好的实用性. 架构 我们采用的是MVC5(本文中介绍的方法对于MVC4也是 ...
- Distributed--分布式架构
如果我们期望实现一套严格满足ACID特性的分布式事务,很可能出现的情况就是在系统的可用性和严格一致性之间出现冲突. 在可用性和一致性之间,永远无法存在一个两全其美的方案. 从集中式到分布式 集中式系统 ...
- MySQL-19-分布式架构MyCat
MyCAT基础架构图(实验环境) MyCAT实验环境准备 1 环境准备 两台虚拟机: db01(10.0.0.51) db02(10.0.0.52) 每台创建四个mysql实例:3307 3308 3 ...
- 响应式架构:消息模式Actor实现与Scala、Akka应用集成
这是一本最近很流行的书. 有时间就去看看
- ASP.NET MVC:模块化/插件式架构实现(转载)
I’ve recently spent quite a lot of time researching and prototyping different ways to create a plugi ...
- HDFS 架构解析
本文以 Hadoop 提供的分布式文件系统(HDFS)为例来进一步展开解析分布式存储服务架构设计的要点. 架构目标 任何一种软件框架或服务都是为了解决特定问题而产生的.还记得我们在 <分布式存储 ...
随机推荐
- 前端少侠的ps故事
前端少侠的ps故事 正所谓,码在江湖,身不由己.自21世纪前后端分离,代码分工细化以来,前端与设计的合作也变得越来越重要.有人说,如果前端懂设计的话,工作会更快一点.倘若说我入前端半年能算半个前端少侠 ...
- 由Photoshop高反差保留算法原理联想到的一些图像增强算法。
关于高反差保留的用处说明呢,从百度里复制了一段文字,我觉得写得蛮好的: 高反差保留就是保留图像的高反差部分,再说得真白些,就是保留图像上像素与周围反差比较大的部分,其它的部分都变为灰色.拿一个人物照片 ...
- Python元组
Python的元组与列表类似,不同之处在于元组的元素不能修改. 元组使用小括号,列表使用方括号. 元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可. 如下实例: tup1 = ('physi ...
- ubuntu源笔记
比如说清华大学的ipv6镜像源:https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu/ /etc/apt/sources.list为包管理工具apt的软件包 ...
- 用Tensorflow让神经网络自动创造音乐
#————————————————————————本文禁止转载,禁止用于各类讲座及ppt中,违者必究————————————————————————# 前几天看到一个有意思的分享,大意是讲如何用Ten ...
- odoo种种
[精]Odoo 8.0深入浅出开发教程-模块开发基础 http://blog.csdn.net/sunansheng/article/details/50864527 搭建odoo开发调试环境 htt ...
- Keepalived的全局配置
Keepalived的全局配置 默认配置文件如下: ! Configuration File for keepalived global_defs { notification_email { aca ...
- NodeJs入门学习(一)
NodeJs是针对前端工程师向web后端深入理解的一门很好的语言. 首先,记录NodeJS几大特性,后续补充: 一.Node.js 是单进程单线程应用程序,但是通过事件和回调支持并发,所以性能非常高. ...
- 百度文库下载器 V2.3.4.3 支持豆丁百度文库道客巴巴
支持豆丁百度文库道客巴巴免下载劵财富值导出word 下载地址: http://pan.baidu.com/s/1qYCmQde
- Oracle查询时间字段并排序
select * from geimstatus_history twhere to_date(t.data_time,'YYYY-mm-dd') = to_date(sysdate,'YYYY-mm ...