Element-factories blir brukt til å gjenopprette arbeidsbenkens modellobjekter basert på data som er lagret ved avslutning av arbeidsbenken.
Før vi ser nærmere på utvidelsen for element-factory, må vi se på en vanlig teknikk som brukes i plattformen for å legge til plugin-spesifikk funksjonalitet i vanlige plattformmodellobjekter.
Når du blar deg gjennom de ulike arbeidsbenkklassene, vil du legge merke til at mange av arbeidsbenkgrensesnittene utvider grensesnittet IAdaptable.
Plugin-moduler bruker adaptere for å legge til spesifikk funksjonalitet i typer som allerede finnes i systemet. Det kan for eksempel hende at arbeidsbenken vil at ressurser skal svare en etikett og et bide for å vise dem. Ut fra et designperspektiv er det ikke lurt å legge til brukergrensesnittfunksjonalitet i objekter på lavere nivåer, så hvordan skal vi legge til denne funksjonaliteten i ressurstypene?
Plugin-moduler kan registrere adaptere som legger til funksjonalitet i typer som allerede eksisterer. Applikasjonskoden kan deretter be et objekt om en bestemt adapter. Hvis det er registrert en adapter, kan applikasjonen hente den og bruke den nye funksjonaliteten som er definert i adapteren.
Ved å oppgi en funksjon som dynamisk oppretter spørring etter et objekt i en adapter, kan vi forbedre fleksibiliteten i systemet etter hvert som det utvikles. Det kan registreres nye adaptere for plattformtyper gjennom nye plugin-moduler, uten at definisjonene for de opprinnelige typene trenger å endres. Mønsteret som brukes for å be om en bestemt adapter, er slik:
//given an object o, we want to do "workbench" things with it. if (!(o instanceof IAdaptable)) { return null; } IWorkbenchAdapter adapter = (IWorkbenchAdapter)o.getAdapter(IWorkbenchAdapter.class); if (adapter == null) return null; // now I can treat o as an IWorkbenchAdapter ...
Hvis det ikke er registrert noen adapter for det aktuelle objektet, returneres null som adapteren. Klienter må være forberedt på å håndtere dette. Det kan nemlig hende at det ikke er registrert en forventet adapter.
Arbeidsbenken bruker adaptere til å hente informasjon om brukergrensesnitt fra baseplattformtyper, for eksempel IResource. Adaptere skjermer basetypene mot brukergrensesnittspesifikk kunnskap og gjør det mulig for arbeidsbenken å utvikle grensesnittene uten å endre definisjonene av basen.
Uten adaptere ville klasser som sendes rundt i programmeringsgrensesnittet for arbeidsbenken, bli tvunget til å implementere brukergrensesnittene, noe som ville ført til flere klassedefinisjoner, en tett kobling og sirkulære avhengigheter mellom kjernen og brukergrensesnittklassene. Med adaptere implementerer hver klasse IAdaptable og bruker adapterregisteret til å la plugin-moduler utvide funksjonaliteten i basetypene.
Du vil oppdage at det over alt i arbeidsbenkkoden er tilfeller der det blir bedt om en adapter i plattformens kjernetype. Spørringen brukes for å hente et objekt som vet hvordan det skal svare med brukergrensesnittorientert informasjon om typen.
Når brukeren avslutter arbeidsbenken, må den gjeldende tilstanden i IAdaptable-objektene som vises i arbeidsbenken, lagres. En objekttilstand lagres ved å lagre de primitive dataparametrene til objektet i et spesialformat, en IMemento. I tillegg lagres også IDen for en factory som kan gjenopprette objektet fra en IMemento, og dataene lagres i filsystemet.
Når plattformen startes på nytt, finner arbeidsbenken den element-factory som er tilknyttet factory-IDen for IMemento. Dette gjøres ved å søke gjennom plugin-registeret etter bidrag til org.eclipse.ui.elementFactories-utvidelsen.
Kodetypen er nokså enkel. Vi trenger bare å oppgi factory-IDen og den tilhørende klassen som implementerer factory.
Følgende kodesnutt kommer fra plugin-modulens plugin.xml.
<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>