Pseudo Interfacce

Quanto esposto in questa pagina riguarda lo sviluppo PHP avanzato di CakePOWER. L'argomento tratta una particolare tecnica di OutsideCoding il cui scopo è permettere al nostro software di essere personalizzato senza che ne vengano modificati i files sorgenti.

Linguaggi evoluti quali Java utilizzano il concetto di interfaccia come una classe “che verrà implementata in seguito”. Questa tecnica consente dunque di utilizzare proprietà e metodi di una classe che può essere “implementata” in modo differente. Il sistema andrà ad utilizzare la classe implementante.

PHP (4 e 5) non permette di definire delle vere e proprie interfacce. Per attuare questa fenomenale tecnica di sviluppo ho utilizzato delle semplici regole di naming.

Un normale approccio alla verticalizzazione

Come esempio prendiamo un semplice modello che ci permette di gestire i vini della nostra cantina:

// /app/models/wine.php

class Wine extends AppModel {
    var $name = 'Wine';
}

Questo modello ci può andare bene fintanto che teniamo in cantina poche bottiglie… Passano gli anni e arriviamo a dover gestire alcune centinaia di bottiglie… Decidiamo di dividerle per regione.

A questo punto dobbiamo mettere mano al nostro modello per aggiungere una relazione:

// /app/models/wine.php

class Wine extends AppModel {
    var $name = 'Wine';

    var $belongsTo = array( 'Region' );

}

Questa operazione di modifica del modello originario può sembrare semplice nell'ambito di questo esempio ma diventa estremamente dispendiosa se abbiamo distribuito il nostro gestionale di cantina a tutti i nostri amici!

La soluzione più semplice sarebbe poter distribuire un pacchetto di modifiche che possa in qualche modo integrarsi e modificare il software esistente mantenendo quanto di buono ha da offrire l'attuale versione (validazioni, layouts, etc…)

Come creare Pseudo Intefacce

Ecco come modificare il nostro modello di base affinchè sia possibile implementarlo dall'esterno:

// /app/models/wine.php

Hook::implement('Wine');

class Wine__Interface__ extends AppModel {
    var $name = 'Wine';
}

Il metodo Hook::implement va a cercare l'esistenza di un'implementazione di Wine definita nel sistema. Wine può essere implementato da un plugin o direttamente dall'app_controller o dal bootstrap di applicazione per creare delle implementazioni on the road da utilizzarsi durante lo sviluppo.

Se non esiste alcuna implementazione di Wine sarà il metodo stesso a crearne una neutra che CakePHP potrà utilizzare come meglio crede!

Come implementare Pseudo Interfacce

Implementare un'interfaccia significa creare una classe che la estenda e che porti il corretto nome della stessa seguendo le regole di naming di CakePHP:

// /app/vendors/my_wine_model.php

class Wine extends Wine__Interface__ {
    var $belongsTo = array( 'Region');
}

In secondo luogo è necessario comunicare al sistema l'esistenza di questa implementazione. Questa operazione va fatta durante il bootstrapping sia a livello di applicazione che di plugin:

// /app/config/bootstrap.php

Hook::implement('Wine', VENDORS.'my_wine_model.php');

Questo metodo è lo stesso utilizzato per definire un'interfaccia solo che in questo caso passiamo anche la path completa della classe che la implementa.

Esiste anche la possibilità di passare un terzo parametro il cui scopo è contestualizzare un'implementazione ad un identificativo di lingua (it, en, etc…). Diventa così possibile variare le implementazioni per realizzare contestualizzazioni di lingua anche molto complesse.

Implementare le Viste

// /app/config/bootstrap.php

Hook::implementView('YUsers.index',APP.'/views/implementations/my_user_index.ctp');

La richiesta della vista dell'action index del controller YUsers viene intercettata da CakePOWER il quale la modifica forzando l'utilizzo del file specificato.

NOTA: qualunque file di vista può essere implementato. Non è necessaria alcuna configurazione specifica della vista stessa.

Come per gli altri tipi di implementazione è possibile passare il parametro di lingua per contestualizzare l'implementazione.

Implementare i Layouts

// /app/config/bootstrap.php

Hook::implementLayout( 'freyr.index', APP.'/views/layout/my_layout.ctp' );

Il nome della posizione ricercata è composto da {pluginName}.{layoutName}. Nel caso si stia implementando un layout generico (non di plugin) la posizione cercata sarà {layoutName}.

Come per gli altri tipi di implementazione è possibile passare il parametro di lingua per contestualizzare l'implementazione.

Implementare gli Elements

// /app/config/bootstrap.php

Hook::implementLayout( 'freyr.element_name', APP.'/views/elements/my_custom_element.ctp' );

Il nome della posizione ricercata è composto da {pluginName}.{elementName}. Nel caso si stia implementando un element generico (non di plugin) la posizione cercata sarà {elementName}.

Come per gli altri tipi di implementazione è possibile passare il parametro di lingua per contestualizzare l'implementazione.

Limiti delle Pseudo Interfacce

Ogni oggetto può essere implementato una sola volta.

Siccome la definizione di un'implementazione è definita nel file “bootstrap.php” (di applicazione o di plugin) se due plugins tentano di implementare la medesima interfaccia solo l'ultimo avrà successo.

Le pseudo-interfacce sono un sistema veloce per personalizzare e verticalizzare applicazioni di terze parti (es. plugins) ma limitano ad un solo livello di personalizzazione.

Quando si sviluppa del software che si intende riutilizzare o distribuire è consigliabile studiare attentamente i possibili punti di integrazione ed esporli tramite degli Hooks documentati in API.

 
/home/juniorcm/public_html/wiki/data/pages/cakepower/pseudo-interface.txt · Ultima modifica: 06/08/2009 11:17 da peg
 
Ad eccezione da dove è diversamente indicato, il contenuto di questo wiki è sotto la seguente licenza:GNU Free Documentation License 1.2
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki