SAP Fiori Elements 应用里的 visitor 访问者设计模式

简介: SAP Fiori Elements 应用里的 visitor 访问者设计模式

SAP Fiori Elements 应用 SmartTable title 控件的 text 属性,在运行时如何生成的?

在 TitleRenderer.js 里设置断点



调用 getText 拿到 text property 值:

问题是这个 Text 属性是从哪里来的?

SmartTable.js 内部能够观察到这个 Products 字符串:

最终的入口还是 XMLTemplateProcessor.js:


应该是这些 XML fragment 加载触发的:


把 smarttable.fragment.xml 下载到本地打开,观察其 header 绑定信息:


{= !${parameter>/settings/quickVariantSelection/showCounts} ? ${path:'header>TypeNamePlural', formatter: 'sap.ui.model.odata.AnnotationHelper.format'} : '' }


根据关键字 TypeNamePlural 进行搜索:

设置了断点,一个也没有触发。

PropertyBinding:

一个 visitor 模式:


源代码:

/**
       * Visits the given attribute of the given element. If the attribute value represents a
       * binding expression that can be resolved, it is replaced with the resulting value.
       *
       * @param {Element} oElement the XML DOM element
       * @param {Attr} oAttribute one of the element's attribute nodes
       * @param {sap.ui.core.template._with} oWithControl the "with" control
       * @returns {sap.ui.base.SyncPromise}
       *   A sync promise which resolves with <code>undefined</code> as soon as the
       *   attribute's value has been replaced, or is rejected with a corresponding error if
       *   getting the binding's value fails.
       */
      function visitAttribute(oElement, oAttribute, oWithControl) {
        if (fnSupportInfo) {
          fnSupportInfo({context:undefined /*context from node clone*/, env:{caller:"visitAttribute", before: {name: oAttribute.name, value: oAttribute.value}}});
        }
        return resolveAttributeBinding(oElement, oAttribute, oWithControl)
          .then(function () {
            if (fnSupportInfo) {
              fnSupportInfo({context:undefined /*context from node clone*/, env:{caller:"visitAttribute", after: {name: oAttribute.name, value: oAttribute.value}}});
            }
          });
      }
      /**
       * Visits all attributes of the given element. If an attribute value represents a
       * binding expression that can be resolved, it is replaced with the resulting value.
       *
       * @param {Element} oElement the XML DOM element
       * @param {sap.ui.core.template._with} oWithControl the "with" control
       * @returns {sap.ui.base.SyncPromise}
       *   A sync promise which resolves with <code>undefined</code> as soon as all
       *   attributes' values have been replaced, or is rejected with a corresponding error if
       *   getting some binding's value fails.
       */
      function visitAttributes(oElement, oWithControl) {
        /*
         * Comparator for DOM attributes by name.
         *
         * @param {Attr} oAttributeA
         * @param {Attr} oAttributeB
         * @returns {number} <0, 0, >0
         */
        function comparator(oAttributeA, oAttributeB) {
          return oAttributeA.name.localeCompare(oAttributeB.name);
        }
        return stopAndGo(
          // Note: iterate over a shallow copy to account for removal of attributes!
          // Note: sort attributes by name to achieve a stable log order across browsers
          Array.prototype.slice.apply(oElement.attributes).sort(comparator),
          function (oAttribute) {
            return visitAttribute(oElement, oAttribute, oWithControl);
          });
      }


这段代码中所使用的设计模式为访问者模式(Visitor pattern)。

访问者模式是一种将算法与对象结构分离的设计模式。这种模式在对象结构中的元素上定义一个访问操作,该操作以一个访问者作为参数,访问者在该操作中实现了一个针对该元素的操作。


在这段代码中,visitAttributevisitAttributes 函数就充当了访问者的角色。它们对 XML DOM 元素及其属性进行访问,解析属性中可能存在的绑定表达式,并将解析后的结果替换原始属性值。


例如,visitAttribute 函数访问单个属性,通过 resolveAttributeBinding 解析可能的绑定表达式,并通过 Promise 结构异步替换属性值。visitAttributes 函数则访问元素的所有属性,通过调用 visitAttribute 对每个属性进行处理。


这种通过访问者访问和处理元素的方式,将元素与处理逻辑分离,增加了代码的可扩展性和复用性。当需要对元素进行新的操作时,只需要定义新的访问者,而无需修改元素类。同时,访问者模式也使得添加新的操作变得更简单,只需添加一个新的访问者即可。


这段代码还体现了访问者模式的另一特性,即访问者可以累积状态。在这段代码中,访问者通过 Promise 结构返回处理结果,这可以看作是访问者在访问过程中累积的状态。通过 Promise 结构,可以方便地处理异步操作和错误,这也是访问者模式的一种常见应用。


相关文章
|
11天前
|
设计模式 Java 数据库连接
Java中的设计模式在实际项目中的应用
Java中的设计模式在实际项目中的应用
|
19天前
|
设计模式 Java
设计模式在Java项目中的实际应用
设计模式在Java项目中的实际应用
|
24天前
|
设计模式 数据库连接 PHP
PHP中的面向对象编程与设计模式应用
传统的PHP编程模式在面向对象的趋势下逐渐演进,本文探讨了面向对象编程在PHP中的应用,并深入分析了常用的设计模式如何优化代码结构和可维护性。
|
9天前
|
设计模式 存储 缓存
Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
15 0
|
9天前
|
设计模式 缓存 安全
Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
8 0
|
17天前
|
设计模式 Java 开发者
Java中设计模式的应用与实现详解
Java中设计模式的应用与实现详解
|
18天前
|
设计模式 Java
设计模式在Java项目中的实际应用
设计模式在Java项目中的实际应用
|
20天前
|
设计模式 缓存 前端开发
现代PHP开发中的设计模式应用与性能优化
本篇文章深入探讨了PHP开发中设计模式的实际应用及其对性能的影响。通过分析具体案例和最新研究成果,文章揭示了合理运用设计模式不仅可以提升代码的可维护性和扩展性,还能在特定场景下优化性能。我们将一起探索如何通过科学方法将设计模式融入日常开发实践,同时保持代码的高效执行。
|
1月前
|
设计模式 人工智能 自然语言处理
【设计模式】MVVM模式在AI大模型领域的创新应用
【设计模式】MVVM模式在AI大模型领域的创新应用
28 0
|
1月前
|
设计模式 PHP 开发者
PHP中的设计模式及其应用
在现代软件开发中,设计模式是一种被广泛采纳的方法论,能够帮助开发者解决常见的设计问题并提高代码的灵活性和可维护性。本文将深入探讨PHP中几种常用的设计模式,包括工厂模式、单例模式和观察者模式,分析它们的实现方式以及在实际项目中的应用场景,帮助读者理解和运用这些模式来优化自己的PHP代码设计。