- 浏览: 1701089 次
- 性别:
- 来自: 杭州699号
文章分类
最新评论
-
莫莫摸:
为什么不用dubbo
RCP数据传输模型回顾 -
大胡子爸爸:
String, Class 都实现了Serializable接 ...
RPC框架几行代码就够了 -
lss598018587:
谢谢大神分享,比起新手看复杂的dubbo框架还不如看大神的这一 ...
RPC框架几行代码就够了 -
15606915740:
你好,请问一下。<dubbo:consumer filt ...
Dubbo文档 -
joqk12345:
...
一些设计上的基本常识
首先,将Java中的Method分成:Subroutine和Function两种,
按照“契约式设计原则”的说法,Subroutine是有副作用的(side-effect),而Function是没有副作用,
语法上,Subroutine通常没有返回值,即void方法,而Function则有返回值,
比较明确的是,模板肯定不允许调用Subroutine,否则肯定会引入大量业务逻辑,
现在待讨论的是,模板中是否允许调用Function?
如:
${object.funtion(arg1, arg2)}
衍生出的还有静态Function:
${funtion(arg1, arg2)}
在CommonTemplate(http://www.commontemplate.org)设计之初,
是禁止调用Function的,因为Function会使模板复杂化,通常可以用其它更好的方式表达:
1.无参的Function,可以直接去掉括号,简化成属性方式,如:
String.trim
String.toUpperCase
List.size
Number.toString
等等
2.有参的Function,也可用其它更形象化的操作符处理,如:
用Map[key]代替Map.get(key)
用List[2..4]代替List.subList(2, 4),
将String看作char[]数组,用String[2..4]代替String.substring(2, 4),用String[2]代替String.charAt(2),
用"aa" ~= "AA"(约等于) 代替 "aa".equalsIgnoreCase("AA")
等等
通常处理的Domian对象,都是POJO,基本数据类型,集合类等,
如果标准包对这些都支持的比较好,那禁掉Function看起来是可行的。
然而,标准包不可能想到用户所有的需求,
所以必需留给用户容易实现的扩展点,
以最近版本加入的orderby为例,
假设其不在标准包,而是用户自己扩展实现的,
需求定义:
实现集合类的按属性排序,如:
$for{book : books}
其中,books是一个包含Book的集合,Book是一个POJO,有title, price等属性
现需要在循环之前对books按价格排序,当然可能是升序或者降序,也可能是多个属性,
有三种方案可以实现:
1.扩展静态方法:
$for{book : orderby(books, "price")}
JSP2.0的EL和Velocity就是用的类似此方案
2.扩展对象方法:
$for{book : books.orderby("price")}
3.扩展二元操作符:
$for{book : books orderby "price"}
如果禁止方法调用,当然也应禁止静态方法,
那就只能用第三种,操作符扩展,
但如果这种需求很多,会不会使操作符的数量骤增,
表达式的可读性及易用性都会降低,
看起来,第二种方案比较合理,通过在外部给集合类扩展一个方法,
但就因为这,开启Function调用,是否应该?
而且视图层又没参与持久化,哪来只读可写之分
以Webwork或Struts2的Action为例,通常用setXXX表示Form传入数据,用getXXX表示页面展示数据,难道强迫用户getter和setter写全?那样契约性会变差(无法表示这个Action需要什么参数,呈现什么数据),而且不必要的setter可能造成安全问题,如订单额只读,而不能setter等。
i m sorry ,why dont you follow JavaBeans Specification?why? 活该!
用户会反过来,我不用这个工具了,这点事都处理不了,你活该,呵呵
不是Object.get*都行,必须有对应的set*,才允许调,单纯的get*,很多都是业务性质的函数,比如查询方法。^_^
那如果是只读属性呢?
不是Object.get*都行,必须有对应的set*,才允许调,单纯的get*,很多都是业务性质的函数,比如查询方法。^_^
符合javaBean规范的function调用要支持。
...
也就说,建议,对符合javaBean规范的function调用支持,比如formBean.tag,就必须有getTag,和setTag才允许调用
这个肯定是支持的,bean.getProperty()和bean.isProperty()都可以用bean.property调用,
非符合Bean规范的部分也支持(因为JDK中不是所有取值函都支持Bean规范),如:String.trim,List.size等
我感觉只要有个方法调用的许可策略就可以了
这个想法不错,规则可定义比较好,
如,可定义许可:
Object.get*, Object.is*, String.trim, List.Size
而像remove等禁止。
(注:List的remove方法违反契约式设计原则,它不是无副作用的函数,但却有返回值)
现在,模板引擎把bean.function(arg1, arg2)的语法解析已经实现了,
只是在配置中,加了一项:
functionAailable=false
默认禁止,如果实在需要,可自行开启。
算是中庸的解决办法。
按照“契约式设计原则”的说法,Subroutine是有副作用的(side-effect),而Function是没有副作用,
语法上,Subroutine通常没有返回值,即void方法,而Function则有返回值,
比较明确的是,模板肯定不允许调用Subroutine,否则肯定会引入大量业务逻辑,
现在待讨论的是,模板中是否允许调用Function?
如:
${object.funtion(arg1, arg2)}
衍生出的还有静态Function:
${funtion(arg1, arg2)}
在CommonTemplate(http://www.commontemplate.org)设计之初,
是禁止调用Function的,因为Function会使模板复杂化,通常可以用其它更好的方式表达:
1.无参的Function,可以直接去掉括号,简化成属性方式,如:
String.trim
String.toUpperCase
List.size
Number.toString
等等
2.有参的Function,也可用其它更形象化的操作符处理,如:
用Map[key]代替Map.get(key)
用List[2..4]代替List.subList(2, 4),
将String看作char[]数组,用String[2..4]代替String.substring(2, 4),用String[2]代替String.charAt(2),
用"aa" ~= "AA"(约等于) 代替 "aa".equalsIgnoreCase("AA")
等等
通常处理的Domian对象,都是POJO,基本数据类型,集合类等,
如果标准包对这些都支持的比较好,那禁掉Function看起来是可行的。
然而,标准包不可能想到用户所有的需求,
所以必需留给用户容易实现的扩展点,
以最近版本加入的orderby为例,
假设其不在标准包,而是用户自己扩展实现的,
需求定义:
实现集合类的按属性排序,如:
$for{book : books}
其中,books是一个包含Book的集合,Book是一个POJO,有title, price等属性
现需要在循环之前对books按价格排序,当然可能是升序或者降序,也可能是多个属性,
有三种方案可以实现:
1.扩展静态方法:
$for{book : orderby(books, "price")}
JSP2.0的EL和Velocity就是用的类似此方案
2.扩展对象方法:
$for{book : books.orderby("price")}
3.扩展二元操作符:
$for{book : books orderby "price"}
如果禁止方法调用,当然也应禁止静态方法,
那就只能用第三种,操作符扩展,
但如果这种需求很多,会不会使操作符的数量骤增,
表达式的可读性及易用性都会降低,
看起来,第二种方案比较合理,通过在外部给集合类扩展一个方法,
但就因为这,开启Function调用,是否应该?
评论
11 楼
javatar
2007-11-28
实现函数功能时,
发现一个有趣的事情:函数就是非符号(与变量名同规则)的一元操作符,
如:定义一个非符号一元操作符:abs (取绝对值操作),
则其写法应为:
${abs -1},
但这样,abs和变量名引起歧义,会把abs当成变量,然后减1。
所以应写成:
${abs(-1)}
用括号加强优先级。
这样,也就变成了函数的风格。
当然也能在复杂情况使用:
${2 + abs(abs(-1) - 3)}
基于此,如果配置:
functionAvailable=false
将禁止非符号的一元操作符。
发现一个有趣的事情:函数就是非符号(与变量名同规则)的一元操作符,
如:定义一个非符号一元操作符:abs (取绝对值操作),
则其写法应为:
${abs -1},
但这样,abs和变量名引起歧义,会把abs当成变量,然后减1。
所以应写成:
${abs(-1)}
用括号加强优先级。
这样,也就变成了函数的风格。
当然也能在复杂情况使用:
${2 + abs(abs(-1) - 3)}
基于此,如果配置:
functionAvailable=false
将禁止非符号的一元操作符。
10 楼
javatar
2007-11-27
leadyu 写道
而且视图层又没参与持久化,哪来只读可写之分
以Webwork或Struts2的Action为例,通常用setXXX表示Form传入数据,用getXXX表示页面展示数据,难道强迫用户getter和setter写全?那样契约性会变差(无法表示这个Action需要什么参数,呈现什么数据),而且不必要的setter可能造成安全问题,如订单额只读,而不能setter等。
leadyu 写道
i m sorry ,why dont you follow JavaBeans Specification?why? 活该!
用户会反过来,我不用这个工具了,这点事都处理不了,你活该,呵呵
9 楼
leadyu
2007-11-25
其实,我觉得jindow的想法蛮好,你可以把策略这层抽象出来,
类似JDK里面reflect里面的PrivilegeControl,在所有方法调用前拦截。
我只是提出这个策略干脆就以javaBean规范为准算了,毕竟广为接受,同时能够很好的规避业务方法。
当然,bean.size,map.key,这些可以例外,至于你说的问题,你想想有没更好的策略了。只是单纯get*个人认为是不合适的。
至于只读属性,我只能说 i m sorry ,why dont you follow JavaBeans Specification?why? 活该!
而且视图层又没参与持久化,哪来只读可写之分,呵呵。当然你可以想想这个策略。
类似JDK里面reflect里面的PrivilegeControl,在所有方法调用前拦截。
我只是提出这个策略干脆就以javaBean规范为准算了,毕竟广为接受,同时能够很好的规避业务方法。
当然,bean.size,map.key,这些可以例外,至于你说的问题,你想想有没更好的策略了。只是单纯get*个人认为是不合适的。
至于只读属性,我只能说 i m sorry ,why dont you follow JavaBeans Specification?why? 活该!
而且视图层又没参与持久化,哪来只读可写之分,呵呵。当然你可以想想这个策略。
8 楼
javatar
2007-11-24
leadyu 写道
不是Object.get*都行,必须有对应的set*,才允许调,单纯的get*,很多都是业务性质的函数,比如查询方法。^_^
那如果是只读属性呢?
7 楼
javatar
2007-11-24
6 楼
bigpanda
2007-11-23
要是不允许函数调用怎么处理递归数据呢?
5 楼
leadyu
2007-11-23
不是Object.get*都行,必须有对应的set*,才允许调,单纯的get*,很多都是业务性质的函数,比如查询方法。^_^
4 楼
javatar
2007-11-23
leadyu 写道
符合javaBean规范的function调用要支持。
...
也就说,建议,对符合javaBean规范的function调用支持,比如formBean.tag,就必须有getTag,和setTag才允许调用
这个肯定是支持的,bean.getProperty()和bean.isProperty()都可以用bean.property调用,
非符合Bean规范的部分也支持(因为JDK中不是所有取值函都支持Bean规范),如:String.trim,List.size等
jindw 写道
我感觉只要有个方法调用的许可策略就可以了
这个想法不错,规则可定义比较好,
如,可定义许可:
Object.get*, Object.is*, String.trim, List.Size
而像remove等禁止。
(注:List的remove方法违反契约式设计原则,它不是无副作用的函数,但却有返回值)
现在,模板引擎把bean.function(arg1, arg2)的语法解析已经实现了,
只是在配置中,加了一项:
functionAailable=false
默认禁止,如果实在需要,可自行开启。
算是中庸的解决办法。
3 楼
leadyu
2007-11-22
符合javaBean规范的function调用要支持。
比如:
$set a=BussinessService1.***()
$if{a=='1'}
...
$else
...
$end
这样写模版是evil的。这样把模型层的业务代入了视图,MVC中的M无法重用。而
$if(formBean.tag=='1')
...
$else
...
$end
这样是合理的,更优于完全屏蔽function调用
这样的控制比在模型层把tag计算出来,set到Context中更有效,更具有封装性,否则模型层的计算就成了一堆散列的参数计算,非常零乱。
也就说,建议,对符合javaBean规范的function调用支持,比如formBean.tag,就必须有getTag,和setTag才允许调用。
比如:
$set a=BussinessService1.***()
$if{a=='1'}
...
$else
...
$end
这样写模版是evil的。这样把模型层的业务代入了视图,MVC中的M无法重用。而
$if(formBean.tag=='1')
...
$else
...
$end
这样是合理的,更优于完全屏蔽function调用
这样的控制比在模型层把tag计算出来,set到Context中更有效,更具有封装性,否则模型层的计算就成了一堆散列的参数计算,非常零乱。
也就说,建议,对符合javaBean规范的function调用支持,比如formBean.tag,就必须有getTag,和setTag才允许调用。
2 楼
wl95421
2007-11-22
不应该
各有各的职责
职责明确,单一才是最重要的
各有各的职责
职责明确,单一才是最重要的
1 楼
jindw
2007-11-21
我感觉只要有个方法调用的许可策略就可以了。
调用方法前,现判断一下,这个方法能不能允许调用,比如,集合类的只读方法,允许访问。
一些静态的工具方法,如字符处理,允许访问。
直接调用方法,模板语法更加简单。当能,map.key这类大家已经普片接受的规则除外。
调用方法前,现判断一下,这个方法能不能允许调用,比如,集合类的只读方法,允许访问。
一些静态的工具方法,如字符处理,允许访问。
直接调用方法,模板语法更加简单。当能,map.key这类大家已经普片接受的规则除外。
发表评论
-
以HTTL为例讲讲模块分包&领域模型&扩展框架
2011-10-09 20:08 16755注:该博客内容已加入 ... -
CommonTemplate增加HTML标签版语法外套
2008-09-09 10:33 2974CommonTemplate(http://www.commo ... -
CommonTemplate访问者设计思考
2008-09-03 10:45 1782经过多个版本的调整, CommonTemplate(http: ... -
CommonTemplate发布0.8.6版本
2008-08-26 20:49 1803CommonTemplate发布0.8.6版本 ... -
CommonTemplate发布0.8.5版本
2008-08-04 13:23 1897CommonTemplate发布0.8.5版本(2008-08 ... -
CommonTemplate加入代码生成器
2008-07-21 13:15 2246模板引擎经常被用于做代码生成, 为此, CommonTempl ... -
加入对YAML数据格式的支持
2008-07-01 12:41 4005CommonTemplate(http://www.commo ... -
嵌套注释语法思考
2008-06-29 14:40 4022主流的C/C++/Java/C#等语言,都将注释语法设计成不可 ... -
转:开源协议
2008-06-10 17:23 2232来源:网络 (1)Contrib ... -
CommonTemplate完成查看器Viewer.exe(及安装程序)
2008-06-04 15:12 1875完成查看器初始版本. 实现功能: 双击*.ctl文件, 自动读 ... -
CommonTemplate完成外部构建树或表达式接口
2008-05-31 11:01 1951CommonTemplate: http://www.comm ... -
CommonTemplate异常国际化完成
2008-05-26 11:48 1929周未把一个累活给干了, 就是异常信息的国际化. 总共有220多 ... -
CommonTemplate加入对无穷数的支持.
2008-05-23 11:07 2742用"*"号表示无穷数, 常在下标号中使用, ... -
CommonTemplate导出模板所需变量结构
2008-05-12 18:28 2260在velocity的邮件列表中收到下面的邮件: Simon G ... -
CommonTemplate完成$snatch指令
2008-05-06 09:20 1905CommonTemplate(http://www.commo ... -
关于CTE当前API无法支持从非引擎方式构建模板树
2008-04-28 17:20 1797因隐藏了模板树的实现, 现在CommonTemplate(ht ... -
CommonTemplate完成DEBUG单步调试
2008-04-21 09:56 2534CommonTemplate(http://www.commo ... -
CommonTemplate准备加入$breakpoint指令
2008-04-19 10:30 2211准备在CommonTemplate( http://www.c ... -
很高兴桂林兄加入CommonTemplate的开发
2008-04-05 20:49 2934桂林的blog: http://jasongreen.itey ... -
展开式序列实现
2008-03-31 22:47 2102现在CommonTemplate(http://www.com ...
相关推荐
5. 报告模板:库可能自动生成函数调用图或日志,显示函数调用的顺序和耗时,方便开发者分析。 使用这样的库,开发者可以在不修改应用程序核心代码的情况下,轻松获取关于函数调用和性能的数据。这对于大型项目或者...
"NC按钮调用模板"则表明这个模板是针对按钮操作的,很可能涉及按钮触发的函数调用或者事件响应。这可能意味着模板包含了对不同事件(如点击、悬停、长按等)的预定义处理,使得开发者可以方便地根据需要进行绑定。 ...
在微信小程序的开发过程中,Page()函数起到了注册页面的作用,它接受一个对象作为参数,用于指定页面的初始数据、生命周期函数、事件处理函数等,而页面的数据操作和函数调用是小程序开发中非常重要的部分。...
在本文中,我们将深入探讨JTBC函数调用的一些核心概念,特别是与首页模板和栏目列表模板相关的调用代码。 首先,我们来看首页模板调用代码。`{$=itransfer('top', '1', 'topx=10;tnum=30;genre=article;class=1')}`...
值得注意的是,尽管这个函数没有使用模板关键字`template`,但它仍然可以与模板函数一起工作,并且在调用时根据参数类型自动选择最合适的版本。 #### 主函数调用分析 在`main`函数中,通过几个具体的调用来演示...
`Z_SDN_PATTERN_FUNC_START`可能是另一个与自动填充模式相关的代码片段或示例,可能是用来启动函数调用的模板或模式。这种模式可能包含了一些预定义的结构,使得开发人员能够快速地开始函数调用,而无需从头开始编写...
函数模板是C++中的一个强大特性,它可以用来创建一个通用功能的函数,以支持多种不同形参。函数模板的声明方法是: template标识符> 函数声明 例如: template T abs(T x) { return x < 0 ? -x : x; } 在上面的...
- 调用函数模板时,编译器会根据传入的实际参数类型推断出模板参数的类型,然后生成对应的实例化函数。 2. **类模板**: - 类模板类似于函数模板,但应用于类。它允许用户声明一个类的模板,其中某些数据成员、...
在主函数`main`中,我们分别对整型和双精度浮点型数组调用了`sort`函数,展示了函数模板的实例化过程,即编译器根据实际参数类型自动生成相应的函数版本。 第三部分涉及了函数模板的显式实例化和隐式实例化。在示例...
由于C++支持名称空间和类,而C语言没有这些概念,因此直接在C代码中调用C++函数会遇到兼容性问题。 为了使C代码能够调用C++函数,我们需要遵循以下步骤: 1. **extern "C" 声明**:C++允许使用`extern "C"`来告诉...
接下来,我们讨论**函数调用**。在程序的其他地方,你可以通过函数名和传递实际参数来调用已定义的函数。调用格式如下: ```cpp 返回值 变量名 = 函数名(实际参数, 实际参数, ...); ``` 实际参数的值会赋给形参,...
例如,在下面的代码中,如果我们使用自动类型推导来调用函数模板mySwap,但是参数类型不同,编译器将报错: ```cpp void test01() { int a = 10; int b = 20; char c = 'c'; mySwap(a, b); // 正确 mySwap(a, ...
要将字符串转换为函数调用,你需要先创建一个函数指针类型的映射表,然后将函数名作为键,对应的函数指针作为值。这样,你可以通过查找字符串来获取对应的函数指针并执行它。 ```cpp #include #include #include ...
如果这个函数调用方法支持MFC,那么它可以在MFC环境下无缝集成,方便开发基于Windows的应用程序。 至于"grandmotherxmb",由于没有更多的上下文,我们只能推测它可能是代码示例的作者或者某个特定功能的标识符。...
然而,由于C++函数可能会涉及对象、模板和命名空间,因此直接使用`ctypes`并不总是可行的。在这种情况下,我们可以采用以下几种方法: 1. **Cython**: Cython是一种Python的超集,它能够编译成C扩展模块,从而可以...
用函数模板方式设计一个函数模板sort,采用直接插入排序方式对数据进行 排序,并对整数序列和字符序列进行排序
在编程领域,函数是执行特定任务的代码块,而函数调用是程序中执行这些任务的方式。本篇文章将深入探讨几种函数调用扩展方法,包括使用函数入口地址、函数对象(functor)以及虚函数,以实现更灵活的代码设计。 ...
在本文中,我们将对 WordPress 中的一些常用的函数调用方法进行汇总,旨在帮助大家更好地掌握 WordPress 函数调用知识。 WordPress 模板基本文件 在 WordPress 中,模板基本文件是非常重要的,它们决定了 ...