2009-03-24 6 views
1

Supposons que nous ayons une classe qui sera largement utilisée dans tout le code (C#), par exemple une classe Log. Dites que le journal écrit des entrées dans des fichiers XML dans un répertoire spécifique. Maintenant, une tentative pour forcer l'utilisateur à initialiser la classe avec les informations requises serait de rendre privé le constructeur par défaut (sans paramètre) et d'en fournir un qui prend un paramètre logdirectory. L'inconvénient est que, chaque fois que quelque chose doit être écrit dans le journal et qu'une instance de la classe Log est créée, le paramètre doit être fourni.Question de conception: Comment gérer l'initialisation?

Quelles sont les autres options disponibles? Merci d'avance pour vos réponses.

Répondre

4

Quatre options (la plupart du temps couvert, mais pas explicitement et ensemble):

  • Il suffit de faire les appels statiques, et comprennent l'initialisation statique. C'est horrible pour les tests (des classes qui en dépendent) mais très simple.

  • Utilisez un singleton comme suggéré par la plupart des autres réponses. C'est potentiellement mieux du point de vue du test (vous pouvez avoir des méthodes internes pour remplacer le singleton à des fins de test uniquement) et implémenter une interface à des fins de simulation. Utilisez l'injection de dépendances: faites en sorte que tout ce qui a besoin de la dépendance la prenne dans un constructeur ou autre, et obtenez votre infrastructure DI pour tout raccorder. Beaucoup mieux du point de vue des essais, mais ce n'est pas vraiment pratique. Utilisez une fabrique - comme le singleton, mais en séparant l'implémentation de la construction. (Il peut efficacement fin comme un singleton, mais sans autant d'hypothèses de cela.)

+0

+1 d'accord sur la plupart de celui-ci. @Jon je ne dirais pas DI n'est pas pratique. Avec un bon cadre DI, il n'y a pas grand-chose à faire, et vous obtenez beaucoup de flexibilité. Que voulez-vous dire par là? – eglasius

+0

Je veux dire qu'avoir un champ "logger" dans chaque classe qui pourrait se connecter, et nécessitant un constructeur prenant un logger partout, peut agir comme un "fluff" supplémentaire quand en production vous utiliserez seulement un singleton. C'est agréable et flexible, certes, mais il y a un certain coût pour cette flexibilité. –

+0

Je vois, je suis d'accord. Vous pouvez également utiliser l'injection de propriété controversée pour l'enregistreur :) – eglasius

1

Je pense que le terme que vous voulez rechercher est le modèle Singleton. Je ne vais pas l'écrire complètement ici - c'est un terme très google-able. Mais fondamentalement vous initialisez une seule instance de l'objet une fois que l'application charge, et ensuite dans toute l'application vous référencez cette même instance

0

Vous êtes si proche ... implémentez ceci comme un singleton, et vous n'aurez pas besoin initialiser plus d'une fois. La réponse courte est de créer une instance publique statique de votre classe en elle-même et une méthode statique publique qui (a) initialise cette instance si elle est actuellement nulle, ou (b) renvoie l'instance déjà initialisée.

Il y a plus de détails à considérer avec le motif singleton, mais cela devrait vous aider à démarrer.

0

Il suffit de faire de la fonction Logger.Log() un appel statique et de faire référence à un membre statique qui est l'information d'annuaire. Ensuite, il vous suffit de définir le membre d'infomration d'annuaire une fois, au début de l'exécution, et tous les appels suivants à Logger.Log() fonctionneront simplement.

0

Singleton. Vous pouvez utiliser une classe statique afin qu'elle n'ait pas besoin d'être instanciée. Ensuite, si vous avez un répertoire de journal, avez un chemin de journal par défaut et un paramètre nullable à la méthode writelog ou une signature de méthode surchargée, on accepte le chemin, on suppose par défaut le fichier de configuration.

Questions connexes