Aggiorna oggetto in PHP

0

Non riesco a trovare informazioni su questo ovunque, quindi presumo che non esista.

Per me è molto sensato che tale funzionalità esista e voglio chiedergli se effettivamente lo fa e ho torto nella mia ipotesi, o ci sono dei buoni motivi per cui non lo fa e perché non dovrei tentare di crearlo.

class User {
    public $name;
    public function __construct($name){
        $this->name = $name;
    }
}

class Admin extends User {
    private $permissions = 0777; // dumb example
}

$user = new User('Tom');

// we decide tom should be an admin
$user->upgrade('\Admin');

get_class($user); // returns "Admin"

Alla fine questo eliminerà anche il bisogno di fabbriche.

    
posta php_nub_qq 13.04.2015 - 10:25
fonte

1 risposta

4

Il tuo esempio è già imperfetto, in quanto Admin acquisisce nuove proprietà rispetto alla classe base che lo rende incompatibile. Sarebbe stato più intelligente posizionare subito la proprietà $permissions nella classe base.

Chiediti, in quali casi potrebbe essere opportuno introdurre nuove proprietà su un oggetto esistente?

Sia l'istanziazione di un oggetto come un'istanza di una classe specifica o l'utilizzo di una fabbrica con l'hint di tipo appropriato garantisce che l'oggetto generato abbia proprietà e interfacce specifiche e il comportamento di ogni singola interfaccia sia costante per tutta la durata del oggetto.

Promuovendo l'oggetto in una classe diversa durante il live time, stai violando questa promessa, rendendo difficile tracciare quale implementazione il tuo codice sta effettivamente utilizzando nel corso della sua vita.

Crea anche un altro problema, se scegli di estendere dinamicamente il tuo oggetto durante il runtime, non c'è modo di tornare indietro per scegliere un diverso affinamento. Ogni interfaccia che si aspetta che il tuo oggetto abbia, dovrebbe quindi essere già presente alla creazione.

Se, come nel tuo esempio, hai un caso in cui un caso speciale di una classe è più avanzato in un solo aspetto, considera di scaricare tale comportamento in una classe separata. Nel tuo caso:

class User {
    private $permission;
    private $name
    public function __construct($name, Permission $permission){
        $this->name = $name;
        $this->permission = $permission;
    }
    public function changePermissionModell(Permission $permission) {
        $this->permission = $permission;
    }
}
interface Permission {
    public function checkPermission($scope);
}
class ACLPermission implements Permission {
    public function checkPermission($scope) {
        return ACL::checkPermission($scope);
    }
}
class RootPermission implements Permission {
    public function checkPermission($scope) {
        return true;
    }
}
$defaultPermission = new ACLPermission();
$user = new User("Tom", $defaultPermission);
// Promote "Tom" to admin
$user->changePermissionModell(new RootPermission());
    
risposta data 13.04.2015 - 11:19
fonte

Leggi altre domande sui tag