Fabryki elementów

Fabryki elementów służą do odtwarzania obiektów modelu środowiska roboczego na podstawie danych zapisanych podczas zamykania środowiska roboczego.

Przed bliższym zapoznaniem się z rozszerzeniem fabryki elementów należy dokonać przeglądu ogólnej techniki używanej na platformie w celu dodawania zachowania właściwego dla modułów dodatkowych do typowych obiektów modelu platformy.

Interfejs IAdaptables i adaptery środowiska roboczego

Podczas przeglądania różnych klas środowiska roboczego można zauważyć, że wiele interfejsów środowiska roboczego rozszerza interfejs IAdaptable.

Moduły dodatkowe dodają określone zachowanie do istniejących już w systemie typów za pośrednictwem adapterów. Na przykład środowisko robocze może oczekiwać od zasobów etykiety i obrazu w celu wyświetlenia. Wiadomo, że dodawanie zachowania właściwego dla interfejsu użytkownika do obiektów niskiego poziomu nie jest dobrą praktyką. Powstaje więc pytanie, w jaki sposób można dodać to zachowanie do typów zasobów.

Moduły dodatkowe mogą rejestrować adaptery, które dodają zachowanie do istniejących już typów. Kod aplikacji może następnie wysłać zapytanie do obiektu o konkretny adapter. Jeśli taki adapter został zarejestrowany dla tego obiektu, aplikacja może uzyskać dostęp do adaptera i użyć nowych zachowań zdefiniowanych w adapterze.

Zapewniając możliwość dynamicznego wysyłania zapytań o adapter do obiektu, można zwiększyć elastyczność systemu w miarę jego ewolucji. Przy użyciu modułów dodatkowych można rejestrować nowe adaptery dla typów już istniejących na platformie bez konieczności zmiany definicji tych typów. Wzorzec zapytania obiektu o konkretny adapter wygląda następująco:

   //dany jest obiekt o, przy jego użyciu mają być realizowane funkcje "środowiska roboczego".

   if (!(o instanceof IAdaptable)) {
      return null;
   }
   IWorkbenchAdapter adapter = (IWorkbenchAdapter)o.getAdapter(IWorkbenchAdapter.class);
   if (adapter == null)
      return null;
   // teraz można traktować o jako IWorkbenchAdapter
   ...

Jeśli dla danego obiektu nie został zarejestrowany żaden adapter, zamiast adaptera zostanie zwrócona wartość NULL. Klienci muszą być przygotowani do obsługi tej sytuacji. Może się czasem zdarzyć, że oczekiwany adapter nie został zarejestrowany.

W środowisku roboczym adaptery są używane do uzyskiwania informacji o interfejsie użytkownika z podstawowych typów platformy, takich jak IResource. Adaptery odgradzają typy podstawowe od informacji właściwych dla interfejsu użytkownika i umożliwiają rozwijanie interfejsów środowiska roboczego bez zmiany definicji tych typów.

Bez adapterów każda klasa przekazywana w interfejsie API środowiska roboczego musiałaby implementować interfejsy użytkownika, co powodowałoby wzrost liczby definicji klas, wprowadzało ścisłe powiązania i prowadziło do cyklicznych zależności między klasami podstawowymi i klasami interfejsu użytkownika. Dzięki adapterom każda klasa implementuje interfejs IAdaptable i używa rejestru adapterów w celu umożliwienia rozszerzania zachowania typów podstawowych przy użyciu modułów dodatkowych.

W kodzie środowiska roboczego można znaleźć fragmenty, w których sprawdza się istnienie adaptera dla typu podstawowego platformy. Zapytanie służy do znalezienia obiektu, który potrafi podać informacje o typie dotyczące interfejsu użytkownika.

Fabryki elementów

Gdy użytkownik zamyka środowisko robocze, konieczne jest zapisanie stanu obiektów IAdaptable wyświetlanych w środowisku. Stan obiektu przechowuje się, zapisując parametry danych podstawowych w specjalnym formacie - IMemento. Identyfikator fabryki, która może odtworzyć obiekt na podstawie informacji IMemento, jest zapisywany wraz z danymi w systemie plików.

Podczas ponownego uruchamiania platformy środowisko robocze znajduje fabrykę elementów powiązaną z identyfikatorem fabryki w informacjach IMemento. W celu znalezienia fabryki środowisko sprawdza w rejestrze modułów dodatkowych elementy wnoszone w punkcie rozszerzeń org.eclipse.ui.elementFactories.

Kod w języku znaczników jest w tym przypadku całkiem prosty. Wystarczy tylko określić identyfikator fabryki i odpowiednią klasę, która implementuje fabrykę.

Poniższy fragment kodu pochodzi z pliku plugin.xml środowiska roboczego.

   <extension
         point="org.eclipse.ui.elementFactories">
      <factory
            class="org.eclipse.ui.internal.model.ResourceFactory"
            id="org.eclipse.ui.internal.model.ResourceFactory">
      </factory>
      <factory
            class="org.eclipse.ui.internal.model.WorkspaceFactory"
            id="org.eclipse.ui.internal.model.WorkspaceFactory">
      </factory>
      <factory
            class="org.eclipse.ui.part.FileEditorInputFactory"
            id="org.eclipse.ui.part.FileEditorInputFactory">
      </factory>
      <factory
            class="org.eclipse.ui.internal.dialogs.WelcomeEditorInputFactory"
            id="org.eclipse.ui.internal.dialogs.WelcomeEditorInputFactory">
      </factory>
      <factory
            class="org.eclipse.ui.internal.WorkingSetFactory"
            id="org.eclipse.ui.internal.WorkingSetFactory">
      </factory>
    </extension>