Quicknavi |
|
Enhancement of existing functionalities
1. Introduction
I'm sure, every developer was once faced with the situation, that an existing library helped to solve
most of the previous tasks, but is not able to handle the current special case. Many developers then
tend to implement a completely new function to meet the current case's needs. Others try to convulsively
find another library that handles this case. All of these possibilities help you to get the goal, but
reduce the maintainability of your software and increase error rate due to a "wild" combination of
various external libraries and special functions for several special cases. Furthermore, each developer
should keep in mind, that API changes originate changes to every function that uses the libray and
is this equal to leaving the update path of the external library. Perhaps, even quick hacks won't
work in the next version of the third party library.
This tutorial wants to explain a method to enhance existing functionalities without changing the
provided library. The tutorial assumes, that the used library is third party code. Otherwise, this
method doesn't make sense.
Maybe you now think, that an API change means, that the API was not designed well. In many cases you
are right, but there are many APIs, that are not designed to meet every special case of your
application.
2. Taglib example
The following example shows you how to enhance the socialbookmark library delivered
with each release to meet your demands.
2.1. Problem description
The socialbookmark library contained in each adventure-codepack-* release are
intended to be included in the content area of your application via XML tag. For this reason, the
module includes a taglib, whose characteristics are described on the
builtin modules page. The tag
definition allows you to specify a page title within the tag definition, that is used as a title
when bookmarking the current page. This definition is statically, because it is specified on tag
definition time and not on execution time. This is problematically with CMS webpages, because there,
titles must be dynamic!
2.2. Analysis of the existing API
To analyze the existing API you must ask yourself the question: "What is already possible and
what is really missing?". In case of the socialbookmark module, the answer is quite obvious:
static titles are possible, dynamic titles not!
2.3. API extension by wrapping
A very common way of extending a API is to wrap it. Wrapping means, that you build
a layer around the existing library - in this case a taglib - to enhance the functionality without
changing the library itself.
Let's at first have a look at the existing library. The taglib implements the coreObject's
transform() method. Within this function the class passes the necessary attributes
to the socialbookmarkManager and asks him to give back the bookmark elements. The
source code of the taglib (please refer to the /apps/modules/socialbookmark/pres/taglib
folder in the adventure-codepack-* release) is displayed in the following code box (comments
werde dropped):
class social_taglib_bookmark extends Document {
function social_taglib_bookmark(){ $this->__Attributes['width'] = '20'; $this->__Attributes['height'] = '20'; $this->__Attributes['title'] = null; $this->__Attributes['url'] = null; $this->__Attributes['target'] = null; // end function }
function transform(){
// get bookmark manager $sBM = &$this->__getServiceObject('modules::socialbookmark::biz','socialBookmarkManager');
// configure width and height $sBM->set('Width',$this->__Attributes['width']); $sBM->set('Height',$this->__Attributes['height']);
// konfigure URL parameters if($this->__Attributes['url'] != null){ $sBM->set('URL',$this->__Attributes['url']); // end if } if($this->__Attributes['title'] != null){ $sBM->set('Title',$this->__Attributes['title']); // end if } if($this->__Attributes['target'] != null){ $sBM->set('Target',$this->__Attributes['target']); // end if }
// return bookmark HTML code return $sBM->getBookmarkCode();
// end function }
// end class }
In order to make the title passed to the bookmark service dynamic, ist is well to define another
tag library, that only contains the difference of functionality, but uses the existing library. To
make it easier to show the proceeding to you, I define, that the tag should be named
my:bookmark. Hence, as described in the
user specific taglibs tutorial,
the class name of the taglib must be my_taglib_bookmark. The taglib then contains the
following source code:
import('modules::socialbookmark::pres::taglib','social_taglib_bookmark');
class my_taglib_bookmark extends social_taglib_bookmark {
function my_taglib_bookmark(){ // execute the constructor of the parent class parent::social_taglib_bookmark(); // end function }
function transform(){
// gather the title of the current page $Title = /* current title */;
// fill the title attribute, that is used by the parent class $this->__Attributes['title'] = $Title;
// generate output with aid of the parent class return parent::transform();
// end function }
// end class }
As you can see in the code box above, the transform() only contains the gathering
of the page's title. There, the title is assigned to the attributes offset used by the parent class.
The core function is still done by the social_taglib_bookmark class. Because of the
fact, that our wrapper class inherits from social_taglib_bookmark, it is still
possible to use the
attributes within the tag definition. The following code shows you how to include the new taglib into
your templates:
<core:addtaglib namespace="dein::namespace" prefix="my" class="bookmark" />
<my:bookmark width="16" height="16" target="_blank" />
2.4. Update handling
In case of API changes to the third-party library, adaptation to the new API is limited to filling
the attribute title, because the call of the parent transform() is still
the same. A second advantage is, that the API of the wrapper class my_taglib_bookmark
remains the same and the components using the API of the wrapper class must not be changed. The
example described in the present tutorial only contained the enhancement of taglibs, but this principle
can be adopted to any other domain.
Comments
Do you want to add a comment to the article above, or do you want to post additional hints? So please click here. Comments already posted can be found below.
There are no comments belonging to this article.
|