Sembra che Cursor
rappresenti una posizione in Document
. La classe Document
dovrebbe essere in definitiva responsabile di tutte le operazioni primitive come l'inserimento, l'eliminazione, l'acquisizione di testo e lo spostamento. Molte di queste operazioni richiedono una posizione come input e alcune restituiscono anche una posizione come output. Cursor
potrebbe essere solo una classe dati concreta che contiene solo la posizione e il Document
, in pratica una coppia. L'altro approccio è di rendere Cursor
un'astrazione di prima classe. In questo caso la sua API rispecchierà solo quella di Document
, e ogni metodo sarà solo un involucro sottile attorno al metodo corrispondente su Document
, ma i metodi su Cursor
ometteranno il parametro posizione poiché verranno riempiti con la posizione da Cursor
.
Lo schema di base è qualcosa come
cursor.someMethod(arg1, ...) = cursor.doc.someMethod(cursor.pos, arg1, ...)
tranne se il metodo Document
restituisce una posizione, allora il metodo Cursor
dovrebbe comprimerlo insieme al documento e restituire un cursore come
cursor.otherMethod(arg1, ...) = new Cursor(cursor.doc,
cursor.doc.otherMethod(cursor.pos, arg1, ...))
Lo svantaggio di questo approccio è la piastra della caldaia sul lato dell'implementazione, ma rende la libreria molto più bella da usare sul lato client. Dal momento che il boilerplate richiesto è semplice e sistematico, potresti essere in grado di evitare di scriverlo manualmente generandolo o eseguendo la delega tramite chiamate riflessive se stai usando un linguaggio con capacità di riflessione decente o un preprocessore ragionevolmente potente.
Devi ancora decidere quale posizione è. Può essere solo un numero che rappresenta la posizione del carattere nell'intero documento (ad es. Emacs), una coppia che rappresenta la linea e la posizione sulla linea, o un puntatore in C / C ++ direttamente nel contenitore sottostante. Ti suggerirei di posizionare un membro su Document
se la tua lingua lo supporta. In questo modo ogni implementazione di Document
può fornire la propria definizione del tipo di posizione. Cursor
tratta le posizioni come completamente astratte, le tiene semplicemente e le passa a Document
metodi. solo Document
si preoccupa di come sono implementati.