Paradigmi di registrazione, DI / IoC, gerarchie di oggetti

4

Sto cercando di capire come supportare il seguente scenario di esempio

sta usando C # come lingua di esempio.

Scenario

La NASA sta inviando Rovers e Satelliti a diversi Pianeti

questi veicoli richiedono molta registrazione e, per ridurre la confusione, vorrebbe poter filtrare questi registri nei seguenti modi:

dovrei essere in grado di combinare / scegliere uno di questi:

  • Registra solo Rovers in Mercury
  • Registra tutto su Marte
  • registra tutti i satelliti

Attuazione

Grafico oggetto

quindiabbiamo3tipidioggetto,Planet,RovereSatellite

Laterracontiene3satelliti

Martecontiene1satellitee2Rover.

Mercurycontiene2satellitie1Rover.

ilsolitomododiaggiungereunregistroaglioggettiècometale:

publicclassMars:Planet{privatestaticILogLog=LogManager.GetCurrentClassLogger();}

questodisolitorestituisceunloggerchiamato"NASA.Mars" che rende semplice configurare semplicemente il framework per registrare tutte le "NASA.Mars" lo stesso accadrebbe con una Rover

public class Rover {
 private static ILog Log = LogManager.GetCurrentClassLogger();
}

Avrei un logger chiamato "NASA.Rover"

ma come potrei sapere che il rover è in mercurio? poiché questo è un requisito del sottosistema di registrazione, non dovrebbe esistere come proprietà nella classe Rover .

Idea

Iniezione di dipendenza

se progetto le mie classi per accettare un'istanza di ILog nel costruttore potrei in teoria controllare un nome di registro degli oggetti figlio

(possibile utilizzare la classe genitore Pianeta , omessa per brevità)

public class Mars : Planet {
  private static ILog Log = LogManager.GetCurrentClassLogger();

  void Mars() {
    this.Rovers.Add(new Rover(LogManager.GetLogger(Log.Name + ".Rover"));
  } 
}

public class Rover {
 private ILog Log;

 void Rover(ILog log) {
   Log = log;
 }
}

I miei problemi con questo approccio:

  • la creazione di un logger per ogni oggetto figlio sembra una specie di "off", forse persino un anti-pattern
  • questo può diventare molto complicato quando si ha a che fare con livelli più profondi di gerarchia (pensa a pianeta - > area - > station - > rover)
  • decifrare la gerarchia degli oggetti dalla stringa del nome del logger (NASA.Mars.Rover) è problematico (i caratteri jolly a volte non sono sufficienti, alcuni nomi potrebbero non essere abbastanza unici).

Sto cercando una buona idea per risolvere questo, senza codice ingombrante, qualcosa di generico

    
posta Aviel 15.09.2016 - 23:47
fonte

3 risposte

2

Con la quantità limitata di informazioni, suppongo che i pianeti non richiedano la registrazione, sono solo le letture di Rovers e Satelliti che fanno (sono i dispositivi di monitoraggio). In tal caso, ogni Rover e Satellite dovrebbe avere la propria istanza di un logger, ma probabilmente accedere allo stesso file di registro.

Sfogliando il tuo design su Planets che possiedono Rovers e Satelliti, Satelliti e Rover che seguono il loro punto di origine, potresti semplificare questo problema.

public class Satellite
{
    private ILog Log;
    void Satellite(Planet origin)
    {
        //include logic here on when not to instantiate logger e.g. origin.Name != "Mercury"
        Log = LogManager.GetLogger("Satellite");
    }
}

Se vuoi tenere traccia del numero di satelliti e rover su ogni pianeta, puoi farlo con le query di Linq se tenga traccia della collezione di quelli registrati e li filtra in base al pianeta da cui provengono.

    
risposta data 21.09.2016 - 11:31
fonte
0

Se è necessario un comportamento di registrazione nei propri oggetti allora sì, un logger è una dipendenza da iniettare. Mentre molti esempi di logger che trovi utilizzano un approccio localizzatore di servizi che non significa che sia il migliore.

Non mi piace il nome ".Rover" non essendo legato al nome della classe. Mi piace essere in grado di ridefinire i nomi delle classi senza dover inseguire le stringhe. Ho usato con successo i trucchi per riflettere e impilare lo stack per mantenere il nome fuori dalle stringhe codificate. Ricorda che quei trucchi non sono economici. Quindi fallo al momento giusto.

Se il tuo comportamento di logging ha solo bisogno di conoscere i nomi delle classi, i metodi chiamati e i parametri passati, guarda in Aspect Oriented Programming. Ho sviluppato interi sistemi di auditing incentrati su alcune convenzioni sui nomi che ci hanno permesso di rimuovere tutto il codice di controllo dagli oggetti sottoposti a verifica.

Il cuore del tuo problema è che hai bisogno di un modo per sapere se un rover deve essere registrato. Se i rover non hanno alcuna conoscenza memorizzata di dove sono, potrebbero conservare queste informazioni sotto forma di impostazioni di registrazione, ovvero tutti i rover Mars potrebbero essere impostati per accedere a dev / null.

La soluzione più restrittiva per i dati e la cpu è la ricerca. Quando un rover segnala che ha bisogno di essere loggato, dovrai cercare il rover nei mondi che potrebbero contenerlo. Se questo è costoso, questo può essere facilmente proibitivo.

AOP può fare tutto ciò. Devi solo costruire quello che ti serve in una classe diversa da Rover. Ricorda che i Rovers devono arrivare su Marte in qualche modo. Che in qualche modo può essere rilevato da AOP. Quindi devi decidere come ricordarlo.

    
risposta data 16.09.2016 - 01:36
fonte
0

La tua specifica si riferisce alla registrazione, quindi puoi creare un servizio di registrazione che implementa queste regole e inseriscilo negli oggetti invece che in log4net.

Dovrebbe avere metodi con un primo argomento che rappresenta l'oggetto che deve registrare qualcosa. Un metodo specifico per ogni oggetto con regole specifiche, più probabilmente un generico solo per ottenere il tipo di oggetto per altri oggetti.

Puoi quindi chiedere a log4net un logger basato sul tipo di oggetto.

Tutti gli oggetti chiamerebbero logging.Log(this, ...) per evitare di sapere se esiste una regola di registrazione specifica.

    
risposta data 18.09.2016 - 18:10
fonte

Leggi altre domande sui tag