Welcome, Guest! Log In | Create Account

The Basic Of XCube Delegate

From xoopscube

Jump to: navigation, search

Contents

The Basic of XCube_Delegate

This document explains the basic usage of the XCube_Delegate class and its features in detail.
This document is written for programmers who at least have familiarity with the following knowledges:

- PHP4/PHP5
- the 'Preload' feature of XOOPS Cube
- the 'Proxy' and 'Deleagete' design patterns

The delegation feature of XOOPS Cube does not actually conform to the 'Delegate' and/or 'Proxy' design patterns by GoF,
but readers are encouraged to refer to the following documents to understand what these patterns are and how they
actually work in applications.




machine translated :) ----

In the beginning

In this document, it explains two usages of "Transferred side" and "Side (side in which it applies for the transfer) where the transfer is received" at the same time by using Derigat. However, the side adjusted to the side transferred in general is thought that a different respectively programmer mounts in XOOPS Cube.

It is necessary to understand a clear difference of the side adjusted to the
transferred side before the explanation can be read.



Especially, Derigat is a technology that abstracts the method as well as the method of virtual.
It is necessary to understand the range that can be recognized from a transferred side, a side where the transfer is received, the main logic (position where the program counter is passed), and scope.
Override cannot be used as shown in above-mentioned figure to change the behavior of doExecute() in this case.
Basically, Derigat will be used under such a condition.

Usage of Derigat

Enhancing

The extendibility by Prirord can be given to base and add-on (module) by transferring processing outside.

In general, it is assumed that it is an ideal to preserve the setting in the data base and the file, to change these values by the special management program, and to do the function in the switch in the CMS application for the end user. However, when it undertakes the upgrade of such an application, a lot of man power and the working hourss of the update of the change of the design, coding, the test, and DB etc. and release, etc. are needed. Moreover, the function becomes a selection from the option installed in the application.

On the other hand, Derigat becomes the program and a solution to the end. The mechanism named Prirord that puts the program in and out is mounted, and each base module of XOOPS Cube can be changed only by setting up the file as the operation condition is easy, and can ..low cost.. correspond more than an official specification change (= function addition) in the application.

    • function addition by preference '

* It is comprehensible in the end user.
* It is more convenient for the end user than the programmer.
* Switch of "Fixed function" that switches processing installed in application
* The developer needs the update etc. such as DB according to the design, coding, the test, debugging, and the necessity from the management screen.
* The unification and reorganization of the function that can be put on a
version on the way is difficult.
* It is permanent or suitable for the function with a large grain degree.
* The end user exchanges knowhow.

** enhancing by Derigat

  • The end user doesn't understand easily.
  • It is more convenient for the programmer than the end user.
  • Cho of .."Programmable" to transfer processing outside as Prirord etc...

Hiroga

  • The developer should change the transfer part to the template pattern, and do the refactoring

to Derigat.

  • The unification and reorganization of the function that can be put on a

version on the way is easy.

  • It is ..tentative.. experimental or suitable for the function with a small

grain degree.

  • The end user exchanges Prirordofail.

It is not the conflicting one though this two object. Preference is "Switch of a fixed function that it costs the development cost", and Derigat is "Enhance by the outside where it doesn't cost the development cost. "
It thinks about Derigat, and there is fit work, too and the procedure of transplanting it to preference is thought with Derigat experimentally first corresponding to the possibility examination of the function enhancing from first to last.

Base callback

Generally, add-on registers and mounts the callback for the controller who has the loop. Derigat can be used for the relation of the Base module and add-on as an interface of a united callback though various mounting is thought.

Event notification

Derigat

It is assumed that there is a class that calls protected method during processing as
follows.

class ClassA{
function ClassA() { ... }
// public
function Execute()
{
// $obj = ...
// ...
// ...

$this->doExecute($obj);
}

function doExecute($obj)
{
}
}

When the doExecute() method is transferred, it is possible to write as follows.


class ClassA
{
var $mDoExecute = null;

function ClassA()
{
$this->mDoExecute = new XCube_Delegate();
}

//public
function Execute()
{
// $obj = ...
//...
//...

$this->mDoExecute->call($obj);
}
}

It transfers it.

Side where transfer is received

The transfer is done ..each function (method)... The program that receives the transfer registers the function in Derigatoinstans by using the XCube_Delegate::add() method.

function myFunc($obj)
{
print "Hello, world\n";
}

$fooInstance = new FooClass();
$fooInstance->mDoExecute->add("myFunc");

$fooInstance->Execute();

// Execution result
Hello, world

The XCube_Delegate::add() method accepts the following two kinds of specification as
a parameter.

  • PHP callback - XCube_Delegate::add (php callback format)
  • Static method XCube_Delegate::add ("Name of method of class name ::")

The following specification is chiefly used though the specification of PHP callback means the
same format as call_user_func etc.

  • Global function- XCube_Delegate::add ("Function name")
  • Static method XCube_Delegate::add (array ("Class name" and "Function name"))
  • Method XCube_Delegate::add of instance (array (&$obj "Function name"))

Derigatomanaja

Derigat can register the function only in Derigat made an instance by seeing from the side where the transfer processing is mounted for the class. Derigat is used as a member of the class that the programmer defines to have seen up to now, and making to the instance is done by the constructor of the class usually.

However, PHP is a dynamic program language and the one to advance processing by making the instance of the action etc. diverging especially ahead of processing according to progress and the content, and calling the method of the instance is the majority in today's PHP application. The class of this action is called action A class, and the member's Derigat is made Derigat B.

XOOPS Cube has the mechanism named Prirord as a mechanism to execute the extension code at the early stage. It is assumed that Prirord that wants to register the function in Derigat B of action A class is here, and makes this Prirord C.

Well, action A is executed at the stage before reading (declaration) as for this Prirord C. Therefore, it is not able not to know class A existence, and to make the PHP script engine an instance naturally at this point. Moreover, class A that differs from Prirord executed every time is not indispensable in processing. Whether it is declared is not understood according to the content of the request.

Then, the mechanism "Derigatomanajar" is prepared in XOOPS Cube as a representation (proxy) for each Derigat. This class is usually XCube_DelegateManager, and it is possible to enhance it. In general, the programmer accesses it from XCube_Root::getSingleton() -> getDelegatemanager().

"Derigatomanaja" accepts the registration of Derigat, and it works as a representation of the operation to Derigat regardless of after before it generates it/is generated. When the function registration operation is done to Derigat B that the realities are uncertain at the stage at the stage of Prirord C through Derigatomanaja, the operation is reflected at the stage where Derigat B is actually used.

Registration to manager

First of all, the programmer who designs class A should register Derigat B in Derigatomanaja by the constructor. Because management is done by the hush map, the registration name is necessary.

class ClassA
{
var $mDelegateC = null;

ClassA()
{
$this->mDelegateC =& new XCube_Delegate();
$this->mDelegateC->register('FooC');
}
}

Follow the convention of each base to avoid repetition with other programs though the registration name can be freely applied.

Derigat C was opened to the public outside as a result if it saw from class A. Moreover, a phenomenon near static happens so that Derigatomanaja may generalize the treatment of Derigat. It describes it later for this.

Registration of function

The problem of not seeing class A to say nothing of instance A in Prirord C(Be not declared) is not solved. Then, the function is registered in Derigatomanaja by using the character string 'ClassA.DelegateC'.

class PreloadC extends XCube_ActionFilter
{
function preBlockFilter()
{
$this->mRoot->mDelegateManager->add(
"FooC",
"PreloadC::myFunc"
);
}

function myFunc()
{
// ...
}
}

When class A is read, and made an instance by the processing after this, Derigatomanaja executes as a proxy and registers PreloadC::myFunc() in Derigat C.

Note in use

Enhancing of XCube_Delegate

Please note that final is specified in the XCube_Delegate class. When it is necessary to change the operation of Derigat, Derigatomanaja is changed. It is prohibited to achieve Porimorfizm instancing about XCube_Delegate in XOOPS Cube.

Method of non-recommendation

It provides with XCube_DelegateManager::call().
However, do not call it from the outside.
It is assumed that the following programs existed.

class ClassD
{
...
//public
function Execute()
{
//...

$this->doSomething();

//...
}

// protected
function doSomething()
{
}
}

Processing in method Execute() of public is made to jump to doSomething() in this program on the way. It is assumed that the programmer changed doSomething() to Derigat to answer an external enhancing. The program is as follows.

class ClassD
{
//...

//protected
var $mDoSomething = null;

// public
function ClassD()
{
$this->mDoSomething = new XCube_Delegate();
$this->mDoSomething->register("ClassD.doSomething");
}

//public
function Execute()
{
// ...
$this->mDoSomething->call();
//...
}
}

At this time, in the program of the outside

$manager =& XCube_Root::getSingleton()->getDelegateManager();
$manager->call("ClassD.doSomething");

Code..write..method..access..same..act..hit.

There is no specification for a specific class to conceal and to open the interface to the public in the PHP language. Therefore, a lot of classes of XOOPS Cube have "Generally, do not use it" method. Please bear a correct program in mind referring to API guide that can be acquired with Doxygen. //

static

The phenomenon that looks like static happens because it is united to Derigatomanaja for the registration function when the instance of Derigat is registered to the manager.

$instanceA->register("FooC", "funcE");
$instanceA->register("FooC", "funcF");

function funcE()
{
static $count = 0;
printf("hello(%d)\n", ++$count);
}

function funcF()
{
static $count = 0;
printf("good bye(%d)\n", ++$count);
}

// Execution result
hello(1).
good bye(1).

hello(2).
good bye(2).

When registering in Derigatomanaja, the buffer where the function registered in Derigat is maintained is shared. Therefore, maintaining Derigat different in each instance becomes difficult.

You will think (b) to be a different thing when registering in (a) and Derigatomanaja when it sees from the programmer who designs the class or Derigat is opened to the public as read only member and opening it to the public.

//(a)
ClassA
{
//public
//[Read Only] to add functions from outside.
var $mDelegateC = null;

function ClassA()
{
$this->mDelegateC =& new XCube_DelegateC();
}
}

//(b)
ClassA
{
//protected
var $mDelegateC = null;

function ClassA()
{
$this->mDelegateC =& new XCube_DelegateC();

$XCube_Root::getSingleton()->getDelegateManager()->register(...);
// OR
// $this->mDelegateC->register("FooC");
}
}