Decorator Pattern

TJava

Bekanntes Mitglied
Hallo ich habe ein paar Fragen zum Decorator Pattern.
Java:
public abstract class Decorator implements AutoItExecutor {

	private final AutoItExecutor exec;

	public Decorator(final AutoItExecutor exec) {
		this.exec = exec;
	}
	public void run(TestSuite t, TestResult r){
		
	}

	@Override
	public void setConfiguration(AutoItConfiguration conf) {
		exec.setConfiguration(conf);
		
	}

	@Override
	public void configure(Configuration c) {
		exec.configure(c);
		
	}

	@Override
	public void run(TestCase t, TestResult r) {
		exec.run(t, r);
		
	}

	
}



Java:
public class ATestDecorator extends Decorator {

	public ATestDecorator(AutoItExecutor exec) {
		super(exec);

	}

	public void run(TestSuite t, TestResult r) {
		System.out.println("opkporkpork");

	}

}

Die Main

Java:
AutoItTestResult result = new AutoItTestResult();
		
		AutoItExecutor implalt = new AutoItExecutorImplementation(config);
		impl = new ATestDecorator(implalt);
		
		
		
		impl.run(Test1, result);
		impl.run(suite1, result);

Hoffentlich versteht ihr das irgendwie.:-D

Ich verstehe nicht warum das ganze nicht so funktioniert:

Java:
AutoItExecutor implalt = new AutoItExecutorImplementation(config);
		AutoItExecutor impl = new ATestDecorator(implalt);
				
		impl.run(Test1, result);
		impl.run(suite1, result);

Die Methode impl.run(suite1, result); ist so unbekannt.
Oder ist es egal welchen Typ das ganze hat.
 
Zuletzt bearbeitet:
Man kann auch neue hinzufügen, das ist aber nicht so richtig Sinn des Decorator-Patterns.

Die gesuchte Methode ist nicht in "AutoItExecutor" enthalten. Aber dort, wo ein "AutoItExecutor" (ob dekoriert oder nicht) verwendet werden soll, sollte er auch nur als AutoItExecutor bekannt sein, und dann kann man auch nur die Methoden aufrufen, die in AutoItExecutor stehen.

Sowas wie
ATestDecorator impl = new ATestDecorator(implalt);
impl.run(suite, result);
würde zwar gehen, aber man würde sich dann darauf verlassen, dass dort ein ATestDecorator verwendet wird, was eine vermutlich nicht zu akzeptierende Einschränkung (d.h. Festlegung auf einen konkreten Typ) sein dürfte...
 
Üblicherweise ja. Nochmal: Man KANN auch neue Methoden hinzufügen (wenn man das will, und für richtig hält), aber da man dann auf den konkreten Typ festgelegt ist, hat das nichts mehr mit der eigentlichen Intention des Decorators zu tun...
 
Weil es dann einfach ein neuer Typ ist mit den gleichnamigen Methoden?
Und würde überall im Code diese Typänderung verlangen. oder ?
 
Nicht direkt... Natürlich kann man diesen Speziellen Typ dann auch noch allgemein verwenden, aber man kann dort dann nicht mehr auf die speziellen Methoden zugreifen.

Java:
void doSomething(AutoItExecutor a)
{
    // Hier kann man alle Methoden verwenden, die
    // im Interface stehen
}

void foo()
{
    AutoItExceutor a0 = ... wird irgendwie erstellt

    a0.run(testCase, r); // Geht: Die Methode run(TestCase...) steht im Interface AutoItExecutor

    AutoItExecutor a1 = new ATestDecorator(a0);
    a1.run(testCase, r); // Geht natürlich auch

    a1.run(testSuite, r); // Geht NICHT: Die Methode run(TestSuite...) steht NICHT im Interface!

    ATestDecorator a2 = new ATestDecorator(a0);
    a1.run(testSuite, r); // Geht: Hier weiß man, dass 'a2' ein ATestDecorator ist, der diese Methode hat

    // 'a2' kann trotzdem noch an die Methode übergeben werden,
    // die ein AutoItExceutor erwartet - 'a2' IST ja (auch) ein AutoItExceutor!
    // Aber IN der Methode kann man run(TestSuite...) NICHT mehr
    // aufrufen, weil man DORT nicht mehr weiß, dass es ein 
    // ATestDecorator ist, sondern nur noch, dass es ein AutoItExecutor ist....
    doSomething(a2);
}

// Wenn man so eine Methode schreiben würde:
private void doSomethingSpecial(ATestDecorator a)
{
    // dann könnte man hier auch run(TestSuite...) aufrufen,
    // aber das Objekt, das an diese Methode übergeben wird,
    // muss dafür auch ein ATestDecorator sein. Diese
    // Methode würde dann - im Gegensatz zu 'doSomething' -
    //  nicht mehr mit jedem AutoItExceutor funktionieren,
    // sondern NUR mit dem speziellen ATestDecorator 
}

Wie gesagt: So eine spezielle Methode kann OK sein wenn man die z.B. verwenden will, um den speziellen ATestDecorator irgendwie zu konfigurieren oder so. Aber man sollte sich immer im klaren sein, dass das NUR mit dem speziellen ATestDecorator funktioniert. Wenn du gerade noch in der "Planungsphase" bist, kannst du ja überlegen, ob die run(TestSuite...) nicht vielleicht auch ins AutoItExecutor-Interface mit rein sollte...
 
Wow Danke für die super Erklärung. Ich werde es jetzt wahrscheinlich mit ins Interface aufnehmen.
Naja dann habe ich wenigsten das Pattern kennengelernt.

Vielen Dank
 

Zurück
Oben