Rientro di nuovo nella classe genitore

3

Ho un'app con la seguente struttura (semplificata un po 'qui) ...

var RecorderApp = function(canvas) {
  this.state = undefined;
  this.states = { record: recordState, save: saveState };
  this.init = function() {
    this.audEng = new AudioEngine();
    this.waveDisp = new WaveformDisplay(canvas);
    this.mouse = new MouseStatus(canvas);
    this.states.record.init(this);
    this.states.save.init(this);
    this.state = this.states.record;
    this.state.enter();
    this.state.execute();
  };

Ho bisogno che le istanze audEng, waveDisp e mouse parlino tra loro - waveDisp deve estrarre i dati delle forme d'onda da audEng, fare clic sugli eventi ricevuti da waveDisp per attivare le modifiche di stato nella classe genitore e così via.

Il mio primo pensiero è stato passare "questo" come parametro nel costruttore di ogni istanza e memorizzare il riferimento come this.parent, quindi "raggiungere il backup" come necessario e chiamare direttamente i metodi di query ei metodi di modifica dello stato che volevo . In questo caso, penso di poter giustificare il raggiungimento diretto nella classe genitore per chiamare un metodo di modifica dello stato, ad esempio this.parent.save (), ma ... risalendo fino al parent e poi nuovamente in un'altra classe, ad es. this.parent.audEng.getWaveform () mi fa sentire a disagio, ho ragione nel pensare che questo viola la legge di Demeter? Se questa è una via imprudente / puzzolente da percorrere, la soluzione giusta è assicurarsi che tutte le comunicazioni inter-class di cui ho bisogno vengano eseguite tramite metodi definiti nella classe master RecorderApp? O è l'architettura che sto suggerendo fondamentalmente stupida.

Modifica perché contrassegnato come duplicato: l'altra risposta che ho visto qui è abbastanza centrata sul C ++, l'opinione sembra divisa, non fornisce esempi espliciti e la migliore risposta non ha risposto alla mia domanda in un modo che mi era completamente chiaro, in in particolare "altre lingue usano un oggetto" è una soluzione un po 'più vaga di quanto speravo.

    
posta technicalbloke 26.09.2016 - 23:24
fonte

2 risposte

1

IMO: passare per riferimento è qualcosa a cui rabbrividisco perché è troppo complicato per i miei gusti.

Suggerisco caldamente che la commutazione degli oggetti incrociati sia gestita a livello genitore / figlio. I fratelli non dovrebbero mai parlare direttamente.

Inoltre, considera cosa succederebbe se fosse necessario modificare il riferimento o la struttura ereditaria in un secondo momento? Dovrai tornare indietro e modificare tutti i riferimenti basati su alberi e, a quel punto, probabilmente dovrai reimparare le tue dipendenze come definite per riferimento.

I metodi espliciti non semplificano la lettura del codice base. Lo rendono più facile da usare.

    
risposta data 27.09.2016 - 00:20
fonte
3

La creazione di una nuova dipendenza all'interno di una stessa classe aumenta l'accoppiamento e rende il codice più difficile da mantenere. Considera di spostare canvas dal costruttore e di passare le tue dipendenze (supponendo che tu stia pianificandole di usarle) come già istanziato con canvas .

Pensa ai tuoi oggetti in termini di composizione, in contrapposizione all'ereditarietà. La composizione ti consente di isolare parti del codice.

Nel tuo esempio, stai passando in canvas, che viene usato a sua volta da WaveformDisplay . Se in futuro devi aggiungere qualcosa a WaveformDisplay , dovrai passarlo a RecorderApp e poi a WaveformDisplay . Puoi evitarlo passando un'istanza WaveformDisplay che è già inizializzata nel modo desiderato.

La mia ipotesi è che non ti interessi davvero se è parent.audEng.getWaveForm() o parent.getWaveForm - la cosa importante è ottenere i dati della forma d'onda. In questo caso è possibile creare un metodo all'interno di RecorderApp che realizzi la stessa cosa riducendo l'accoppiamento:

var RecorderApp = function(audEng) { this.getWaveform = function() { audEng.getWaveform(); }; };

Dai anche un'occhiata ai moduli in JavaScript, tramite il Pattern del modulo in JS vanilla o in alcuni dei framework più recenti dotati di funzionalità integrate per la gestione delle dipendenze.

    
risposta data 27.09.2016 - 01:18
fonte

Leggi altre domande sui tag