• Non ci sono risultati.

3 Tecnologie Web: approcci avanzati

N/A
N/A
Protected

Academic year: 2022

Condividi "3 Tecnologie Web: approcci avanzati"

Copied!
32
0
0

Testo completo

(1)

Tecnologie Web:

approcci avanzati

a.a. 2020/2021

3

Anna Goy

(2)

Object-oriented

introduzione PHP:

(3)

Object-Oriented Programming → classi e istanze:

• una classe è un’astrazione che rappresenta le proprietà comuni (struttura e comportamento) a un insieme di oggetti concreti (istanze); una classe, in un certo senso, rappresenta un concetto

• un’istanza (oggetto) è un’entità concreta, che esiste nel tempo (viene

costruita e distrutta) e nello spazio (occupa memoria); un'istanza (oggetto) è sempre "istanza di una classe" e rappresenta un oggetto concreto che ha

tutte le proprietà di quella classe Per esempio:

OOP: classi e istanze - I

classe Libro (concetto astratto di "libro")

un libro specifico

(istanza, oggetto) è un'istanza di...

(4)

Una classe può anche essere vista come un modello (un template) che

definisce la struttura e il comportamento di un'insieme di istanze (oggetti) Una classe può essere vista come la definizione di un nuovo tipo di dato, definito dal programmatore

Per esempio:

• se nel mio programma devo gestire un insieme di utenti, accanto ai tipi predefiniti (stringhe, numeri interi, date, ...) potrebbe essermi utile il tipo di dato (classe) Utente

• le istanze di una classe sono quindi oggetti del tipo definito dalla classe: le istanze della classe Utente sono "oggetti di tipo Utente"

OOP: classi e istanze - II

(5)

Una classe è simile (ma NON identica!) alla definizione di una tabella in un database (relazionale), che rappresenta una certa entità

Un'istanza (oggetto) è simile ad un record specifico

• per es, in un database posso definire una tabella che rappresenta l'entità Utente, definendo i campi che la caratterizzano (per es: nome, cognome, data-di-nascita, ...)

• ogni record di tale tabella rappresenta un utente concreto ha valori specifici per i campi (per es: "Mario", "Rossi", "1234567", ...)

• analogamente, posso definire una classe che rappresenta il concetto di Utente, con le proprietà che tutti gli utenti devono avere (per es: nome, cognome, data-di-nascita, ...)

• ogni istanza di tale classe rappresenta un utente concreto ha valori specifici per le proprietà (per es: "Mario", "Rossi", "1234567", ...)

OOP: classi e istanze - III

(6)

La principale (e fondamentale) differenza tra tabelle/record e classi/istanze

(oggetti) è che classi e istanze (oggetti) contengono anche funzioni, operazioni, detti "metodi"

L'insieme dei metodi (funzioni, operazioni) di una classe – e di conseguenza di tutte le sue istanze – rappresentano il suo comportamento o la sua interfaccia Per esempio, nella classe Utente possiamo definire un metodo (funzione) per cambiare il numero di telefono: cambia_tel(nuovo_num)

Supponiamo che, nel nostro programma, la variabile mr contenga l'istanza di Utente che rappresenta Mario Rossi; se Mario Rossi ha cambiato numero di telefono, per aggiornare i suoi dati dobbiamo invocare il metodo (la funzione) sull'oggetto che rappresenta Mario Rossi, quindi:

OOP: metodi (funzioni)

(7)

Insieme delle operazioni che possono essere invocate su un oggetto (istanza)

= insieme dei metodi (pubblici) di una classe (e quindi di tutte le sue istanze)

= interfaccia di quella classe (e quindi di tutte le sue istanze)

= API (Application Programming Interface)

Le API sono lo strumento per rendere disponibile ad altri programmatori le funzionalità di un programma (classe)

Per esempio: "programma" per includere una mappa nel mio sito ed operare su di essa = classe Map (definita da Google) → le API della classe Map mi

permettono di creare una mappa, centrarla su una città, ecc...

OOP: API

(8)

Ma come faccio a creare una nuova istanza della classe Utente (cioè un oggetto di tipo Utente), che rappresenta Mario Rossi, e metterla nella variabile mr?

Nella classe Utente definiamo un metodo speciale, chiamato costruttore, che, quando viene invocato, crea una nuova istanza della classe (e assegna alle

proprietà dei valori specifici)

Per invocare il costruttore di una classe, generalmente si usa lo stesso nome della classe, preceduto dalla keyword new:

mr = new Utente("Mario", "Rossi");

Se il costruttore, nella classe Utente, è definito correttamente, i valori

contenuti nei parametri (attuali): "Mario", "Rossi" verranno assegnati alle proprietà nome, cognome dell'istanza contenuta nella variabile

OOP: costruttori

(9)

In linea di massima i metodi vengono invocati su oggetti specifici (è il numero di Mario che voglio modificare, NON il concetto di numero di tel. della classe Utente!)

⇒• prima creo un'istanza, invocando un costruttore (oppure utilizzo un'istanza predefinita, per es. un oggetto del DOM)

• poi invoco il metodo (definito nella classe) sull'istanza

In certi casi però un metodo (definito nella classe) non deve modificare dei dati in un'istanza specifica, ma serve semplicemente per offrire un servizio, una funzionalità; per es. il metodo sqrt, della classe Math, che restituisce la radice quadrata del valore che gli viene passato come parametro

[esempio tratto da Java!]

Math.sqrt(x);

Questi metodi si chiamano statici e vengono invocati direttamente sulla classe

OOP: metodi

(10)

Grady Booch nel suo famoso libro (Booch G. Object Oriented Design with applications, Benjamin-Cummings, 1991) definisce (tra gli altri…) 4 principi fondamentali dell'object-oriented programming:

1. Astrazione

2. Incapsulamento (information hiding) 3. Modularità

4. Gerarchia

Vediamo il secondo (information hiding) e il terzo (modularità)

OOP: i principi di Booch

(11)

Incapsulamento

(information hiding)

OOP: information hiding

L’incapsulamento è il principio secondo cui la struttura interna, il funzionamento interno, di un

oggetto non deve essere visibile all’esterno

L’incapsulamento (o information hiding) è il processo che nasconde quei dettagli, relativi al funzionamento di un oggetto, che non costituiscono le sue caratteristiche essenziali e distintive

⇒ ogni oggetto è costituito da 2 parti:

• l’interfaccia (vista “esterna”) → visibile

• l’implementazione (vista “interna”) → nascosta

(12)

Modularità

OOP: modularità

La modularità consiste nella

suddivisione di un sistema in una serie di componenti indipendenti, che

interagiscono tra loro per ottenere il risultato

⇒ ogni oggetto (modulo) è specializzato in un certo compito: tutti gli altri oggetti (moduli) possono rivolgersi a lui (inviandogli un messaggio) se hanno bisogno dei suoi servizi (in cui lui è specializzato)

Per esempio, pensate a com'è organizzata la nostra società, attraverso la

modularizzazione delle funzioni e la collaborazione tra gli individui, ognuno specializzato

(13)

Metodo classico di software design = top-down functional (structured) design = scomposizione gerarchica funzionale

paradigma procedurale: procedura (algoritmo) = sequenza di passi per ↓ raggiungere il risultato

Pes es. iscrizione ad un appello = scomposizione in passi via via più semplici, elementari = procedura per iscriversi ad un appello

PROGRAMMI = PROCEDURE + STRUTTURE-DATI

Paradigma procedurale vs OOP - I

iscrizione

prenotaz.

login selez.es.

ins. id-pswd

ver. id-pswd

autorizzaz.

ecc…

(14)

Metodo alternativo = object-oriented design = si parte dagli oggetti, non dalle funzionalità!

paradigma ad oggetti: oggetti che interagiscono tra loro scambiandosi dei↓ messaggi = collaborazione per raggiungere il risultato

Pes es. iscrizione ad un appello = entità coinvolte nell'attività e loro relazioni

Paradigma procedurale vs OOP - II

gestore dati studenti interfaccia

studenti id-pswd

verifica id-pswd

autorizz.

selez.

appello prenota app.

gestore ecc…

(15)

Alcuni vantaggi fondamentali dell'approccio Object-Oriented:

• Migliore organizzazione, strutturazione del software

• Maggiore possibilità di riuso

• Maggiore leggibilità

• Maggiore robustezza

• Estensione, modifica e manutenzione più semplici

• Migliore gestione del team di lavoro

Nella sua visione più semplice, l'approccio OO è una forma di

modularizzazione del software... in qualche modo un'estensione della tecnica di inclusione di file esterni, usata in molti linguaggi di scripting (vedi include(file) di PHP)

OOP: vantaggi

(16)

PHP: definire una classe - I

Torniamo a PHP e vediamo un esempio:

creiamo una classe che gestisce un conto corrente Nell'implementazione della classe ci saranno:

strutture dati (variabili) → si chiamano variabili d'istanza, sono private ("nascoste") e rappresentano le proprietà delle istanze della classe

• un costruttore → un metodo (funzione) pubblico per costruire nuove istanze (conti correnti)

NB: in PHP una classe può avere un solo costruttore!

metodi (funzioni) pubblicamente accessibili (interfaccia, API) NB1 il loro funzionamento è "nascosto" (implementazione)

NB2 per ogni variabile d'istanza (privata), è buona norma avere due metodi pubblici:

(17)

Per definire cosa appartiene all'interfaccia pubblica (visibile, accessibile) e cosa all'implementazione privata ("nascosta") si utilizzano gli

access modifiers:

• public: variabili (e metodi/funzioni) definiti public sono accessibili (= visibili) da qualunque punto del programma PHP (che "vede" quella classe)

• private: variabili (e metodi/funzioni) definiti private sono accessibili (= visibili) solo dall'interno della classe stessa (→ della singola istanza di quella classe)

• protected: variabili (e metodi/funzioni) definiti protected sono accessibili (=

visibili) dall'interno della classe stessa (→ della singola istanza di quella classe) e di tutte le sottoclassi (→ delle istanze delle sottoclassi)

[tra poco vedremo cos'è una sottoclasse…]

Gli access modifiers (in particolare private) ci permettono di implementare il principio dell'incapsulamento (information hiding)

PHP: definire una classe - II

(18)

Per definire una classe:

class Nomeclasse { private $nomevar;

public function __construct(paramcostr) { azioni;

}

public function nomemetodo(parametri) { azioni;

}

PHP: definire una classe - III

variabili (strutture dati)

costruttore (metodo pubblico per costruire nuove istanze della classe) NB si deve chiamare __construct

la keyword class indica che stiamo definendo una classe

(19)

Esempio:

class Conto { private $nome;

private $saldo;

public function __construct($n) {

$this->nome = $n;

$this->saldo = 0.0;

}

public function setNome($n) {

$this->nome = $n;

}

public function getNome() { return $this->nome;

}

public function setSaldo($s) {

$this->saldo = $s;

}

public function getSaldo() { return $this->saldo;

PHP: definire una classe - IV

VEDI Conto.php

in questo modo le variabili sono

accessibili (visibili) solo all'interno delle istanze della classe: per assegnare loro nuovi valori o leggere i valori correnti dall'esterno si utilizzano i metodi

set/get, che, in quanto pubblici, appartengono all'interfaccia (API)

il costruttore, quando invocato, crea una nuova istanza della classe Conto

la sua implementazione,

tipicamente, inizializza le variabili d'istanza

posso passare alcuni di questi valori come parametri

(20)

...

public function deposita($denaroIn) {

$this->saldo += $denaroIn;

return $this->saldo;

}

public function preleva($denaroOut) { if ($this->saldo >= $denaroOut) {

$this->saldo -= $denaroOut;

}

return $this->saldo;

} }

-> equivale alla dot notation!

[in PHP il . è usato per la concatenazione di stringhe... :-( ]

Per riferirsi ad una variabile d'istanza da dentro l'oggetto stesso:

PHP: definire una classe - V

VEDI Conto.php

(21)

Note

• Una funzione utile, che stampa lo stato completo dell'oggetto (cioè i valori di tutte le variabili):

var_dump($ogg);

Variabili e metodi (funzioni) possono anche essere static...

per accedere a una var statica: self :: $var

per accedere a un metodo statico: Classname :: method() [rif. php.net/manual/en/language.oop5.static.php]

• A differenza di Java, il file che contiene la definizione della classe non deve necessariamente avere lo stesso nome della classe (anche può essere molto utile...)

PHP: definire una classe - VI

scope resolution operator

(22)

Una classe, in se stessa, è inutile… il codice scritto finora in Conto.php non fa nulla!

Questo perché la classe è solo un modello di oggetti (istanze della classe appunto) che devono essere ancora creati (e usati)

Per usare una classe:

include("nomefile");

$ogg = new Nomeclasse(...);

PHP: usare una classe - I

"importiamo" la classe, includendo il file che ne contiene la definizione

costruiamo una nuova istanza di quella classe (un nuovo oggetto), invocando il costruttore

invochiamo i metodi pubblici (API) per

[1]

[2]

[3]

(23)

PHP: usare una classe - II

• in PHP, per includere un file:

<?php include("nomefile") ?>

nel punto in cui si vuole inserire il codice contenuto nel file esterno;

l'interprete farà sostanzialmente un "copia&incolla" del contenuto del file incluso all'interno della pagina PHP

• in generale, utile per inserire codice che verrà utilizzato in più pagine, per es. intestazioni e piè di pagina, o connessioni a database

i file inclusi possono contenere codice HTML, script client-side (es:

Javascript), script server-side (es: PHP) e hanno generalmente estensione .php o .html o .inc

al posto di include, si può usare require("nomefile") che dà errore se non trova nomefile

include_once("nomefile") o require_once("nomefile") che evita di

(24)

<?php

include("Conto.php");

$contoR = new Conto("Rossi");

$saldoR = $contoR->getSaldo();

$cliente = $contoR->getNome();

?>

<P>SALDO <?= $cliente; ?>: <?= $saldoR ?></P>

<?php

$saldoR = $contoR->deposita(100.0);

?>

<P>deposito > SALDO <?= $cliente; ?>: <?= $saldoR ?></P>

<?php

$saldoR = $contoR->preleva(40.0);

?>

<P> prelievo > SALDO <?= $cliente ?>: <?= $saldoR ?></P>

<P>Conto <?= $cliente ?>:

<?php

PHP: usare una classe - III

VEDI es-classe.php

[1] [2]

[3]

[3]

[3]

(25)

• Quando definiamo una classe, possiamo definirla come sottoclasse ("figlia") di una classe esistente ("genitore")

• Una sottoclasse (figlia), tipicamente, definisce tipologie di oggetti più

specifiche rispetto alla sua sovraclasse (genitore), specificandone proprietà e/o funzionalità aggiuntive (o diverse)

• Esempi:

• Una sottoclasse (figlia) eredita i metodi e le proprietà della sovraclasse (genitore) ̶ a meno che non siano sovrascritte dalla sottoclasse [prox slide]

PHP: definire una sottoclasse - I

Utente

Impiegato

Docente

Studente

AnimaleDomestico

Cane

PesceRosso Gatto

(26)

• In una sottoclasse (figlia) è possibile ridefinire (sovrascrivere ̶ override) i metodi della sovraclasse (genitore), x es:

$doc = new Docente();

$doc->assegnaPrivilegiAccesso();

$stu = new Studente();

$stu->assegnaPrivilegiAccesso();

PHP: definire una sottoclasse - II

Utente

Impiegato

Docente

Studente

metodo: assegnaPrivilegiAccesso() → accesso servizi didattici + intranet

ridefiniz. metodo: assegnaPrivilegiAccesso() → accesso servizi didattici

accesso ai soli servizi didattici (viene eseguito il metodo ridefinito nella classe figlia Studente)

accesso ai servizi didattici + alla intranet (viene eseguito il metodo ereditato dalla classe genitore Utente)

(27)

Note

"PHP 5 introduces abstract classes and methods" ("Classes defined as abstract may not be instantiated […] Methods defined as abstract simply declare the method's signature - they cannot define the implementation")

[www.php.net/manual/en/language.oop5.abstract.php]

"Object interfaces allow you to create code which specifies which methods a class must implement, without having to define how these methods are implemented.

Interfaces are defined in the same way as a class, but with the interface keyword replacing the class keyword and without any of the methods having their contents defined. All methods declared in an interface must be public"

[www.php.net/manual/en/language.oop5.interfaces.php]

Una classe può implementare un'interfaccia utilizzando la keyword implements e definendone i metodi

In PHP 7 sono state introdotte le

classi anonime ("anonymous classes are useful when simple, one-off

objects need to be created")

PHP: classi astratte, interfacce, classi anonmime…

$oneOffObj = new class {

public function __construct($msg){

$this->msg = $msg;

} }

(28)

Creiamo una sottoclasse della classe Conto:

class ContoYoung extends Conto{

// eredito le var nome e saldo! [*]

private $bonus;

public function __construct($n, $b){

$this->nome = $n;

$this->bonus = $b;

$this->saldo = 0.0;

}

public function setBonus($b) {

$this->bonus = $b;

}

public function getBonus() { return $this->bonus;

}

// eredito gli altri metodi set e get !!!

PHP: definire una sottoclasse - III

VEDI ContoYoung.php

questo costruttore sovrascrive quello ereditato!!

Sovrascriviamo il metodo

deposita = lo ridefiniamo (quando

viene effettuato un deposito, viene accreditato un bonus)

quando lo invochiamo su

un'istanza di ContoYoung, viene utilizzato questo

NB1 Se non lo ridefiniamo, viene

keyword per definire una sottoclasse

(29)

[*] Attenzione!

Per poter utilizzare (ereditare) le variabili definite nella

sovraclasse genitore Conto nella sottoclasse figlia ContoYoung, devo definirle protected (se le definisco private dalle istanze di ContoYoung non le vedo…):

class Conto {

protected $nome;

protected $saldo;

...

PHP: definire una sottoclasse - IV

VEDI Conto.php

(30)

Usiamo la sottoclasse ContoYoung:

<?php

include("Conto.php");

include("ContoYoung.php");

$contoB = new ContoYoung("Bianchi", 10);

$saldoB = $contoB->getSaldo();

$cliente = $contoB->getNome();

?>

<P>SALDO <?= $cliente; ?>: <?= $saldoB ?></P>

<BR />

bonus <?= $cliente; ?>: <?= $contoB->getBonus() ?>

<?php

$saldoB = $contoB->deposita(100.0);

?>

<P>deposito > SALDO <?= $cliente; ?>: <?= $saldoB ?></P>

<?php

PHP: usare una sottoclasse - I

VEDI es-sottoclasse.php

(31)

• "giocate" un po' con es-classe.php e Conto.php...

– x es. provate ad aggiungere un tetto per il possibile sformamento (conto in rosso) e, al momento del prelievo, se si sfora, ma entro il tetto, avvisate l'utente

• "giocate" un po' con es-sottoclasse.php e ContoYoung.php...

– x es. provate ad aggiungere qualche condizione per gestire diversi bonus

TRY YOURSELF!

(32)

CASE STUDY: quiz

(versione 1)

• costruiamo un pagina web che mostri all'utente una serie di domande

• nelle prossime lezioni impareremo:

– a leggere le domande da un database

– a creare un form per permettere all'utente di rispondere – a leggere le risposte dell'utente e ad assegnargli punti

• per ora:

– creiamo una classe Domanda (file DomandaI.php) che contiene il testo della domanda e i punti (ogni risposta esatta porterà dei punti all'utente...)

creiamo un array di oggetti di tipo Domanda e stampiamo sulla pagina i

PUT ALL TOGETHER & TRY YOURSELF!

Riferimenti

Documenti correlati

A differenza dei legami peptidici delle proteine che sono planari, i legami fosfodiesterici negli acidi nucleici possono assumere una grande varietà di conformazioni, definite

Il numero degli accessi ai PS per sindrome gastroenterica senza sangue nelle feci è in decremento e nessuna soglia di allerta è.

L’ingresso a tale registro è costituito dalle linee XDATA, poiché da esse proviene l’in- formazione che dovrà essere eventualmente catturata; inoltre, poiché l’aggiornamento

Nuova interfaccia (altre operazioni) Nuova interfaccia (altre operazioni) Presidio di Valutazione della.. Presidio di Valutazione della Ricerca Ricerca

L'obiettivo di questo corso è quello di gettare le basi per poi essere in grado di affrontare anche questi aspetti :-).. mypage.html) con dentro un semplice codice HTML e

Nella settimana di riferimento il 2,1% di tutte le persone che si sono rivolte ai PS è stato visitato per una sindrome ga- stroenterica senza sangue nelle feci. Il numero degli

Metodo Berlitz L’attenzione è concentrata su una buona pronuncia. Si punta molto sull’uso spontaneo della lingua, non sulla traduzione. L’attenzione è concentrata su una buona

CISQ – Politecnico di Bari - Corso di formazione per RSPP – Modulo 6: Esempio di un insieme PED (ing. Boenzi).. Bari, 3 febbraio