Metodi di istanza che modificano più oggetti

2

Attualmente sto riscrivendo una vecchia libreria per la gestione dei documenti.

Ho difficoltà a specificare un'interfaccia per la gestione dei collegamenti tra tali documenti. In precedenza sono stati specificati semplicemente come chiavi primarie degli altri documenti. Ma per avere un'interfaccia più orientata agli oggetti, le chiavi primarie dovrebbero essere sostituite con oggetti dei documenti effettivi.

Ora l'implementazione dei metodi AddLink / RemoveLink è un problema perché se aggiungi un link dal documento A al documento B viene aggiunto automaticamente un altro link da B a A.

Una descrizione più generale del problema potrebbe essere la seguente: Come è possibile modificare le proprietà che dipendono l'una dall'altra ma che si trovano in oggetti diversi (probabilmente dietro le interfacce).

Cose che ho provato finora:

  • Utilizzo dei metodi interni per cambiare i collegamenti "dietro la parte posteriore" dell'oggetto

    Funziona solo per le classi normali ma quando le interfacce sono coinvolte (il mio caso) non funzionerà.

  • Utilizzando un qualche tipo di meccanismo di rilevamento della ricorsione, per fermarsi semplicemente a quel punto

    Funziona, ma secondo me è un trucco

  • Uso dei gestori di eventi (non funziona per l'aggiunta, solo per la rimozione)

  • Abbandonare l'idea di avere accesso diretto agli oggetti e continuare a utilizzare le chiavi primarie

Codice di esempio:

class Document
{
    private List<Document> links;

    public IReadOnlyList<Document> Links { get { return links.AsReadOnly(); } }

    public void AddLink(Document other)
    {
        links.Add(other);
        // How to add this to other.Links?
        // Just calling other.AddLink(this) would cause infinite recursion
    }
}
    
posta Alexander Hausmann 02.10.2015 - 13:45
fonte

1 risposta

0

OK, non vedo il vantaggio di avere l'oggetto piuttosto che l'id, ma ..

un modo per farlo è iniettare un repository Document / Link. così quando aggiungi il link, viene aggiunto (come collegamento a due vie) al repository. Entrambi i documenti generano i loro collegamenti quando vengono interrogati controllando il repository (condiviso).

es.

    /// <summary>
    /// inject into documents, this access a shared database or its a shared instance etc
    /// </summary>
    public interface IRepository
    { 
        Document GetDocument(string id);

        /// <summary>
        /// get all the links which are linked to or from the Id
        /// </summary>
        /// <param name="documentId"></param>
        List<Document> GetLinks(string documentId);

        /// <summary>
        /// add link refernce both docs
        /// </summary>
        /// <param name="linkFromId"></param>
        /// <param name="linkToId"></param>
        void AddLink(string linkFromId, string linkToId);
    }

    public class Document
    {
        public string Id {get;set;}

        private IRepository repo;

        public Document(IRepository repo)
        {
            this.repo = repo;
        }

        public IReadOnlyList<Document> Links 
        { 
            get 
            { 
                return repo.GetLinks(this.Id).AsReadOnly();
            } 
        }

        public void AddLink(Document other)
        {
            repo.AddLink(this.Id,other.Id);
        }
    }
    
risposta data 02.10.2015 - 13:55
fonte

Leggi altre domande sui tag