Accedi all'oggetto contenitore dall'interno di un oggetto

1

Generalmente ho 3 classi, un contenitore che contiene una matrice di elementi e un oggetto speciale che è un'altra proprietà della classe contenitore. Quello che devo fare è accedere all'oggetto speciale da un oggetto oggetto all'interno del contenitore. Vedo 2 modi per raggiungere questo obiettivo.

class Container {

    protected $object;
    protected $items = [];

    public function __construct() {
        $this->object = new SpecialObject;
    }

    public function setItem($index, Item $item) {
        $this->items[$index] = $item;
    }

    public function getItem($index) {
        return $this->items[$index];
    }

}

class Item {

    protected $container;

    public function __construct(Container $container) {
        $this->container = $container;
    }

    public function action() {
        $this->container->object;
    }
}

o

class Container {

    protected $object;
    protected $items = [];

    public function __construct() {
        $this->object = new SpecialObject;

        Registry::set('SpecialObject', $this->object);
    }

    public function setItem($index, Item $item) {
        $this->items[$index] = $item;
    }

    public function getItem($index) {
        return $this->items[$index];
    }

}

class Item {

    public function action() {
        Registry::get('SpecialObject');
    }
}

Con il primo esempio il problema che mi preoccupa è che ci sarà un riferimento all'interno di ogni oggetto Item che punta al contenitore, che non è solo ridondante ma se un oggetto cambia contenitore (per qualche motivo, non inteso) avrà un riferimento errato del contenitore e potrebbe causare problemi. Il secondo implica tuttavia che ci sarà solo un'istanza di Container, che potrebbe non essere e probabilmente non sarà il caso. Penso che non ci sia un modo infallibile per afferrare il contenitore di un oggetto, ma cosa suggeriresti è il modo "migliore" per raggiungere questo risultato in termini di prestazioni ed evitare bug?

    
posta php_nub_qq 23.09.2015 - 15:43
fonte

1 risposta

2

Alcune soluzioni mi vengono in mente:

Invece di chiamare action sull'articolo, chiamalo sul contenitore. Qualcosa del genere:

class Container {
    ...

    public function actionOnItem($index) {
        // do stuff with the item and the special object
        $this->object;
        $this->items[$index];
    }
}

Invece di codificare con decisione la dipendenza dall'elemento, è possibile iniettarlo quando l'elemento ne ha bisogno. Qualcosa Lungo queste linee:

class Item {
    ...
    public function action(SpecialObject $object) {
        // do stuff with the item and the special object
        $object;
        $this;
    }
}

E potresti usarlo in questo modo:

$item->action($container->object);

Un'altra opzione sarebbe quella di creare un oggetto dedicato per quell'azione e iniettare sia l'oggetto che l'oggetto speciale quando vuoi che faccia ciò che è. Qualcosa in questo ordine.

class ItemAction {

    private $object;

    public function __construct(SpecialObject $object) {
        $this->object = $object;
    }

    public function action(Item $item) {
        // do stuff with the item and the special object
        $this->object;
        $item;
    }
}

O forse qualcosa di simile

class ItemAction {

    public static function action(Item $item, SpecialObject $object) {
        // do stuff with the item and the special object
        $object;
        $item;
    }
}

Quale sarebbe l'opzione migliore nel tuo caso è difficile da dire e dipende in gran parte dall'ambito e dalle dimensioni della tua applicazione, e anche dal framework che stai usando (non). Forse potresti provare a dare un esempio reale di ciò che stai cercando di ottenere? ...

Ad ogni modo, se dovessi arrivare fino a me, la Dependency Injection sarebbe la strada da percorrere! E ha il vantaggio di rendere il tuo codice più facile da testare. Anche quel SpecialObject verrebbe iniettato nel Container se fosse dove mi trovo, invece di aggiornarlo hardcoded all'interno del tuo costruttore Container.

    
risposta data 23.09.2015 - 21:59
fonte

Leggi altre domande sui tag