2010-03-23 12 views
5

Wyobraź sobie, że mam kilka komponentów przeglądarki, które są używane do wyświetlania tekstu i mają kilka trybów, które użytkownik może przełączać (różne ustawienia czcionek do wyświetlania tekstu/binarny/hex). Jakie byłoby najlepsze podejście do zarządzania współdzielonymi obiektami - na przykład czcionkami, okienkiem dialogowym wyszukiwania itp.? Pomyślałem, że klasa statyczna z leniwie zainicjowanymi obiektami byłaby w porządku, ale może to być zły pomysł.Zarządzanie dzielonymi zasobami między klasami?

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

Należy pamiętać, że wszelkie zasoby IDisposable (czcionki, dialogi itp.), Które umieściłeś twoja klasa statyczna zostanie przydzielona na okres ważności twojej aplikacji. To może być to, czego chcesz; tylko FYI. – TrueWill

+0

to jest to, czego chcę, ponieważ chcę, aby zasoby pozostały na zawsze po ich utworzeniu, aby można je było "natychmiastowo" wychowywać po pierwszym leniwym ładowaniu. – Axarydax

+0

Nie chciałbym stracić oka, gdybym przeczytał ten kod w recenzjach (wygląda mi dobrze!). –

Odpowiedz

1

Dla elementów, które chcesz utworzyć raz, a następnie użyć ponownie, istnieją dwa odpowiednie wzorce: Singleton i Cache. Jeśli będziesz ponownie używał przedmiotu na zawsze, Singleton jest OK. Pamięć przydzielona do tej instancji nigdy nie zostanie wyczyszczona. Jeśli będziesz używać tego przedmiotu przez jakiś czas, ale może funkcja ta nie będzie używana przez kilka dni, sugeruję użycie pamięci podręcznej. Następnie pamięć można wyczyścić, gdy element nie jest już używany.

Jeśli używasz Singleton, prawdopodobnie chcesz po prostu zainicjować czcionkę bezpośrednio, zamiast używać wzoru Lazy init. Dla mnie Fonts brzmi dość prosto i nie może się zepsuć. Jeśli jednak element może zawieść podczas budowy (być może z powodu brakującego pliku czcionki lub czegoś podobnego), to leniwy wzorzec przynajmniej pozwala mu ponowić próbę następnym razem. Nie można ponownie wykonać statycznego inicjatora później, nawet jeśli się nie powiedzie, bez ponownego uruchamiania całej aplikacji. Zachowaj ostrożność, aby ograniczyć te próby!

Wreszcie, nazwa klasy "ViewerStatic" budzi niepokój. Istnieje anty-wzór znany jako obiekt "Boga". Nazywam to "wiadrem". Jeśli ją stworzysz, rzeczy nadejdą. Wkrótce znajdziesz wszystkie rodzaje rzeczy, które zostaną wrzucone do wiadra. Twoja klasa ViewerStatic stanie się ogromna. Lepiej byłoby mieć klasę o nazwie "FontFlyWeights", a następnie inną nazwę o nazwie "ConstantStrings" lub "SystemDialogFactory" ... itd.

1

Wydaje mi się to w porządku, ale czy to naprawdę konieczne? Prostym podejściem byłoby po prostu tworzenie nowych czcionek i okien dialogowych, kiedy ich potrzebujesz, a następnie usuwanie ich w razie potrzeby i pozostawienie ich do wyczyszczenia.

Czy zmierzyłeś, czy proste podejście ma zauważalny koszt, który sprawia, że ​​warto dodać złożoność buforowania współużytkowanych obiektów?

Powiązane problemy