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:
-
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)?
-
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.