Document Actions

Componenti
medio

Up one level
Zope 3 è stato sviluppato nella prospettiva dei Componenti, che pervade tutto il framework sin dalle fondamenta.

Una delle differenze fondamentali tra i due "gusti" di Zope e' data dal fatto che, mentre in Zope 2 molte funzionalita' sono ottenute utilizzando i meccanismi di ereditarieta' multipla sugli oggetti python, Zope 3 e' stato sviluppato nella prospettiva dei Componenti.

Ma cosa e' un componente?

Vediamo prima di capire come si arriva ad averne bisogno!

Gli oggetti mediante i quali le applicazioni Zope 2 sono costruite tendono a implementare le proprie funzionalita' ereditando da molte mix-in class, ciascuna deputata a dotare l'oggetto di una specifica caratteristica. Questo comporta una effettiva facilita' alla specializzazione e al riuso del codice, ma anche una non trascurabile complessita delle classi che definiscono le applicazioni, una dipendenza molto rigida tra i vari blocchetti che contribuiscono al risultato finale, e una derivazione non sempre chiara del pezzo di codice responsabile di una specifica implementazione.

Classe Derivato

Per scardinare le controindicazioni dei meccanismi di ereditarieta' senza perderne le prerogative di flessibilita' e potenza e' stata introdotta l'Architettura a Componenti, che consente di distribuire la complessita' sui vari componenti che lo sviluppatore predispone, favorendo la realizzazione di singole classi piu' semplici e piu' facili da mantenere nel tempo, e rendendo piu' lineare aggiungere e modificare funzionalita' senza manipolare classi esistenti.

Il superamento del problema della dipendenza stretta che scaturisce dai meccanismi di ereditarieta' tra classi viene ottenuto introducendo il concetto di Interfaccia.

Cercando di semplificare, dal punto di vista di chi la utilizza una classe ha un comportamento che puo' essere descritto in prima battuta elencandone gli attributi e i metodi pubblici, e per ciascuno descrivendone il significato semantico. Per questo, una classe tende a implementare una o piu' "interfacce" di funzionamento che ne definiscono il comportamento.

Tale processo descrittivo consente di "sterilizzare" il contratto di funzionamento che ci si aspetta dalla classe rispetto alla effettiva implementazione di tale comportamento.

In sostanza, una classe dichiara di implementare una specifica interfaccia, ma senza necessariamente preoccuparsi di fornire l'effettiva implementazione di tale interfaccia: questo favorisce l'introduzione di Adattatori che possono fornire implementazioni alternative dell'interfaccia specifica in base al contesto.

Componente

Per fare un esempio, possiamo immaginare di disporre di una classe che dichiara di essere in grado di spedire una notifica ad una lista di iscritti. L'implementazione fornita a corredo si preoccupa di inviare tale notifica alla lista con una mail per ogni iscritto.

Ammettiamo ora di avere uno specifico contesto in cui l'implementazione richiesta consiste nell'invio di un SMS al posto della mail. In Zope 2 si deve direttamente modificare la classe responsabile della notifica (perdendo il comportamento originale o facendo in modo di saper discriminare tra i due), oppure la strada dell'ereditarieta' ci suggerisce di costruire una classe derivata da quella di partenza e di ridefinire il metodo responsabile della notifica, con grosso dispendio di energia per continuare a far funzionare la nostra classe modificata nel suo contesto operativo.

Con l'approccio a componenti invece tutto quel che dobbiamo fare e' descrivere la nostra implementazione mediante un adattatore, che sostituira' l'implementazione originale grazie al framework a componenti adeguatamente istruito da un file di configurazione che si limita a descrivere chi deve implementare la specifica interfaccia nello specifico contesto.

In sintesi, ammettiamo di avere una richiesta di attivazione di un metodo di interfaccia su un oggetto che dichiara tale interfaccia, il Component Framework individua il codice che implementa il metodo richiesto secondo le configurazioni che accoppiano l'interfaccia alle implementazioni disponibili, quindi lo esegue.

Cio' implica che modificare un certo comportamento di uno specifico oggetto e' semplice quanto produrre un file di configurazione.

L'architettura a componenti di Zope 3 fornisce quindi un meccanismo che rende relativamente semplice assemblare oggetti tra loro: gli oggetti sono connessi in base alle interfacce che dichiarano, questo porta al concetto di componente secondo Zope 3.

Un Componente Z3 e' un oggetto con delle interfacce pubbliche dichiarate, implementate mediante una o piu' classi python.

Inoltre i componenti sono oggetti disaccoppiati che facilmente possono essere connessi tra loro.

Una nota conclusiva e' d'obbligo! L'architettura a componenti e' un servizio che si affianca al normale meccanismo di ereditarieta' che chiaramente resta funzionante, in quanto proprio di Python, e in molti casi ancora indispensabile.

Biblio

Una trattazione teorica piuttosto chiara e generica dello sviluppo basato su componenti si trova nel numero 4 del 2003 della rivista Upgrade

by Maurizio Delmonte last modified 2007-06-06 10:15
Contributors: Maurizio Delmonte