Concetto: Componente
Un componente è una parte incapsulata di un sistema, idealmente una parte non irrilevante, quasi indipendente e sostituibile di un sistema che soddisfa una chiara funzione nel contesto di un'architettura ben definita.
Relazioni
Descrizione principale

Definizione

L'industria del software e la relativa letteratura utilizzano il termine "componente" facendo riferimento a diversi argomenti. Viene spesso utilizzato in senso lato per indicare "una parte costituente". Viene inoltre utilizzato frequentemente in senso stretto per indicare delle caratteristiche specifiche che consentono la sostituzione e l'assemblaggio in sistemi più grandi.

In RUP, si utilizza il termine "componente" per indicare una parte incapsulata di un sistema, idealmente una parte non irrilevante, quasi indipendente e sostituibile di un sistema, che soddisfa una chiara funzione nel contesto di un'architettura ben definita. Sono compresi:

  • Componente di progettazione - una significativa parte incapsulata della progettazione, e quindi include dei sottosistemi di progettazione e a volte importanti classi di progettazione e pacchetti di progettazione.
  • Componente di implementazione - una significativa parte incapsulata dell'implementazione, in genere del codice che implementa un componente di progettazione.

Idealmente la progettazione riflette l'implementazione, quindi si può fare riferimento ai soli componenti, poiché ognuno di essi dispone di una progettazione e di un'implementazione.

L'UML ([UML04]) definisce "componente" come:

Una parte modulare di un sistema che racchiude il contenuto e la cui manifestazione è sostituibile all'interno del relativo ambiente. Un componente definisce il suo comportamento in termini di interfacce fornite e richieste. Quindi un componente serve come tipo, la cui conformazione viene definita dalle interfacce fornite e richieste (comprendendo sia la semantica statica che quella dinamica).

Un componente viene definito come il sottotipo di una classe strutturata che fornisce un componente con degli attributi e delle operazioni, in grado di partecipare a delle associazioni e generalizzazioni e con una struttura interna e delle porte. Per ulteriori dettagli consultare Concetto: Classe strutturata.

Esiste un determinato numero di stereotipi standard UML da applicare al componente, ad es. <<sottosistema>> per modellare componenti su larga scala, e <<specifica>> e <<realizzazione>> per modellare componenti con delle distinte definizioni di specifica e realizzazione, dove una specifica può avere più realizzazioni.

In RUP l'utilizzo del termine componente è più vasto della definizione UML. Piuttosto che definire i componenti come aventi caratteristiche quali la modularità, la distribuibilità e la sostituibilità, consigliamo queste ultime come caratteristiche auspicabili dei componenti. Leggere la sezione riportata di seguito sulla sostituibilità dei componenti.

Sostituibilità dei componenti

Nella terminologia RUP e UML i componenti devono essere sostituibili. Tuttavia, questo può significare solo che il componente espone una serie di interfacce che nascondono un'implementazione sottostante.

Esistono altri tipi di sostituibilità, più forti. Sono elencati di seguito.

Sostituibilità dei file origine

Se due classi vengono implementate in un unico file di codice sorgente, di solito non è possibile controllare ed assegnare la versione alla singola classe.

Tuttavia, se un insieme di file implementa completamente un unico componente e nessun altro, in quel caso sarà possibile sostituire i file origine del componente. Questa caratteristica facilita il controllo versione del codice sorgente del componente, il suo confronto con la linea di base e il suo riutilizzo.

Sostituibilità di distribuzione

Se due classi vengono distribuite in un unico file eseguibile, la singola classe non sarà sostituibile in modo indipendente in un sistema distribuito.

Una caratteristica auspicabile per i componenti con più ampia granularità è di essere "sostituibili nella distribuzione", consentendo alle nuove versioni del componente di essere distribuite senza dover ricreare gli altri componenti. Questo in genere significa che esiste un file o un insieme di file che distribuisce quel componente e non altri componenti.

Sostituibilità runtime

Se un componente può essere ridistribuito in un sistema in esecuzione, viene detto "sostituibile nel runtime". Questo consente l'aggiornamento del software senza la perdita della disponibilità.

Trasparenza della posizione

I componenti con interfacce di rete indirizzabili vengono definiti aventi "trasparenza di posizione". Questo consente ai componenti di essere riposizionati su altri server o di essere replicati su più server, per supportare la tolleranza agli errori, il bilanciamento del carico e così via. Questi tipi di componenti spesso vengono denominati "distribuiti" o "distribuibili".

Modellazione dei componenti

Il componente UML è un costrutto di modellazione che fornisce le seguenti funzioni:

  • può raggruppare le classi per definire una parte di granularità più ampia di un sistema
  • può separare le interfacce visibili dall'implementazione interna
  • può disporre di istanze che si eseguono al runtime

Un componente dispone di un certo numero di interfacce fornite e richieste, che formano le basi di collegamento fra i componenti. Un'interfaccia fornita è un'interfaccia implementata direttamente dal componente oppure è una delle sue classi di realizzazione o dei suoi sottocomponenti, oppure è il tipo di una porta fornita del componente. Un'interfaccia richiesta viene progettata da una dipendenza di utilizzo dal componente o da una delle sue classi di realizzazione o dei suoi sottocomponenti oppure è il tipo di una porta richiesta.

Un componente dispone di una vista esterna (o vista "scatola nera") tramite le relative proprietà e operazioni visibili pubblicamente. Facoltativamente è possibile collegare una funzionalità come la macchina a stati di protocolli ad un'interfaccia, ad una porta e al componente stesso, per definire in modo più preciso la vista esterna rendendo espliciti i vincoli dinamici nella sequenza delle chiamate di operazioni. Il collegamento fra i componenti di un sistema o di un altro contesto possono essere definiti strutturalmente utilizzando le dipendenze fra le interfacce del componente (in genere nei diagrammi dei componenti).

Facoltativamente è possibile effettuare una specifica più dettagliata della collaborazione strutturale utilizzando le parti e i connettori in strutture composte, per specificare il ruolo o la collaborazione dei livelli di istanza fra i componenti. Si tratta della vista interna del componente (o vista "scatola bianca") tramite le sue proprietà private e le sue classi di realizzazione o i suoi sottocomponenti. Questa vista mostra come viene realizzata internamente la funzionalità esterna. La corrispondenza fra la vista esterna e quella interna viene ottenuta tramite le dipendenze (nei diagrammi dei componenti), oppure tramite connettori di delega per le parti interne (nei diagrammi di strutture composte).

RUP consiglia di utilizzare i componenti come rappresentazione di sottosistemi di progettazione. Per ulteriori dettagli consultare Work Product: Design Subsystem, Task: Subsystem Design, and Guida: Sottosistema di progettazione. Consultare anche le definizioni in Concetto: Classe strutturata.

Creazione di un'istanza di componente

Un'istanza di componente può essere o non essere creata direttamente al runtime.

Un componente istanziato indirettamente viene implementato o realizzato da una serie di classi, sottocomponenti o parti. Il componente stesso non compare nell'implementazione; serve come progettazione che un'implementazione deve seguire. L'insieme di classi di realizzazione, di sottocomponenti o parti deve coprire l'intera serie di operazioni specificate nell'interfaccia fornito del componente. Il modo per implementare il componente è responsabilità di chi effettua l'implementazione.

Un componente istanziato direttamente specifica la propria implementazione incapsulata; viene istanziato come oggetto indirizzabile. Significa che un componente di progettazione dispone di un costrutto corrispondente nel linguaggio dell'implementazione, quindi è possibile farne riferimento esplicitamente.

Rappresentazione UML 1.x

UML 1.5 ha definito "componente" come segue:

Una parte modulare, distribuibile e sostituibile di un sistema che racchiude l'implementazione ed espone un insieme di interfacce. Un componente in genere viene specificato da una o più classi o sottocomponenti che vi risiedono, e possono essere implementati da uno o più artefatti (ad es., file binari, eseguibili o script).

In UML 1.3 e nelle versioni precedenti di UML, la notazione "componente" veniva utilizzata per rappresentare i file nell'implementazione. I file non vengono più considerato come "componenti" dalle definizioni dell'ultimo UML. Tuttavia, molti tool e profili UML usano ancora la notazione di componente per rappresentare i file. Per ulteriori argomentazioni sulla rappresentazione dei file in UML consultare Guida: Elemento di implementazione.

Dalla prospettiva di modellazione, i componenti erano paragonati ai sottosistemi UML in UML 1.5, poiché fornivano modularità, incapsulamento ed istanze in grado di andare in esecuzione al runtime. RUP considera il costrutto di modellazione del componente UML 1.5 una notazione alternativa per rappresentare i sottosistemi di progettazione. Per ulteriori dettagli consultare Prodotto di lavoro: Sottosistema di progettazione e Guida: Sottosistema di progettazione.

Per ulteriori informazioni consultare Differenze fra UML 1.x e UML 2.0.