# Single Sourcing und der ImplementationLoader



## andkul (3. Nov 2011)

Hallo,
wie aus dem Titel unschwer zu erkennen ist, beschäftige ich mich gerade mit RCP/RAP-Single Sourcing, dabei bin ich auf ein Problem gestoßen, für das mir gerade keine Lösung einfällt und bei google hab ich auch keine Beispiele dafür gefunden.

Situation:
Ich habe eine Klasse ClassA im Host-Bundle. Diese Klasse enthält eine Methode (doSomething()), die für RCP und RAP unterschiedlich implementiert werden muss. Deshalb habe ich ClassA abstrakt und die Methode statisch gemacht und lasse hier den Aufruf lediglich an die Implementierung (IMPL.doSomethingImpl()) im passenden Fragment delegieren. Das Problem ist, dass ich damit diese abstrakte Klasse nicht mehr instantieren kann, ohne gleich dessen abstrakte Methoden zu implementieren (die ja gerade in den Fragementen implementiert werden soll). Ich brauche aber leider ein Objekt dieser Klasse.

[Java]
public abstract class ClassA {

	private static final ClassA IMPL 
		= (ClassA)ImplementationLoader.createInstance(ClassA.class);

	public ClassA(final String someStringArg, final int someIntArg){
		//...
	}

	//DELEGATE
	public static String doSomething(final String someArg)	{
		return IMPL.doSomethingImpl(someArg);
	}

	//je 1 Implementierung in RAP-Fragment und RCP-Fragment erzwingen
	public abstract String doSomethingImpl(final String someArg);

}
[/Java]

Wäre evtl. eine Alternative, die ClassA ein Interface IClassA implementieren zu lassen, das die Fragement-Klassen ClassAImpl in den beiden Fragementen ebenfalls implementieren? Damit würde ja die ClassA sozusagen eine allgemeine Implementierung liefern, die evtl. eine Fehlerausgabe machen könnte, oder so. Wenn alles korrekt funktioniert, dann müsste diese Methode im Host-Bundle ja sowieso von einer Ableitung in einem Fragment überschrieben werden und damit kommt keine Fehlermeldung?!
Wie ist denn da der Best Practice?
Vielen Dank schon mal für die Hilfe


----------



## nillehammer (3. Nov 2011)

- Definiere ein Interface "MyDoer" mit der Methode "doSomething"
- Mache Davon eine Implementierung MyDoerRcpImpl und eine Implementierung MyDoerRapImpl
- Ermittle anhand irgend eines Merkmals, ob Du Dich in einer RCP- oder RAP-Umgebung befindest (kenne mich da nicht so aus, weiß deswegen nicht, was man da nehmen kann)
- Sorge anhand der ermittelten Umgebung am besten mit Hilfe eines IOC-Containers, am zweit Besten mit einer Factory, am dritt besten durch eigenhändige Instanzierung für eine Referenz auf die richtige Impl-Instanz


----------



## Gast2 (15. Nov 2011)

Wenn du kein DI verwendest, bleibt dir dir Möglichkeit über OSGi-Services...
Mach ein Bundle mit einem Interface mit der Methode doSth().

Mach ein Bundle/Fragement für die RCP und ein Bundle/Fragment für die RAP Anwendung, welche jeweils eine Implmentierung des Interfaces hat und biete diese als OSGI-Services an.


----------



## andkul (15. Nov 2011)

Erstmal danke für die Anworten.
Ich bin das Problem jetzt erstmal umgangen, indem ich einen Kompromiss implementiert habe, der für RCP und RAP funktioniert...

"- Ermittle anhand irgend eines Merkmals, ob Du Dich in einer RCP- oder RAP-Umgebung befindest (kenne mich da nicht so aus, weiß deswegen nicht, was man da nehmen kann)"
Das funktioniert leider nicht...

@nillehammer: Diese Lösung hört sich gut an, ich werds probieren, sobald ich Zeit finde und halte euch auf dem laufenden, ob´s funktioniert...

Danke


----------



## Gast2 (15. Nov 2011)

andkul hat gesagt.:


> "- Ermittle anhand irgend eines Merkmals, ob Du Dich in einer RCP- oder RAP-Umgebung befindest (kenne mich da nicht so aus, weiß deswegen nicht, was man da nehmen kann)"
> Das funktioniert leider nicht...



Doch in dem deine Bundles OSGi Services anbieten dann macht der Rest das Framework für dich.
OSGi with Eclipse Equinox - Tutorial
Kapitel 7, aber der Rest schadet auch nicht.


----------

