• User

    Incomprensione visibilità delle classi

    Salve,
    ho seri dubbi riguardo la visibilità delle proprietà di una classe. Ciò che non capisco è:
    se programmo da zero una classe User ( per fare un esempio ) contenente la proprietà $password, perché questo dovrebbe essere dichiarato private se io e soltanto io ho accesso a quella classe? Inoltre, sempre seguendo questo ragionamento, che senso ha fare una funzione get e set complicandosi ancor di più la vita, se posso dichiarare semplicemente la proprietà come public?

    Grazie a chiunque saprà risolvermi questo dubbio!


  • ModSenior

    Ciao,
    non è questione di chi ha accesso ad una classe bensì l'utilità di un attributo per l'esterno.
    Un esempio più pratico è nel caso in cui ho un attributo che viene usato dalla classe per effettuare un'operazione, se quest'attributo non deve poter essere modificato dall'esterno in quel caso è privata.
    Get e set ti permettono di implementare successivamente, estendendo ad esempio la classe, delle condizioni particolari ad esempio.
    Cioè ad esempio una cosa di questo tipo:
    [php]
    function set($name, $value)
    {
    if($name == 'debug' && $value === TRUE)
    $this->attivaDebug();

    $this->data[$name] = $value;
    }
    [/php]

    O ti permette di fare una validazione, cioè se vuoi che l'attributo debug abbia ad esempio 2 soli valori possibili(TRUE e FALSE), puoi restituire un errore senza eseguire quell'operazione.


  • User

    Ciao, innanzitutto grazie per la risposta.

    Un esempio più pratico è nel caso in cui ho un attributo che viene usato dalla classe per effettuare un'operazione, se quest'attributo non deve poter essere modificato dall'esterno in quel caso è privata.
    Il punto è, chi o cosa dovrebbe poter modificare quell'attributo?
    Una volta che faccio ad esempio:

    [PHP]
    class User {
    private $password;
    public $username;

    public function __construct( $in_username, $in_password )
    {
    /// Costruttore
    {
    }
    $usr = new User( 'username', 'password' );
    [/PHP]

    Se io per risettare la password facessi:
    [PHP]$usr->changePassword( 'newpassword' );[/PHP]

    Oppure: ( Questo nel caso fosse public la proprietà password )
    [PHP]$usr->password = 'newpassword';[/PHP]

    Non sarebbe praticamente la stessa identica cosa?


  • ModSenior

    No perchè nel primo caso tu puoi fare in modo tale che chiamando quel metodo oltre a modificare valore dell'attributo, fai ad esempio una query che aggiorna il database.
    Nel secondo caso è un cambio di valore dell'attributo senza alcuna validazione o conseguenza diretta.


  • User

    Giusto, ottima osservazione. A questo non c'avevo pensato!
    Però, non potrei utilizzare il secondo metodo sempre con una variabile public?


  • ModSenior

    Cioè?


  • User

    [PHP]$usr->changePassword( 'newpassword' );[/PHP]

    Dove la proprietà $password è dichiarata come public. Cioè, voglio dire, non è necessario che la variabile sia private per creare un metodo simile, no? Ho letto molto in giro per internet che "non si devono far vedere i dati al di fuori della classe", ma che senso ha se l'oggetto lo uso soltanto io?


  • ModSenior

    Allora una classe serve per astrarre una determinata cosa, tu nel momento in cui crei una classe devi mettere dei metodi pubblici che vengono utilizzati dall'esterno e basta.
    Se tu hai una classe che ti gestire l'autenticazione ad esempio, e vuoi fare in modo che uno sviluppatore di ad esempio un modulo aggiuntivo possa modificare la password del database, quella memorizzata in sessione ed altre cose legate alla password, devi creare un metodo che si occupi di fare tutto ciò. Quello sviluppatore non deve avere il minimo bisogno di sapere cosa utilizza internamente la classe, ed ovviamente non puoi dire setta l'attributo col nuovo valore, e poi fatti tu un update del database, della sessione, ecc.

    Poi sei libero di fare diversamente sopratutto se ci lavori solo tu su quel progetto, ma rimane una cosa concettualmente errata.


  • User

    Scusa, non volevo far valere a tutti i costi la mia opinione, ho dato un'impressione sbagliata. E' che proprio non c'arrivo!
    A livello puramente teorico riesco a capire ciò che mi dici, ma quindi la conclusione è che quasi tutte le variabili devono essere private o protected, e lavorarle con i metodi public?


  • ModSenior

    Non preoccuparti, ho capito che non era per far valere a tutti i costi la tua idea. 🙂

    Il problema è che esiste la teoria e la pratica. La teoria è uguale per tutti i linguaggi di programmazione, e quindi unisce ambiti molto diversi tra loro, in PHP si fanno delle cose molto differenti da quelle che si fanno in java, c++ o c#. Per cui la pratica cambia da linguaggio a linguaggio.

    A livello teorico
    Una classe deve risolvere un determinato compito e deve poter essere spostata su un altro progetto per poter essere riutilizzata facilmente. Per cui ha se nel tuo caso l'utilizzo che ne fai è solo quello, una classe va pensata come potrebbe essere utilizzata sia nel tuo progetto che altrove. In questa ottica tu devi avere dei metodi che devono essere facilmente utilizzabili dallo sviluppatore, senza dover eseguire 100 operazioni per fare un banale cambio password. Chiami un metodo e fa tutto lui.

    A livello pratico in PHP
    Fare quello che si dovrebbe fare a livello teorico è indubbiamente più pesante da eseguire, se fai dei semplici benchmark in locale tra:

    • Chiamare un attributo public dell'istanza di una classe
    • Chiamare un metodo get dell'istanza di una classe

    Noterai che la prima opzione è molto più veloce da eseguire, ma ovviamente ha tutti i limiti del caso e i relativi problemi teorici(I vari esempi che ho fatto prima, come la validazione del valore degli attributi, ecc).

    In php tutto si complica ulteriormente, perchè fare tutto in maniera ideale significa avere delle performance orribili. Perchè ovviamente ad uno stesso script avrai un numero elevatissimo di richieste nello stesso secondo, e le performance (Tranne in alcuni ambiti) sono abbastanza importanti perchè influiscono sui costi del server.
    Se chiedi a più persone, non avrai la stessa risposta, perchè ognuno segue la sua idea, in base alle proprie esperienze, l'ambito in cui programma ed anche il budget a disposizione per far funzionare tutto.

    Io in php, avendo dei browser game ed un numero molto elevato di pagine viste al giorno, seguo la strada di fare tutto con la programmazione ad oggetti nell'uso più semplice possibile.
    Per spiegare meglio:
    Se devo prendere dal database 30 utenti, non ci penso nemmeno a creare 30 istanze della classe utente con i relativi dati(Cosa che a livello teorico sarebbe più corretta) per poi utilizzarli.
    In PHP l'utilità di questo genere di cose, tranne determinati casi, è abbastanza bassa mentre l'impatto sulle performance è elevato.

    Ma ci sono ambiti in cui le performance possono essere trascurate in quanto non sono la cosa principale a cui stare attenti, ma si deve garantire altro. In altri linguaggi, che uso anche io per creare giochi, invece si ricalca al massimo la linea teorica perchè l'organizzazione è molto differente da un sito/applicazione web.

    Quindi in conclusione la linea teorica è quella, ma non si rispetta quasi mai fino in fondo, almeno per quanto riguarda i casi più comuni.
    Poi ci sarà sempre chi invece sostiene la linea teorica all'estremo, ma io non faccio parte di quella categoria (perchè alcune cose, per me, hanno un impatto più negativo che positivo). :fumato:


  • User

    Grazie, quest'ultima spiegazione è stata molto esaustiva! 😄


  • ModSenior

    Figurati, se hai altri dubbi chiedi pure! 🙂