Gallery: 嵌入:基于事件的松耦合整合:修订间差异

来自站长百科
跳转至: 导航、​ 搜索
无编辑摘要
无编辑摘要
第58行: 第58行:


== 为何要松耦合? ==
== 为何要松耦合? ==
The alternative to a loose-coupled system is a '''tight integration''' where data structures (database tables, ...) and / or function calls of the two applications are interweaved to a point where it becomes unmaintainable, there are more and more cross-dependencies all over and the resulting system is (almost) a fork of the two other applications.
某个松耦合系统的另一选择就是'''紧致整合(tight integration)''',这里数据结构(数据库表格)和/或两应用程序的函数呼叫被交织为一点,这使得其无法维护。跨越式依赖性越来越普遍,而结果系统(几乎)成了两个应用程序的分支了。


What happens if one of the applications has a new release? The authors of the integration would then have to backport all the changes to their forked integration system. Or apply all the hacks to the new release.
如果其中某个应用程序有新版本时会怎样?该整合的编写者会在(旧的)分支整合系统中添加新的修改。或将所有内容应用于新版本。


This is not a fictional scenario, there are plenty of examples of such integrations, e.g. [http://www.pnphpbb.com/ PNphpBB] (PostNuke fork of phpBB).
这不是纸上谈兵,关于这样的整合有很多例子可以佐证,如[http://www.pnphpbb.com/ PNphpBB] (phpBB的PostNuke分支)。


Such tight integrations are not easy to maintain and require a dedicated team to keep it up to date and to port security patches and fixes from the original applications to the fork / hacked integration. Depending on a third, often very small and not well-organized team of developers for a production-level application is sure not preferable. Developers lose their interest and it's important to have applications backed by large development teams guaranteeing continued support and development. Also, being able to quickly apply critical security patches is also of great importance.
这种紧致整合维护起来可不容易,且还需要配备专门的小组来保证其更新读,并从原版应用程序向分支整合不断导入安全性补丁和修正。因此将此产品级别的应用程序托付给某个第三方开发小组可不是好主意。开发者也会失去兴趣,因此将其托付给较大规模的能保证不间断支持和开发的开发团队是至关重要的举措。还有,及时快速的安全性补丁应用也是很关键的。


The main goal of '''loose-coupled''' integration is to provide a very well integrated experience for the end-user while keeping the involved applications as separate as possible in the back-end. Well defined interfaces and a good design guarantee that there are no drawbacks for the end-user compared to tight integrations.
'''松耦合'''整合的主要目的就是让最终用户体验良好的整合性,并保持相关的应用程序在后端中尽量独立。较佳定义的接口和良好的设计将保证最终用户体验最佳的特点,相比紧致整合不会出现不足之处。


== 为何要基于事件? ==
== 为何要基于事件? ==
The alternative to event-based notifications of changes is '''on-the-fly notifications''' that is, instead of notifying the other applications exactly when the event happens, the other application is notified on-the-fly when a user requests the next embedded page.
基于事件的变更通知还有另一选择,就是'''即时通知'''。即,取代事件发生时立刻通知另一应用程序,另一程序则是当某用户请求下一个嵌入页面时被通知。
'''注:'''此处的即时指的是当有需要时才执行某操作,而非立刻的意思。


Example:
举例:
# A new user is created in application B (e.g. a CMS)
# 应用程序B中某新用户被创建(如一个CMS)
# The same user visits an embedded page of A in B
# 相同的用户访问B中A的某个嵌入页面
# When A is called by B, '''A checks whether the user already exists in A, if not, the user is created'''.
# 当A被B呼叫时, '''会检查该用户是否已存在于A中,如为否定,则用户被创建'''
# A handles the request in any case and returns the data as usual
# A处理任何情况下的请求并按通常方式返回数据


In this case we talk of '''on-the-fly user creation'''.
在此例中,我们谈到了'''即时的用户创建'''


The problems of on-the-fly user creation are obvious:
即使用户创建的问题和明显:
* As long as a user doesn't visit an embedded page of A in B, the changes are not synchronized. If A has features like mass-emails to all registered users, it won't send emails to all registered users since only a subset already have an account in A
* 只要某个用户不访问B中A的某个嵌入页面,变更就不会被同步。比如,如果A具有向所有注册用户群发电邮的特点的话,在这种情况下,它就不会向所有注册用户群发邮件,因此仅有一个子集具有A中的某个帐户。
* Only a small subclass of changes can be synchronized on-the-fly. User deletion, user data changes (e.g. email address), logout, configuration changes, ... cannot be synchronized without a performance penalty using a workaround like checking for a list of queued changes on each embedded request or trade-off solutions like running a synchronization task periodically
* 仅有很小一子类的变更能被即时同步。用户的删除,用户数据的变更(如,电子邮件的地址),登出,配置的变更就无法被同步—如果不采用各嵌入请求队列列表检查或定期进行同步的措施的话,这就无法达成。


Therefore we classify on-the-fly synchronization as a '''low-tech fallback solution''' for applications that are not ready to provide events / hooks such that plugins or other applications can hook into core functionality like the user creation.
所以,我们将即时同步归为针对无法充分提供事件/挂钩(hook)的应用程序的'''低端倒退式的解决方案'''


== 实现 ==
== 实现 ==
In this example we use the same pattern of a master-slave relationship as the one used before.
在此例中,我们使用前面用过的主仆关系。


=== 主应用程序 ===
=== 主应用程序 ===
The master application is the principle application receiving and handling requests by users and serving the resulting pages. A typical example is a content management system.
主应用程序是接受并处理用户请求并服务于结果页面的主要应用程序。典型的例子就是内容管理系统CMS。


Let's further assume the master application is modular and developers can extend its functionality with plugins (or modules, extensions, componennts, ...). To embed a slave application, e.g. a forum or a photo management system, in the master application, you would then write a new plugin for the master. The plugin consists of a small wrapper scripts which communicates with the slave.
接着让我们假设主应用程序是模块化的,开发者可以使用插件(或模块,扩展及组件等)进行功能上的扩充。要在主应用程序中嵌入一个仆应用程序,如一个论坛或相片管理系统,你就要为主应用程序编写一个新插件。该插件包括一个小的封包脚本用于与仆应用程序进行交流。


==== 封包脚本 ====
==== 封包脚本 ====
Sample for the wrapper script:
封包脚本(wrapper script)样例:
   $userId = getUserId(); // get the userId of the current active user in the master application
   $userId = getUserId(); // 获取主应用程序中当前活动用户的userId
   $baseUrl = getBaseUrl(); // get the base URL of all URLs that point to the master application
   $baseUrl = getBaseUrl(); // 获取所有指向主应用程序URL的base URL
   include('some/path/to/slaveApplication/embed.php'); // include the interface exposed by the slave application
   include('some/path/to/slaveApplication/embed.php'); // 包括仆应用程序所暴露的接口
   embed_init($userId, $baseUrl); // initialize the slave application with the authenticated user and the base URL
   embed_init($userId, $baseUrl); // 使用经验证的用户和base URL初始化仆应用程序
   $html = embed_run(); // let the slave application handle the current request and return the resulting HTML
   $html = embed_run(); // 使仆应用程序处理当前请求并返回结果HTML


Then the master would embed the generated $html in one of its own templates and return the complete rendered page to the user.
接着主应用程序就会将生成的$html接入其某个模板中并返回给用户完全渲染过的页面。


==== 事件同步 ====
==== 事件同步 ====
We also assume the master application has a built-in event or hook system that enables its plugins to execute their own code on events such as user creation, login or configuration changes. An illutrative implementation of an event system could look like this (we don't encourage the use of globals, but they are illustrative):
我们还假设主应用程序具有一个内置事件或hook系统,能够允许其插件在事件发生时执行自己的代码,这些事件包括用户的创建,登入或配置的变更。某颇具说明性事件系统的实现就像这样:(我们不提倡使用global,但它们的代表性很强)
   function create_user($username, $password) {
   function create_user($username, $password) {
       ... // create the user as usual
       ... // create the user as usual


       global $hooks;
       global $hooks;
       if (!empty($hooks[CREATE_USER])) { // check if there are any registered event listeners / hooks
       if (!empty($hooks[CREATE_USER])) { // 检查是否存在任何已注册的事件侦听器或挂钩
           foreach ($hooks[CREATE_USER] as $event_handler) {
           foreach ($hooks[CREATE_USER] as $event_handler) {
               $event_handler->handle_event($username, $password);
               $event_handler->handle_event($username, $password);
第115行: 第116行:
       }
       }
   }
   }
A plugin of the master application could register an event handler like this:
主应用程序某插件可按如下方式注册一个事件处理器:
   $GLOBALS['hooks'][CREATE_USER][] = new my_create_user_handler();
   $GLOBALS['hooks'][CREATE_USER][] = new my_create_user_handler();
And the handler itself would look like this:
而处理器本身就如:
   class my_create_user_handler {
   class my_create_user_handler {
       function handle_event($username, $password) {
       function handle_event($username, $password) {
           // synchronize user creation to our embedded application
           // 将用户创建与我们嵌入的应用程序同步
           include('path/to/slaveApplication/embed.php'); // include the interface to the slave application
           include('path/to/slaveApplication/embed.php'); // 包括仆应用程序的接口
           embed_init(); // initialize the slave application
           embed_init(); // 初始化仆应用程序
           embed_create_user($username, $password); // create the user in the embedded application
           embed_create_user($username, $password); // 在嵌入的应用程序中创建用户
       }
       }
   }
   }


Of course you wouldn't implement an event / hooking system that way, but the important part is that there is an event when a user is created in the master application and that plugins of the master application can register themselves as an event listener or hook somehow into core functionality such that they can execute their embed_create_user() function when a user is created.
当然你不能以这种方式实现一个事件/挂钩系统。但重要的是,主应用程序中某用户被创建的事件以及主应用程序的插件可以将自己注册为事件侦听器或挂入核心功能,这样它们就能够在某用户被创建时执行embed_create_user()函数了。


=== 仆应用程序 ===
=== 仆应用程序 ===
The primary task of the slave application is to offer an interface or a protocol of integration related methods. This interface must offer methods to:
仆应用程序的主要任务就是提供整合相关方法的接口或协议。该接口所提供的方法必须能够:
* Initialize the application (as an alternative to the normal index.php entry point)
* 初始化该应用程序(作为一般index.php入口点的备用方法)
* Create / update / delete users
* 创建/更新/删除用户
* login / logout users
* 登入/登出用户
* ...
* ...
A sample interface could look like this (the embed.php file referenced above):
接口的样例如下:
   function embed_init($userId=null, $baseUrl=null) {
   function embed_init($userId=null, $baseUrl=null) {
       include(..); // include some files, intitialize the application
       include(..); // 包括某些文件,初始化应用程序
       $user = get_user_by_mapped_external_userid($userId);
       $user = get_user_by_mapped_external_userid($userId);
       set_active_user($user);
       set_active_user($user);
第143行: 第144行:
   function embed_run() {
   function embed_run() {
       $mode = 'embedded';
       $mode = 'embedded';
       $html = main($mode); // call the application in embedded mode (return html instead of printing to browser, ...)
       $html = main($mode); // 在嵌入模式中呼叫应用程序(返回html,而不是打印至浏览器)
       return $html;
       return $html;
   }
   }
第150行: 第151行:
   }
   }


The slave application must of course meet a lot of requirements that allow it to run in embedded mode. But the important bit here is that the inner architecture of the application is hidden and only a stable, simple interface is exposed to the master application.
仆应用程序当然需要达到很多要求才能在嵌入模式中运行。但在此重要的一点就是,应用程序的内部构造是隐藏的,而仅稳定且简单的接口才会暴露给主应用程序。




== 标准化 ==
== 标准化 ==
Integrating a web application into another can be quite complicating since only a small percentage is designed to also work when embedded and only a few frameworks / applications are designed to offer the means to embed other applications into them.
将某web应用程序正如另一应用程序会十分复杂,因为仅有很低比例的应用程序被设计为在被嵌入时仍能运作,而仅有很少一些框架/应用程序提供了可嵌入其他应用程序于其中的手段。


If there was a standardized way of integrating applications with specifications that must be met by the master and by the slave applications, writing an integration could be faciliated a lot. Everyone would profit:
如果应用程序的嵌入有标准化的方式的话,那么主仆应用程序都应符合要求。整合的编写会得到很大促进,每个人都能获益:
* There would be clear, standardized patterns and specifications to follow when designing an application for integration
* 在为整合设计应用程序时,应有清晰的,标准化的方案及规则来遵循
* Interoperability of a large range of applications would be guaranteed
* 应用程序大范围的互通性将得到保障
* Frameworks / CMS would profit from seamlessly integrating best-of-breed applications in their overall solution
* 框架/CMS会因应用程序的完美整合获益
* Dedicated applications (forums, commerce, photo album, ...) would find their way into more CMS'
* 专门的应用程序(forums,commerce,photo album等)会找到更多嵌入CMS的方法
* The end-user profits from better overall solutions
* 最终用户会因更好的总体解决方案而获益
* Tools common to all integrations could be developed
* 对所有整合通用的工具将会被开发出来


They key requirements at master applications is the event or hooking system. Without, only a low-tech fallback solution like on-the-fly user creation with periodic synchronization runs is possible. How this event system is implemented, does not matter at all.
主应用程序的关键要求就是事件或挂钩系统。如何实现该事件系统则根本不重要。


The slave applications must expose a well-defined interface or protocol. The details of such an interface are not that important (for now, we can always improve the standardization at a later point), as long as the interface follows the same basic principles to offer functions to initialize, handle the request, create a user, etc.
The slave applications must expose a well-defined interface or protocol. The details of such an interface are not that important (for now, we can always improve the standardization at a later point), as long as the interface follows the same basic principles to offer functions to initialize, handle the request, create a user, etc.
第175行: 第176行:


== 支持基于事件整合的应用程序 ==  
== 支持基于事件整合的应用程序 ==  
As a master application:
主应用程序:
* Gallery2 (90% events / hooks for user / group create / update / delete, logout, login, ..missing: configuration changes)
* Gallery2 (90% events / hooks for user / group create / update / delete, logout, login, ..missing: configuration changes)
* Xaraya (100% events / hooks for user / group create / update / delete, configuration changes, logout, login, ..)
* Xaraya (100% events / hooks for user / group create / update / delete, configuration changes, logout, login, ..)
第185行: 第186行:
* ...
* ...


As a slave application:
仆应用程序:
* Gallery 2
* Gallery 2
* Phorum.org
* Phorum.org
第191行: 第192行:


== 参考 ==  
== 参考 ==  
Event-based loose integration is an obvious and the most prominent approach to software integration for a long time now. These are a few papers and references on the topic:
基于事件的松散整合是目前软件整合的最突出的手段了。下面则是有关该话题参考及论述:
* Daniel J. Barrett, Lori A. Clarke, Peri L. Tarr, Alexander E. Wise, [ftp://ftp.cs.umass.edu/pub/techrept/techreport/1996/UM-CS-1996-068.ps "A Framework for Event-Based Software Integration"] (Postscript, 461K). ACM Transactions on Software Engineering and Methodology (TOSEM), Volume 5 Number 4, October 1996. Also see: http://www.blazemonger.com/publications.html#ACADEMIC
* Daniel J. Barrett, Lori A. Clarke, Peri L. Tarr, Alexander E. Wise, [ftp://ftp.cs.umass.edu/pub/techrept/techreport/1996/UM-CS-1996-068.ps "A Framework for Event-Based Software Integration"] (Postscript, 461K). ACM Transactions on Software Engineering and Methodology (TOSEM), Volume 5 Number 4, October 1996. 另见:http://www.blazemonger.com/publications.html#ACADEMIC


More links specific to web / PHP interoperability:
更多专门涉及web/PHP互通性的链接:
* http://www.geeklog.net/article.php/2002111817094613 (from early 2002)
* http://www.geeklog.net/article.php/2002111817094613(自2002年初)
* http://www.google.com/search?hl=en&q=cms+bridge
* http://www.google.com/search?hl=en&q=cms+bridge
* http://www.phorum.org/phorum5/read.php?28,53902,page=1 (2006)
* http://www.phorum.org/phorum5/read.php?28,53902,page=1 (2006)

2008年10月20日 (一) 15:34的版本

基于事件的松耦合整合

该文档描述说明基于事件驱动同步的松耦合整合,其实现和备选方法,以及这些标准如何能够提高整个web应用程序群中应用程序的互通性的。

请参阅有关Gallery2嵌入的综述。

什么是基于事件的松耦合整合

基于事件的松耦合整合是将某个web应用程序整合或嵌入另一应用程序中的方法,如,将某个相片相册程序整合到某个内容管理系统中,或将某个blog与某个论坛进行合并。

其中的两个术语松耦合(loose-coupled)基于事件(event-based)可以分开解释;但只有将两者结合起来才能够理解应用程序整合/合并的完整方法。

松耦合整合

松耦合的意思就是两个应用程序不被改变,而各应用程序都暴露一个接口,而两应用程序间能通过此接口互访。。两个应用程序不依赖对方,但它们通过这些接口进行交流以承担相互间登入/验证的职责。

整合应用程序A至B中,通过顶部的一些胶水代码(glue code)/作为B的插件,呼叫A获取生成的输出(HTML),接着B将这些生成的输出置入自己的输出并将整个输出返回给用户。

 用户 – 请求--> 应用程序B(如一个CMS)
                        |____ B初始化。
                        |____ B认证 
                        |     活动用户
                        |____ 如请求针对  -- B呼叫--> 应用程序A(如一个论坛)
                        |     B中某A的                   |____ A 处理该请求 
                        |     整合页面                                     并返回输出
                        |                            <- A 返回 -
                        |     
                        |____ B组合整个 
                        |     页面输出并将
                        |     A的输出嵌入其中
                        |____ B向用户返回 
                        |     被请求的页面
 用户 <-- 输出---   |

应用程序A依靠应用程序B在其对A的呼叫中提供足够的信息。最重要的是有关经认证用户的信息。对于web应用程序来说,B告知A 所生成URL的表现方式也同样重要。

还有就是注意A和B通过各自经清晰定义的接口或协议互访,而他们不会直接对各自的数据结构或函数进行访问。

备忘:请介绍些有关: 接口,API,协议及主仆关系的信息。

基于事件的同步

由于应用程序是松耦合并且不共享数据的,它们就需要告知彼此相关的变更或足以影响彼此的事件。这些事件包括:

  • 新用户的创建
  • 某些用户数据的更新,如电子邮件地址
  • 某个用户的删除
  • 登入,登出
  • 应用程序设定
  • ...

因此每当新用户在某个应用程序中被创建时,它都会通过该事件经定义的接口告知另一个应用程序相关的用户名,用户数据等。接着后者就会做出适当的反应,在此例中就是创建一个对应的用户并按用户名或id编号使两者进行映射。

备忘:请介绍些有关: hook和事件的信息。

摘要

松耦合整合加上基于事件的通告将保证两应用程序:

  • 可独立开发而无需forked / hacked
  • 永不会失去同步
  • 易于整合

通常整合都是单方的,正如例子中所见,A被嵌入到B中。B是主,A就是仆。此主仆关系中的交流/通知仅为simplex的。B通知A有关的变更,向A请求数据,并且这种方式永远不会倒过来。

为何要松耦合?

某个松耦合系统的另一选择就是紧致整合(tight integration),这里数据结构(数据库表格)和/或两应用程序的函数呼叫被交织为一点,这使得其无法维护。跨越式依赖性越来越普遍,而结果系统(几乎)成了两个应用程序的分支了。

如果其中某个应用程序有新版本时会怎样?该整合的编写者会在(旧的)分支整合系统中添加新的修改。或将所有内容应用于新版本。

这不是纸上谈兵,关于这样的整合有很多例子可以佐证,如PNphpBB (phpBB的PostNuke分支)。

这种紧致整合维护起来可不容易,且还需要配备专门的小组来保证其更新读,并从原版应用程序向分支整合不断导入安全性补丁和修正。因此将此产品级别的应用程序托付给某个第三方开发小组可不是好主意。开发者也会失去兴趣,因此将其托付给较大规模的能保证不间断支持和开发的开发团队是至关重要的举措。还有,及时快速的安全性补丁应用也是很关键的。

松耦合整合的主要目的就是让最终用户体验良好的整合性,并保持相关的应用程序在后端中尽量独立。较佳定义的接口和良好的设计将保证最终用户体验最佳的特点,相比紧致整合不会出现不足之处。

为何要基于事件?

基于事件的变更通知还有另一选择,就是即时通知。即,取代事件发生时立刻通知另一应用程序,另一程序则是当某用户请求下一个嵌入页面时被通知。 注:此处的即时指的是当有需要时才执行某操作,而非立刻的意思。

举例:

  1. 应用程序B中某新用户被创建(如一个CMS)
  2. 相同的用户访问B中A的某个嵌入页面
  3. 当A被B呼叫时, 会检查该用户是否已存在于A中,如为否定,则用户被创建
  4. A处理任何情况下的请求并按通常方式返回数据

在此例中,我们谈到了即时的用户创建

即使用户创建的问题和明显:

  • 只要某个用户不访问B中A的某个嵌入页面,变更就不会被同步。比如,如果A具有向所有注册用户群发电邮的特点的话,在这种情况下,它就不会向所有注册用户群发邮件,因此仅有一个子集具有A中的某个帐户。
  • 仅有很小一子类的变更能被即时同步。用户的删除,用户数据的变更(如,电子邮件的地址),登出,配置的变更就无法被同步—如果不采用各嵌入请求队列列表检查或定期进行同步的措施的话,这就无法达成。

所以,我们将即时同步归为针对无法充分提供事件/挂钩(hook)的应用程序的低端倒退式的解决方案

实现

在此例中,我们使用前面用过的主仆关系。

主应用程序

主应用程序是接受并处理用户请求并服务于结果页面的主要应用程序。典型的例子就是内容管理系统CMS。

接着让我们假设主应用程序是模块化的,开发者可以使用插件(或模块,扩展及组件等)进行功能上的扩充。要在主应用程序中嵌入一个仆应用程序,如一个论坛或相片管理系统,你就要为主应用程序编写一个新插件。该插件包括一个小的封包脚本用于与仆应用程序进行交流。

封包脚本

封包脚本(wrapper script)样例:

 $userId = getUserId(); // 获取主应用程序中当前活动用户的userId
 $baseUrl = getBaseUrl(); // 获取所有指向主应用程序URL的base URL
 include('some/path/to/slaveApplication/embed.php'); // 包括仆应用程序所暴露的接口
 embed_init($userId, $baseUrl); // 使用经验证的用户和base URL初始化仆应用程序
 $html = embed_run(); // 使仆应用程序处理当前请求并返回结果HTML

接着主应用程序就会将生成的$html接入其某个模板中并返回给用户完全渲染过的页面。

事件同步

我们还假设主应用程序具有一个内置事件或hook系统,能够允许其插件在事件发生时执行自己的代码,这些事件包括用户的创建,登入或配置的变更。某颇具说明性事件系统的实现就像这样:(我们不提倡使用global,但它们的代表性很强)

 function create_user($username, $password) {
     ... // create the user as usual
     global $hooks;
     if (!empty($hooks[CREATE_USER])) { // 检查是否存在任何已注册的事件侦听器或挂钩
         foreach ($hooks[CREATE_USER] as $event_handler) {
             $event_handler->handle_event($username, $password);
         }
     }
 }

主应用程序某插件可按如下方式注册一个事件处理器:

 $GLOBALS['hooks'][CREATE_USER][] = new my_create_user_handler();

而处理器本身就如:

 class my_create_user_handler {
     function handle_event($username, $password) {
         // 将用户创建与我们嵌入的应用程序同步
         include('path/to/slaveApplication/embed.php'); // 包括仆应用程序的接口
         embed_init(); // 初始化仆应用程序
         embed_create_user($username, $password); // 在嵌入的应用程序中创建用户
     }
 }

当然你不能以这种方式实现一个事件/挂钩系统。但重要的是,主应用程序中某用户被创建的事件以及主应用程序的插件可以将自己注册为事件侦听器或挂入核心功能,这样它们就能够在某用户被创建时执行embed_create_user()函数了。

仆应用程序

仆应用程序的主要任务就是提供整合相关方法的接口或协议。该接口所提供的方法必须能够:

  • 初始化该应用程序(作为一般index.php入口点的备用方法)
  • 创建/更新/删除用户
  • 登入/登出用户
  • ...

接口的样例如下:

 function embed_init($userId=null, $baseUrl=null) {
     include(..); // 包括某些文件,初始化应用程序
     $user = get_user_by_mapped_external_userid($userId);
     set_active_user($user);
 }
 function embed_run() {
     $mode = 'embedded';
     $html = main($mode); // 在嵌入模式中呼叫应用程序(返回html,而不是打印至浏览器)
     return $html;
 }
 function embed_create_user($username, $password) {
     some_api_call_to_create_user($username, $password);
 }

仆应用程序当然需要达到很多要求才能在嵌入模式中运行。但在此重要的一点就是,应用程序的内部构造是隐藏的,而仅稳定且简单的接口才会暴露给主应用程序。


标准化

将某web应用程序正如另一应用程序会十分复杂,因为仅有很低比例的应用程序被设计为在被嵌入时仍能运作,而仅有很少一些框架/应用程序提供了可嵌入其他应用程序于其中的手段。

如果应用程序的嵌入有标准化的方式的话,那么主仆应用程序都应符合要求。整合的编写会得到很大促进,每个人都能获益:

  • 在为整合设计应用程序时,应有清晰的,标准化的方案及规则来遵循
  • 应用程序大范围的互通性将得到保障
  • 框架/CMS会因应用程序的完美整合获益
  • 专门的应用程序(forums,commerce,photo album等)会找到更多嵌入CMS的方法
  • 最终用户会因更好的总体解决方案而获益
  • 对所有整合通用的工具将会被开发出来

主应用程序的关键要求就是事件或挂钩系统。如何实现该事件系统则根本不重要。

The slave applications must expose a well-defined interface or protocol. The details of such an interface are not that important (for now, we can always improve the standardization at a later point), as long as the interface follows the same basic principles to offer functions to initialize, handle the request, create a user, etc.

If all interfaces were standardized one could assemble a CMS that has a feature-rich forum, gallery etc. by just writing a little glue-code. Seeing each CMS writing their own (mostly poor in features) forum solution or multimedia framework and thus wasting their own resources and making users less happy than with feature-rich solutions is reason enough for such a standard.

A standard should have different levels, meaning that not all applications can meet all goals of such a standard, but they should still work together, just on a lower level of standardization.

CMS devs usually want to develop their own solution, favor their own forum or gallery solution etc since they believe that one day, they'll have all the features needed, plus it's then an integral part of their CMS, well desgined and their code is better anyway :) Of course we have to accept and appreciate this position, but with integration/interoperability standards, applications could achieve the same, without having to develop specialized solutions like a forum system.

支持基于事件整合的应用程序

主应用程序:

  • Gallery2 (90% events / hooks for user / group create / update / delete, logout, login, ..missing: configuration changes)
  • Xaraya (100% events / hooks for user / group create / update / delete, configuration changes, logout, login, ..)
  • Wordpress (90% events / hooks for user / update / delete, rewrites, logout, login, ..)
  • Drupal (80% maybe?)
  • Joomla (100% joomla 1.5; login, logout, create, update, delete user, block, activation, system before and after start)
  • Typo3 (50% maybe?, e.g. no unified create user event / hook)
  • TikiPro (?%)
  • ...

仆应用程序:

  • Gallery 2
  • Phorum.org
  • Pretty all scripts, since you can always add a layer / interface which calls the internal functions and add output buffering around it. But they need to provide basic means to dictate the URL format etc.

参考

基于事件的松散整合是目前软件整合的最突出的手段了。下面则是有关该话题参考及论述:

更多专门涉及web/PHP互通性的链接: