2010-03-23 5 views
5

Imaginez que j'ai plusieurs composants Viewer qui sont utilisés pour afficher du texte et qu'ils ont peu de modes que l'utilisateur peut changer (différents préréglages de police pour l'affichage du texte/binaire/hexadécimal). Quelle serait la meilleure approche pour gérer les objets partagés - par exemple les polices, la boîte de dialogue de recherche, etc? J'ai pensé que la classe statique avec des objets paresseusement initialisés serait OK, mais cela pourrait être une mauvaise idée.Gestion des ressources partagées entre classes?

static class ViewerStatic 
{ 
    private static Font monospaceFont; 
    public static Font MonospaceFont 
    { 
     get 
     { 
      if (monospaceFont == null) 
       //TODO read font settings from configuration 
       monospaceFont = new Font(FontFamily.GenericMonospace, 9, FontStyle.Bold); 
      return monospaceFont; 
     } 
    } 

    private static Font sansFont; 
    public static Font SansFont 
    { 
     get 
     { 
      if (sansFont == null) 
       //TODO read font settings from configuration 
       sansFont = new Font(FontFamily.GenericSansSerif, 9, FontStyle.Bold); 
      return sansFont; 
     } 
    } 
} 
+2

Sachez que toutes les ressources IDisposables (polices, dialogues, etc.) que vous avez placées dans votre classe statique sera allouée pour la durée de votre application. Cela peut être ce que vous voulez; juste FYI. – TrueWill

+0

c'est ce que je veux, parce que je veux que les ressources vivent éternellement après leur création, afin qu'elles puissent être mises en place "instantanément" après le premier chargement paresseux. – Axarydax

+0

Je ne serais pas un oeil si je devais lire ce code dans une revue par les pairs (me semble bien!). –

Répondre

1

Pour les éléments que vous souhaitez créer une fois, puis réutiliser, il existe deux modèles pertinents: Singleton et Cache. Si vous réutiliserez l'article pour toujours, le Singleton est OK. La mémoire allouée à cette instance ne sera jamais effacée. Si vous allez réutiliser l'élément pendant un moment, mais peut-être que cette fonction ne sera pas utilisée pendant quelques jours, je suggère d'utiliser le cache. Ensuite, la mémoire peut être effacée lorsque l'objet n'est plus utilisé.

Si vous utilisez le Singleton, vous voulez probablement initier directement les polices plutôt que d'utiliser le pattern init Lazy. Pour moi, les polices semblent assez simples et pas susceptibles d'erreur. Toutefois, si l'élément peut échouer pendant la construction (peut-être en raison d'un fichier de police manquant ou quelque chose d'autre), alors le modèle paresseux lui permet au moins de réessayer la prochaine fois. Vous ne pouvez pas refaire un initialiseur statique plus tard, même en cas d'échec, sans redémarrer l'application entière. Veillez à limiter ces tentatives!

Enfin, le nom de votre classe "ViewerStatic" soulève un problème. Il y a un anti-pattern connu sous le nom d'objet "Dieu". Je l'appelle le "seau". Si vous le créez, des choses viendront. Vous trouverez bientôt toutes sortes de choses dans le seau. Votre classe ViewerStatic deviendra énorme. Il vaudrait mieux avoir une classe appelée "FontFlyWeights" puis une autre appelée "ConstantStrings" ou "SystemDialogFactory" ... etc.

1

Cela me semble bien, mais est-ce vraiment nécessaire? L'approche simple serait simplement de créer de nouvelles polices et boîtes de dialogue lorsque vous en avez besoin, puis de les éliminer si nécessaire et de laisser le garbage collector les nettoyer.

Avez-vous mesuré pour voir si l'approche simple a un coût apparent qui fait qu'il vaut la peine d'ajouter la complexité de mettre en cache des objets partagés?

Questions connexes