Anteprima
Vedrai una selezione di 11 pagine su 48
Appunti Ingegneria del software Pag. 1 Appunti Ingegneria del software Pag. 2
Anteprima di 11 pagg. su 48.
Scarica il documento per vederlo tutto.
Appunti Ingegneria del software Pag. 6
Anteprima di 11 pagg. su 48.
Scarica il documento per vederlo tutto.
Appunti Ingegneria del software Pag. 11
Anteprima di 11 pagg. su 48.
Scarica il documento per vederlo tutto.
Appunti Ingegneria del software Pag. 16
Anteprima di 11 pagg. su 48.
Scarica il documento per vederlo tutto.
Appunti Ingegneria del software Pag. 21
Anteprima di 11 pagg. su 48.
Scarica il documento per vederlo tutto.
Appunti Ingegneria del software Pag. 26
Anteprima di 11 pagg. su 48.
Scarica il documento per vederlo tutto.
Appunti Ingegneria del software Pag. 31
Anteprima di 11 pagg. su 48.
Scarica il documento per vederlo tutto.
Appunti Ingegneria del software Pag. 36
Anteprima di 11 pagg. su 48.
Scarica il documento per vederlo tutto.
Appunti Ingegneria del software Pag. 41
Anteprima di 11 pagg. su 48.
Scarica il documento per vederlo tutto.
Appunti Ingegneria del software Pag. 46
1 su 48
D/illustrazione/soddisfatti o rimborsati
Disdici quando
vuoi
Acquista con carta
o PayPal
Scarica i documenti
tutte le volte che vuoi
Estratto del documento

GRASP

UML descrive una responsabilità come “un contratto o un obbligo di un

classificatore”. Il Responsibility-Driven Design è un metodo di design che si

focalizza sugli oggetti come astrazioni comportamentali caratterizzate da

responsabilità, e migliora l’incapsulazione utilizzando un modello client-server.

Per creare le astrazioni comportamentali sì utilizzano comunemente le CRC-

card.

Applicare le responsabilità di un oggetto include: fare qualcosa da solo, come

creare un oggetto o effettuare calcoli; inizializzare un azione in altri oggetti;

controllare e coordinare attività in altri oggetti.

GRASP (General Responsibility Assignment Software Patterns) è una collezione

di pattern, usata nella progettazione object-oriented, che fornisce delle linee

guida per l'assegnazione di responsabilità alle classi e agli oggetti.

Ogni pattern illustra un problema che può verificarsi continuamente nel nostro

ambiente, e descrive il cuore della soluzione al problema, in modo tale che possa

essere usata sempre. I pattern sono: Creator, Information Expert, Low Coupling,

Controller, High Cohesion, Polymorphism, Pure Fabrication, Indirection,

Protected Variations.

Creator: risolve il problema di chi debba essere responsabile per la creazione di

una nuova istanza di una classe. Date due classi A e B, B potrebbe essere

responsabile per la creazione di A nel caso in cui B contenga (o nel complesso

aggreghi, registri, usi strettamente e contenga) le informazioni iniziali per A.

Information Expert: permette di assegnare correttamente le responsabilità agli

oggetti. Stabilisce che la responsabilità deve essere assegnata all'Information

Expert (la classe che possiede tutte le informazioni essenziali). Migliora

l’'incapsulamento e riduce così l'accoppiamento di altre classi per

l'implementazione della classe Information Expert.

Low Coupling: (accoppiamento: grado con cui ciascuna componente di un

software dipende dalle altre componenti) è un pattern valutativo, che stabilisce

come assegnare le responsabilità per supportare: bassa dipendenza tra classi;

basso impatto in una classe dei cambiamenti in altre classi; e alto potenziale di

riuso.

Controller: assegna la responsabilità di eventi di chiamata a sistema ad una classe

(che non sia ad interfaccia utente) che rappresenta l'intero sistema in uno

scenario di caso d'uso. Un controllore di casi d'uso potrebbe essere impiegato

per comunicare con tutti gli eventi di sistema di uno o più casi d'uso (ad esempio,

per i casi d'uso Crea Utente ed Elimina Utente, si può usare un solo controllore

ControlloreUtente, anziché due separati per ciascun caso d'uso).

High Cohesion: (coesione: misura di quanto strettamente correlate siano le varie

funzionalità messe a disposizione da un singolo modulo) è un pattern valutativo

che cerca di mantenere gli oggetti focalizzati, gestibili e intelligibili in maniera

appropriata. Un'alta coesione significa che le responsabilità di un dato elemento

sono fortemente correlate ed altamente focalizzate.

Polymorphism: la responsabilità di definizione delle variazioni dei

comportamenti basati sul tipo viene assegnata ai tipi per i quali avviene tale

variazione. Ciò viene ottenuto usando le operazioni di polimorfismo.

Pure Fabrication: è una classe che non rappresenta un concetto nel dominio del

problema. Ma viene creata per ottenere basso accoppiamento, alta coesione e

potenziale di riuso da esso derivante (quando non vi è

una soluzione presentata dal pattern Information

Expert).

Indirection: supporta il basso accoppiamento (ed il

potenziale di riuso) tra due elementi attraverso

l'assegnazione di responsabilità di mediazione tra di

loro ad un oggetto intermedio. Un esempio è

l'introduzione di un componente controllore per la

mediazione tra i dati (modello) e la loro

rappresentazione (vista) nel pattern Model-View-

Controller.

Protected Variations: protegge gli elementi dalle variazioni compiute in altri

elementi (oggetti, sistemi, sottosistemi) mascherandoli con un'interfaccia ed

usando il polimorfismo per creare diverse implementazioni di questa interfaccia.

Design Patterns

La Gang of Four (GoF) indica che i patterns possono avere 3 scopi:

Creazionali: astraggono il processo di istanziazione - Abstract Factory, Builder,

Factory Method, Prototype, Singleton.

Strutturali: sono legati a come le classi e gli oggetti sono composti per formare

strutture più grandi - Adapter, Bridge, Composite, Decorator, Facade, Flyweight,

Proxy.

Comportamentali: sono legati agli algoritmi e l’assegnamento di responsabilità

tra oggetti - Chain of Responsibility, Command, Interpreter, Iterator, Mediator,

Memento, Observer, State, Strategy, Template Method, Visitor.

Considerazione: composizione invece di ereditarietà

Le due tecniche più comuni per riutilizzare funzionalità nei sistemi object-

oriented sono l’ereditarietà tra classi e la composizione di oggetti (combinare

oggetti semplici o tipi di dato in oggetti più complessi). Favorire la composizione

di oggetti all’ereditarietà tra classi aiuta a mantenere ogni classe incapsulata e

concentrata su un compito. La delegazione è un modo di rendere la

composizione tanto potente per il riuso quanto l’ereditarietà.

Il problema dell’ereditarietà è che non viene affrontato in modo

corretto né l’Open/Closed Principle (OCP) né Protected

Variations (PV). Tuttavia si deve sapere che le superclassi non

sono l’unica astrazione possibile, ed è possibile utilizzare la

composizione, che è più flessibile e può cambiare a runtime.

Template Method [Pattern Comportamentale]

Questo pattern permette di definire la struttura di

un algoritmo lasciando alle sottoclassi il compito di

implementarne alcuni passi come preferiscono. In

questo modo si può ridefinire e personalizzare

parte del comportamento nelle varie sottoclassi

senza dover riscrivere più volte il codice in comune.

Normalmente sono le sottoclassi a chiamare i

metodi delle classi genitrici; in questo pattern è il

metodo template, appartenente alla classe genitrice, a chiamare i metodi

specifici ridefiniti nelle sottoclassi. Tale pattern aiuta

ad adempiere all’OCP.

Strategy [Pattern Comportamentale]

L'obiettivo di questa architettura è isolare un

algoritmo all'interno di un oggetto, in maniera tale da

risultare utile in quelle situazioni dove sia necessario

modificare dinamicamente gli algoritmi utilizzati da

un'applicazione.

Si pensi ad esempio alle possibili visite in una struttura

ad albero (visita anticipata, simmetrica, posticipata);

mediante il pattern strategy è possibile selezionare a tempo

di esecuzione una tra le visite ed eseguirla sull'albero per

ottenere il risultato voluto. Tale pattern aiuta ad

implementare OCP e obbedisce alle PV, inoltre favorisce la

composizione rispetto all’ereditarietà (has-a invece di is-a).

Considerazione: il New è considerato dannoso

Il New alloca memoria ogni volta che un client ha bisogno di una referenza, non

c’è controllo sul ciclo di vita delle istanze e crea una dipendenza tra l’utente e la

classe concreta implementata dalla referenza (viola il Dependency Inversion

Principle - DIP). Inoltre le modifiche nel costruttore della classe concreta creano

problemi nei client (viola l’OCP).

Factory Method [Pattern Creazionale]

Questo pattern indirizza il problema della

creazione di oggetti senza specificarne l'esatta

classe. Questo pattern raggiunge il suo scopo

fornendo un'interfaccia per creare un oggetto,

ma lascia che le sottoclassi decidano quale

oggetto istanziare.

Considerazione: il problema delle notifiche

Nuovi osservatori (e nuovi tipi di osservatori) possono apparire in un tempo

futuro. Quando una classe “notifica” un’altra è esposta alla sua interfaccia

(quindi dipende da quell’interfaccia).

Observer [Pattern Comportamentale]

Sostanzialmente il pattern si basa su uno o più oggetti,

chiamati osservatori o observer, che vengono registrati

per gestire un evento che potrebbe essere generato

dall'oggetto "osservato", che può essere chiamato

soggetto. Oltre all'observer esiste il concrete Observer

che si differenzia dal primo perché implementa

direttamente le azioni da compiere in risposta ad un

messaggio; riepilogando il primo è una classe astratta, il

secondo no. Uno degli aspetti fondamentali è che tutto il

funzionamento dell'observer si basa su meccanismi di

callback, a cui spesso vengono passati dei parametri in fase di

generazione dell'evento.

Façade [Pattern Strutturale]

Significa "facciata", ed infatti indica un oggetto che

permette, attraverso un'interfaccia più semplice,

l'accesso a sottosistemi che espongono interfacce

complesse e molto diverse tra loro, nonché a blocchi di

codice complessi. Fornisce un’interfaccia unificata ad un

insieme di interfacce di un sottosistema: definisce

un’interfaccia a livello più alto che rende il sottosistema

più facile da utilizzare. Nelle librerie standard Java (Java

2 Platform, Standard Edition) questo pattern viene spesso

usato; si considerino ad esempio tutte le classi disponibili

per fare il rendering del testo o delle forme geometriche,

un programmatore può ignorare tutte queste classi e utilizzare unicamente le

classi façade (Font e Graphics) che offrono un'interfaccia più semplice e

omogenea.

Singleton [Pattern Creazionale]

È un pattern che ha lo scopo di garantire che di una

determinata classe venga creata una e una sola istanza, e di

fornire un punto di accesso globale a tale istanza.

L'implementazione più semplice di questo pattern prevede

che la classe singleton abbia un unico costruttore privato, in

modo da impedire l'istanziazione diretta della classe

(fornisce anche un metodo "getter" statico che restituisce l'istanza della classe).

Proxy [Pattern Strutturale]

Nella sua forma più generale, un proxy è una classe che

funziona come interfaccia per qualcos'altro. L'altro

potrebbe essere qualunque cosa: una connessione di

rete, un grosso oggetto in memoria, un file e altre risorse

che sono costose o impossibili da duplicare. Tipicamente

viene creata un'istanza di oggetto complesso, e

molteplici oggetti proxy, ognuno dei quali contiene un

riferimento al singolo oggetto complesso. Ogni

operazione svolta sui proxy viene trasmessa all'oggetto

Dettagli
A.A. 2019-2020
48 pagine
SSD Ingegneria industriale e dell'informazione ING-INF/05 Sistemi di elaborazione delle informazioni

I contenuti di questa pagina costituiscono rielaborazioni personali del Publisher simonagalante12 di informazioni apprese con la frequenza delle lezioni di Ingegneria del software e studio autonomo di eventuali libri di riferimento in preparazione dell'esame finale o della tesi. Non devono intendersi come materiale ufficiale dell'università Università degli Studi di Bologna o del prof Rossi Davide.