|  | 重构和嵌套函数
解决问题的办法往往不止一个。要记住,使用 XQuery 函数的优点之一便是它的可重用性。另一个优点便是关注点分离。以此为依据,看看您创建的新函数,如 清单 13 所示。
清单 13. 新函数:尚有改善的余地?
declare function local:getPrice($minnowElement as element(minnow)) as xs:string
{
if ($country = 'Mexico') then
(concat((data($minnowElement/international-prices/price[@denomination="peso"]))
," Pesos"))
else if ($country = 'Canada') then
(concat(
(data($minnowElement/international-prices/price[@denomination="canadian-dollar"]))
," Canadian Dollars"))
else if ($country = 'United States') then
(concat((data($minnowElement/international-prices/price[@denomination="dollar"]))
," Dollars"))
else
(concat((data($minnowElement/international-prices/price[@denomination="euro"]))
," Euros"))};
|
该函数的大部分内容都是不断重复的表达式。它在搜索方面惟一更改的地方是 denomination 属性值。这种情况为重构提供了好机会。如何对此进行重构呢?您可以已经猜到,使用另一个函数!是一个嵌套函数吗?对,没错!
有另一个函数处理搜索匹配价格的逻辑之后,如果该逻辑发生改变,您就不需要在同一个函数中对它进行 4 次更改(像 清单 13 中的函数那样)。另外,如果因扩展业务需要添加一个使用另一种货币的国家(比如印度或中国),按照原先的方法问题就更加复杂了,因为又有另一个 地方需要更改逻辑。
通过使用另一个函数,您将获得重用代码带来的两个好处,并且可以使用封装。新的函数处理从 XML 文档体获取实际价格的必要业务逻辑。
因此,创建一个称为 getCountrySpecificPrice 的新函数。这个函数接受两个参数:上述的 <minnow> 元素和表示货币面值名称的属性的实际名称。然后,函数将从该元素获取值作为一个 denomination 属性值。这个属性值与作为参数传递给该函数的名称相匹配。
清单 14 不仅展示了新函数,还演示了如何重写 getPrice 函数,使其包含新的函数。
清单 14. 改进后的新函数
declare function local:getCountrySpecificPrice($minnowElement as element(minnow),
$denomination as xs:string) {
let $price :=
(data($minnowElement/international-prices/price[@denomination=$denomination]))
return ($price)
};
declare function local:getPrice($minnowElement as element(minnow)) as xs:string
{
if ($country = 'Mexico') then
(concat(local:getCountrySpecificPrice($minnowElement,"peso")," Pesos"))
else if ($country = 'Canada') then
(concat(local:getCountrySpecificPrice($minnowElement,"canadian-dollar")
," Canadian Dollars"))
else if ($country = 'United States') then
(concat(local:getCountrySpecificPrice($minnowElement,"dollar")," Dollars"))
else (concat(local:getCountrySpecificPrice($minnowElement,"euro")," Euros"))};
|
如您所见,最后修改的代码更加干净了。这也很重要,因为它演示了如何在函数中嵌套函数。
本教程的用例以此结束。不过,使用 XQuery 函数可以对本教程给出的 XML 文档和 XQ 文件进行其他实践。您可以开始探索自己喜欢的事情。使用这些源文件实现自己的用例和相应的测试,并且要经常进行备份。
|  |
|