Bookmark and Share
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 è data dal fatto che, mentre in Zope 2 molte funzionalità sono ottenute utilizzando i meccanismi di ereditarietà multipla sugli oggetti Python, Zope 3 è stato sviluppato nella prospettiva dei Componenti.

Ma cosa è 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 funzionalità ereditando da molte mix-in class, ciascuna deputata a dotare l'oggetto di una specifica caratteristica. Questo comporta una effettiva facilità 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 ereditarietà senza perderne le prerogative di flessibilità e potenza è stata introdotta l'Architettura a Componenti, che consente di distribuire la complessità sui vari componenti che lo sviluppatore predispone, favorendo la realizzazione di singole classi più semplici e più facili da mantenere nel tempo, e rendendo più lineare aggiungere e modificare funzionalità senza manipolare classi esistenti.

Il superamento del problema della dipendenza stretta che scaturisce dai meccanismi di ereditarietà 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 può 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 più "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'ereditarietà 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 è descrivere la nostra implementazione mediante un adattatore, che sostituirà 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.

Ciò implica che modificare un certo comportamento di uno specifico oggetto è 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 è un oggetto con delle interfacce pubbliche dichiarate, implementate mediante una o più classi python.

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

Una nota conclusiva è d'obbligo! L'architettura a componenti è un servizio che si affianca al normale meccanismo di ereditarietà 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 2009-01-22 13:36
Contributors: Maurizio Delmonte