Catena oggetto attraverso un'interfaccia

1

Supponiamo che io abbia 3+ tipi di oggetti:

function Sea() {
    var logs = [Logs];
    this.getLog = function(ind){return logs[ind]}
}

function Log() {
    var bumps = [Bumps];
    this.getBump = function(ind){return bumps[ind]}
}

function Bump() {
    var frogs = [Frogs];
    this.getFrog = function(ind){return frogs[ind]}
}

function Frog() {
    this.ribbit = function(){alert("Onomatopoeia!")}
}

Quindi, Frog non sa circa Bump , e Bump non sa circa Log , ma Log può accedere a Bump e Frog direttamente e indirettamente, rispettivamente.

Ora, diciamo che ogni volta che un Frog pronuncia un ribbit , Log si muove leggermente (sebbene Frog internamente non si preoccupi di cosa succede al di fuori di se stesso).

Ora signora Demeter suggerisce che non lo faccio:

Sea.getLog(5).getBump(2).getFrog(1).ribbit()

Si legge bene, ma ci sono alcuni problemi. Oltre al problema dell'accoppiamento stretto, questo metodo rende anche impossibile per ribbit spostare Log a meno che Frog non ottenga un riferimento su Log , il che significa che l'accoppiamento diventa ancora più stretto.

Tuttavia il metodo alternativo a "un punto" sembra un po 'atroce:

Sea.tellFrogOnBumpOnLogToRibbit(1, 2, 5)

Una soluzione ragionevole che è stata suggerita qui (penso) è quella di creare un'interfaccia concisa ma strettamente accoppiata per ... interfaccia, con il codice più business-logico:

function SeaInterface() {

    var sea = createSea(); //Genesis 1:10

    var logInterfaces = [LogInterfaces];
    this.getLog = function(ind) {return logInterfaces[ind]}

}

function LogInterface() {

    var log = createLog();

    var bumpInterfaces = [BumpInterfaces];
    this.getBump = function(ind) {return bumpInterfaces[ind]}

    //Private method that Frogs will know about internally:
    var move = function(){} 
}

function BumpInterface() {

    var bump = createBump();

    var frogInterfaces = [FrogInterfaces];
    this.getFrog = function(ind) {return frogInterfaces[ind]}

}

function FrogInterface(log) {

    var frog = createFrog();

    this.ribbit = function() {
        frog.ribbit();
        log.move(); //I'm allowed to do this because I'm a simple interface
    }

}

In questo modo, potrei ancora usare il concatenamento e fare in modo che il codice legga bene (nota: concatenare non è una necessità):

Sea.getLog(5).getBump(2).getFrog(1).ribbit()

E Log si muoverà ancora dopo un ribbit .

Alla fine, è davvero solo un tentativo di minimizzare gli effetti dannosi che possono causare gli oggetti a conoscenza di altri oggetti.

Domande:

  1. Esiste un modo ugualmente leggibile o più leggibile e infallibile per ottenere la stessa cosa (più oggetti all'interno di oggetti dove occasionalmente la manipolazione di un oggetto interno influisce su un oggetto esterno)?

  2. Oltre a richiedere più codice e il fatto che l'interfaccia stessa sia strettamente accoppiata (accettabile?), quali altri problemi potrebbero sorgere se dovessi interfacciarmi con l'oggetto reale con qualcosa del genere? Inoltre ... questo metodo ha un nome?

Non ho davvero visto molti approcci come questo in natura, che è ciò che mi rende nervoso.

    
posta Jeffrey Sweeney 24.07.2014 - 04:41
fonte

1 risposta

1

Sospetto che la tua domanda sia accademica o formale, quindi potresti non essere soddisfatto della mia soluzione che è pratica.

Quando ci pensi, quello che hai è un LogConcernedWithFrogRibbits alla fine. Il modo migliore che ho trovato per disaccoppiare rapidamente le cose è attraverso un MVC (come ad esempio PureMVC) che è la "soluzione complessa" o semplicemente andare con un semplice sistema pub / sub come Radio.js.

Quindi gli Urti avrebbero ascoltato i messaggi di rana e i registri avrebbero ascoltato i messaggi di rilievo. Ogni messaggio contiene il suo mittente, quindi il ricevitore può determinare se il mittente è un oggetto nella sua raccolta, altrimenti non lo ignora.

Tutti i tipi di oggetti che hai elencato, le loro istanze dovrebbero probabilmente provenire da una fabbrica, quindi puoi fare riferimento alla fabbrica se lo desideri, e tutte le istanze dovrebbero anche ascoltare i messaggi (verso il basso) che saranno ribbit delle rane dal percorso .

Qualcosa come: "SeaMessage", {Sea: 0, Log: 10, Bump: 2, Rana: 9000, Azione: 'Ribbit'}

Quale sarebbe suddiviso in base al Mare corretto e in cascata lungo il suo percorso come "LogMessage".

Voglio dire, devo tirare su Einstein's Razor su questo, perché batterti sulla testa? No, non è il meccanismo più efficiente, ma questo è Javascript - che diamine stai costruendo? haha

È comprensibile, elegante e facilmente estensibile. Mantieni buoni documenti su ciò che stai facendo sul fronte dei messaggi e osserva la ricorsione.

    
risposta data 28.07.2014 - 05:55
fonte

Leggi altre domande sui tag