Nochmal das Decorator - Mit der abstrakten Klasse möglich?

Wuast

Bekanntes Mitglied
Hallo zusammen,

ich möchte gerade nochmal das Decorator-Pattern verwenden. Dazu wollte ich Rückfragen, ob
1. das hier so sinnvoll ist wie ich mir das überlegt habe (oder was ihr alternativ nehmen würdet)
2. ob das so umsetzbar ist oder ich da etwas falsch gemacht habe.

Ich habe folgenden relevanten Code (hab den für den Kontext nicht wichtigen Kram rausgeschnibbelt):

Java:
public class Route implements RoutePlanner {

    private ArrayList <Location> route;
    
    public Route () {
        route = new  <Location> ArrayList ();
    }
    
    @Override
    public void addDestination(Object location) {
        route.add((Location) location);
    }

    @Override
    public Object getRoute() throws Exception {
        if (this.route.isEmpty()) {
            throw new Exception ("Route has no content.");
        }
        else return route;
    }   
}

public abstract class RouteDecorator implements RoutePlanner {
    
    protected Object route;
    
    public RouteDecorator (Object route) {
        this.route = route;
    }

    public ArrayList <Location> getRoute() {
        return ((RouteDecorator) route).getRoute();
    }
}

public interface RoutePlanner {

    public void addDestination(Object location);
    
    public Object getRoute() throws Exception;
}

public abstract class Location extends RouteDecorator {

    public Location(Object route) {
        super(route);
    }
    
    // hier kommen die Attribute, Getter und Setter)
    
public ArrayList <Location> getRoute() {
        ((RouteDecorator) route).getRoute().add((Location) route);
        return ((RouteDecorator) route).getRoute();
    }   
}

//und noch ein Bspw. für eine Location, es gibt weitere

public class City extends Location {

    public City(Object route) {
        super(route);

    }

    private String parkingFacilities;
    
    public String getParkingFacilities () {
        return parkingFacilities;
    }
    
    public void setParkingFacilities (String parkingFacilities) {
        this.parkingFacilities = parkingFacilities;
    }

    @Override
    public void addDestination(Object location) {
        // TODO Auto-generated method stub   
    }
}

zu 1: Ich dachte mir, wenn ich eine Route planen möchte anhand von Zielen, die ich bereits besucht habe, kann ich doch aus einer Liste von Location-Objekten auswählen und die einer neuen Route (mit einem festgelegten Startpunkt, z.B. dem Zuhause) zufügen. Sinnvoll?
zu 2: Bin mal wieder beim Aufbau etwas verunsichert. Ich kann das ganze nicht vernünftig testen, da noch so viel fehlt - aber irgendwo musste ich anfangen / weitermachen und da kam mir gerade spontan der Gedanke, das package Routenplanung fortzuführen. Aus Entwickler-Perspektive natürlich eine katastrophale Herangehensweise :D .. Also ist das von der grundsätzlichen Art her richtig umgesetzt? und was mich am meisten verunsichert: Kann ich eine Abstrakte Klasse nehmen und dort "einfach" das interface RoutePlanner implementieren?

Würd mich über eine kurze Kontrolle freuen :)
Danke vorab und ein tolles baldiges Wochenende an euch alle.
 

mihe7

Top Contributor
zu 2.: Ich weiß nicht, was Du eigentlich versuchst, umzusetzen. Im RoutePlanner sind Destination und Route vom Typ Object. Warum? Eine Location ist ein RouteDecorator, der aber einen RoutePlanner statt einer Route dekoriert. Warum? Die "Dekoration" ist der Gestalt, dass ein Cast realisiert wird... Es scheint, als möchtest Du Generics verwenden, wobei mir auch hier nicht wirklich klar ist, warum.

zu 1.: Die Anforderung kann durchaus sinnvoll sein. Nur: was hat der gezeigte Code damit zu tun?

EDIT:
Kann ich eine Abstrakte Klasse nehmen und dort "einfach" das interface RoutePlanner implementieren?
Natürlich. Wenn die das Interface implementierende Klasse nicht alle Methoden des Interfaces implementiert, muss die Klasse sogar abstrakt sein.
 

Barista

Top Contributor
Ich habe das Dekorator-Pattern erstmals benutzt, um einen InputStream zu erweitern.

Mein Dekorator hat eine Pufferung hinzufügt.

Ein anderes Mal habe ich einen Lookahead (gucke-nach-vorn) hinzugfügt.

Ich hoffe, es hat dem Dekorator-Pattern entsprochen.

Vielleicht wäre so eine Lösung günstiger für Dich.
 

Barista

Top Contributor
Eine weitere Idee für das Dekorator-Pattern wäre ein Iterator, der das zuletzt von der next-Methode zurückgegebene Objekt noch mal zurückgeben kann.

Ich würde die Methode current nennen, weil last eventuell auch bedeuten könnte, dass zum letzten Element/Objekt des Iterators gelaufen und dieses zurückgegeben werden soll.

So einen Dekorator habe ich auch schon selbst verwendet.
 

Wuast

Bekanntes Mitglied
was hat der gezeigte Code damit zu tun?
Anscheinend zu wenig.. was mich gerade etwas verwundert. Ich dachte, ich brauche für das Pattern eine abstrakte Decorator-Klasse, ein Interface RoutePlanner welches von der Route-Klasse und der Decorator-Klasse implementiert wird und somit die Schnittstelle darstellt und die Klasse(n), die dann dekorieren sollen (hier die Locations).. die erben dann von RouteDecorator.

zu 2.: Ich weiß nicht, was Du eigentlich versuchst, umzusetzen. Im RoutePlanner sind Destination und Route vom Typ Object. Warum? Eine Location ist ein RouteDecorator, der aber einen RoutePlanner statt einer Route dekoriert. Warum? Die "Dekoration" ist der Gestalt, dass ein Cast realisiert wird... Es scheint, als möchtest Du Generics verwenden, wobei mir auch hier nicht wirklich klar ist, warum.
Typ Object war erstmal für mich ein Platzhalter als ich angefangen habe das anzugehen, weil ich dachte: Object geht doch immer und kann ich nachher ändern. Zu deinen Erklärungen stehen meine Gedanken ja oben... Was muss ich denn ändern, damit die Location nicht der Decorator ist sondern das Dekor? Hatte mich da an den Erklärungen von Entwurfsmuster von Kopf bis Fuß orientiert (respektive einem YT-Tutorial, was damit arbeitet).
 

Wuast

Bekanntes Mitglied
Ok ich habe nochmal ein bisschen rumgewurschtelt. Hatte einiges durcheinander gebracht. Hoffe, jetzt ist es besser :/

Java:
public interface RoutePlanner {
    public void addDestination(Location location);
    public ArrayList <Location> getRoute() throws Exception;
}

public abstract class RouteDecorator implements RoutePlanner {   
    protected RoutePlanner routePlanner;
    
    public RouteDecorator (RoutePlanner routePlanner) {
        this.routePlanner = routePlanner;
    }

    public ArrayList <Location> getRoute() throws Exception {
        return routePlanner.getRoute();
    }
    
    @Override
    public void addDestination(Location location) {
        routePlanner.addDestination(location);
    }
}

public class Route implements RoutePlanner {

    private ArrayList <Location> route;
    
    public Route () {
        route = new  <Location> ArrayList ();
    }
    
    @Override
    public ArrayList <Location> getRoute() throws Exception {
        if (this.route.isEmpty()) {
            throw new Exception ("Route has no content.");
        }
        else return route;
    }

    @Override
    public void addDestination(Location location) {
        route.add(location);
    }
}

public abstract class Location extends RouteDecorator {

    public Location(RoutePlanner routePlanner) {
        super(routePlanner);
    }

    @Override
    public void addDestination(Location location) {
        super.addDestination(location);
    }

    private String title;
    protected String name;
    //usw
}

public class City extends Location {

    public City(RoutePlanner routePlanner) {
        super(routePlanner);
    }

    public City() {                   
         setName("Sansibar");
    }
}

Die Klasse Route selbst implementiert das Interface auch und dann habe ich die Verbindung zu dem Decorator. Wenn ich eine abstrakte Klasse Location habe, die vom RouteDecorator erbt, dann brauche ich einen Konstruktor, der einen RoutePlanner übergeben bekommt (weil der RouteDecorator das Interface implementiert und eine geschütze Instanz vom Interface erzeugt). Ist das soweit jetzt korrekt?
Wenn ich jetzt dekorieren will, dann muss ich jedem neuen Objekt, dass ich in diesem Zug erzeuge, den RoutePlanner übergeben?! (wenn ich eine neu Route starte, dann kann ich doch auch das bereits erzeugte Objekt RoutePlanner nutzen, oder spricht etwas dagegen)?

würde dann so aussehen.

Code:
public static void main(String[] args) {
        
        RoutePlanner route = new Route();
        RouteDecorator decRoute = new Home (route);
        
        Location sansibar = new City(route);
        sansibar.setName("Sansibar");

      decRoute.addDestination(sansibar);

     Location entenhausen = new City (route);
    entenhausen.setName("Entenhausen"); entenhausen.setSightseeing("Geldspeicher");
    decRoute.addDestination(entenhausen);

    }
 

mihe7

Top Contributor
ich brauche für das Pattern
Vergiss die Design Patterns. Ein Design Pattern ist nichts, das es explizit anzustreben gilt. Wenn Du ein Design-Problem hast und Dir keine Lösung einfällt, dann kannst Du evtl. nachsehen, ob es ein Pattern dafür gibt (mit der Zeit kennst Du die wichtigsten natürlich auswendig), aber grundsätzlich gestaltest Du den Entwurf unabhängig davon. Wenn Du dabei "zufällig" ein Design Pattern verwendest, dann hast Du halt einen Namen dafür, den Du zur Kommunikation mit anderen verwenden kannst.

Du darfst ein Interface in den Patterns nicht mit einem Interface einer Programmiersprache wie Java gleichsetzen. Jede Klasse besitzt eine "Schnittstelle", die aus ihren öffentlichen Methoden besteht. Wenn also im Decorator Pattern die Komponente als Interface angegeben ist, kann das auch eine Java-Klasse sein.

Beim Decorator geht es darum, durch eine gewisse Struktur im Entwurf zusätzliche Funktionalität (aka Verhalten) Objekten hinzuzufügen, ohne deren Klasse ändern zu müssen. Ein Beispiel ist z. B. der PrintWriter, der selbst ein Writer ist. Writer ist eine (abstrakte) Klasse, die über ein paar Methoden verfügt (append, write, close und flush). Diese bilden das im Pattern genannte "Interface". Der PrintWriter ist von Writer abgeleitet, hat also die gleiche Schnittstelle wie ein Writer und leitet Aufrufe der Methoden der Writer-Schnittstelle an ein Delegate (vom Typ Writer) weiter. Der PrintWriter erweitert also das Delegate um zusätzliche Funktionalitäten wie z. B. format, printf, println usw.

Natürlich muss das LSP einghalten werden, d. h. ein "extends" beschreibt nach wie vor eine is-a-Beziehung. Und damit komme ich zu Deinem Code: Location is-a RouteDecorator und implementiert damit indirekt RoutePlanner. RoutePlanner kennt Location. Das ist eine zyklische Abhängigkeit und zumindest ein "Design smell". Vielmehr allerdings frage ich mich, warum Location ein RouteDecorator ist.

Kannst Du - möglichst ohne softwaretechnisches Gedöns - beschreiben, was das Ziel des Ganzen ist? Zum Beispiel hattest Du am Anfang geschrieben, Du möchtest Locations aus einer Liste auswählen. Dazu brauchst Du doch einfach nur eine Liste von Location-Objekten. Daher hatte ich gefragt, was der Code damit zu tun hat. Dann hattest Du erwähnt, dass eine feste Stadt der Startpunkt einer Route sein soll: auch schön, nur dann erzeugst Du halt eine Route und fügst dieser als erstes die fixe Stadt hinzu.

Vielleicht bin ich blind oder leide an geistiger Umnachtung, aber ich sehe den Zusammenhang zum Decorator nicht.
 

Barista

Top Contributor
Deine Begrifflichkeit zeigt, dass Du einfach nur rumwurstelst.

Ein Routenplaner ist ein Routenplaner und keine Route.

Ein Routenplaner berechnet eine Route.

Ein Dekorator erweitert eine vorhandene Funktionalität.

Also kann nur ein Routenplaner dekoriert werden, keine Route.

Dann ist die Frage, welche Funktionalität soll dem Routenplaner hinzugefügt werden.

Das Interface oder abstrakte Oberklasse ist nur dafür da, dass der aufrufende (Anwendungs-)Code die dekorierte Variante genauso benutzen kann wie die einfache Variante.
 

Wuast

Bekanntes Mitglied
Wollt schon sagen..

Ok, Patterns vergessen. Danke, dass du es nochmal so ausdrücklichst sagst. Dachte, das wäre schon so gewollt, dass man auf diese Art Programme aufbaut. "State of the art" und was man da immer liest..

Kannst Du - möglichst ohne softwaretechnisches Gedöns - beschreiben, was das Ziel des Ganzen ist? Zum Beispiel hattest Du am Anfang geschrieben, Du möchtest Locations aus einer Liste auswählen. Dazu brauchst Du doch einfach nur eine Liste von Location-Objekten. Daher hatte ich gefragt, was der Code damit zu tun hat. Dann hattest Du erwähnt, dass eine feste Stadt der Startpunkt einer Route sein soll: auch schön, nur dann erzeugst Du halt eine Route und fügst dieser als erstes die fixe Stadt hinzu.

Vielleicht bin ich blind oder leide an geistiger Umnachtung, aber ich sehe den Zusammenhang zum Decorator nicht.
Ich dachte bei dem Routenplaner, es macht vllt. Sinn, eine Liste von möglichen Zielen um selbige zu erweitern. Mein Grundgedanke war, dass ich in dem Programm dokumentieren kann, wo ich im Urlaub war und wie es gefallen hat, was mir aufgefallen ist etc. pp. - dafür gibt es ja bereits eine Liste, der Locations hinzufügen kann. Kann dann z.B. eine Stadt oder ein See sein.
Und ein anderer Teil sollte dann ermöglichen, eine Route anhand der bisher besuchten Orte zu planen. Ich habe einen Ort, wo ich starte (egal wo), und dann schau ich mal durch meine Liste, wo wir gewesen sind und welche PLZ in der Nähe sind, und füge die zu einer möglichen Route hinzu (für den Fall, dass ich nochmal hin möchte). Und für diesen letzten Teil dachte ich mir kann ich doch eine Route dekorieren :)
Dann ist die Frage, welche Funktionalität soll dem Routenplaner hinzugefügt werden.
keine wenn ich darüber nachdenke.

Ich wurstel den decorator wieder raus und übe mich im kiss
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Ostkreuz Wieso wird die Methode nochmal aufgerufen? Java Basics - Anfänger-Themen 5
E nochmal synchronisierte Methoden Java Basics - Anfänger-Themen 5
J Hinzufügen eines Objekts in eine Liste, um später dann nochmal auf das Objekt zugreifen zu können Java Basics - Anfänger-Themen 8
B Unique ID nochmal Unique machen Java Basics - Anfänger-Themen 20
X Wenn Exception dann nochmal try. Java Basics - Anfänger-Themen 7
R Nochmal Quaxli Spieletutorial ;) Java Basics - Anfänger-Themen 9
V Nochmal Hilfe - Replace Methode Java Basics - Anfänger-Themen 2
T Override klappt nochmal wie? Java Basics - Anfänger-Themen 3
Haubitze_Broese Methode am ende nochmal startet? Java Basics - Anfänger-Themen 8
D Ausgabe sauber formatieren *bitte nochmal reinschaun* Java Basics - Anfänger-Themen 7
D C0 und C1 Test nochmal Java Basics - Anfänger-Themen 9
B könnte nochmal jemand über mein Projekt schauen? Java Basics - Anfänger-Themen 4
C Nochmal zu lokale Einstellungen Java Basics - Anfänger-Themen 2
G nach Thread.start(); nochmal start(); aufrufen geht nicht Java Basics - Anfänger-Themen 4
S Fehler durch Exception beheben und nochmal versuchen Java Basics - Anfänger-Themen 4
U Nochmal was zum Date(); Java Basics - Anfänger-Themen 23
F nochmal Array Declaration Java Basics - Anfänger-Themen 2
G Nochmal vereinfacht - hoffe mer kanns nachvollziehen Java Basics - Anfänger-Themen 9
F Referenz Pointer oder doch nochmal neu suchen ? Java Basics - Anfänger-Themen 2
G Nochmal zweidimensionaler Vector Java Basics - Anfänger-Themen 10
ven000m Char einlesen, wie ging das nochmal? Java Basics - Anfänger-Themen 9
D Nochmal zu den dummen Eingaben über Tastatur Java Basics - Anfänger-Themen 15
B Nochmal ich/ Graphik wird nicht angezeigt ? Java Basics - Anfänger-Themen 12
G Nochmal Problem mit Kommunikation zwischen Klassen Java Basics - Anfänger-Themen 3
B nochmal ich / jdk1.5 Java Basics - Anfänger-Themen 5
S nochmal Taschenrechner ;) Java Basics - Anfänger-Themen 16
B Nochmal NoClassDefFoundError Java Basics - Anfänger-Themen 3
megachucky nochmal JDBC. komme nicht weiter. Java Basics - Anfänger-Themen 4
K nochmal Jtable Java Basics - Anfänger-Themen 5
P Grundsatzfrage zu Decorator-Pattern Java Basics - Anfänger-Themen 6
T Decorator Pattern Java Basics - Anfänger-Themen 7
V Frage zu Decorator-Pattern Java Basics - Anfänger-Themen 4
U Funktionale Interfaces mit mehreren abstrakten Methoden? Java Basics - Anfänger-Themen 8
L Klassen Kann eine Unterklasse einer abstrakten Klasse ein Interface implementieren? Java Basics - Anfänger-Themen 2
M Methoden Overloading in abstrakten Klassen Java Basics - Anfänger-Themen 26
F Probleme mit privaten Klassen (abstrakten Klassen) Java Basics - Anfänger-Themen 1
P OOP Sinn von abstrakten Klassen Java Basics - Anfänger-Themen 2
B in einem abstrakten Set ,Elemente einer einfache verkettete List epeichern Java Basics - Anfänger-Themen 13
G Methode einer Abstrakten Klasse aufrufen Java Basics - Anfänger-Themen 1
C Konstruktor in Abstrakten Klassen Java Basics - Anfänger-Themen 4
O Javadoc bei abstrakten Methoden Java Basics - Anfänger-Themen 1
M Frage zu Generics in Klassen, Abstrakten Klassen und Interfaces Java Basics - Anfänger-Themen 5
G Auf einen bestimmten Konstruktor in der abstrakten Superklasse zugreifen? Java Basics - Anfänger-Themen 2
T Interface implementieren mit Abstrakten Typen? Java Basics - Anfänger-Themen 4
F Interface Unterschied von Attributen und Methoden bei abstrakten Klassen und Interfaces Java Basics - Anfänger-Themen 5
T fenster schliesen und mouse events in einer nicht abstrakten klasse Java Basics - Anfänger-Themen 6
Corben Methoden Methode einer Abstrakten Klasse Java Basics - Anfänger-Themen 7
A Deklarationen in abstrakten Klassen und Interfaces Java Basics - Anfänger-Themen 11
N finale Attribute in abstrakten Basisklassen Java Basics - Anfänger-Themen 6
T Frage zu Interfaces und Abstrakten Klassen Java Basics - Anfänger-Themen 4
Spin Eigenen Abstrakten Datentypen Java Basics - Anfänger-Themen 28
A Verwendung von abstrakten Klassen Java Basics - Anfänger-Themen 17
X Problem: Erben von einer abstrakten Klasse Java Basics - Anfänger-Themen 4
I [Java] Umgang mit abstrakten Klassen, Interfaceklassen (BSP) Java Basics - Anfänger-Themen 12
M Frage zu einer abstrakten Klasse Java Basics - Anfänger-Themen 16
N variablen vom typ einer abstrakten Klasse Java Basics - Anfänger-Themen 5
M instanzieren einer abstrakten Klasse? Java Basics - Anfänger-Themen 2
A Objekte von abstrakten Klassen? Java Basics - Anfänger-Themen 6
M Rückgabetype Unterklasse von einer abstrakten Klasse Java Basics - Anfänger-Themen 3
V Verständnisproblem mit Abstrakten zu Konkreten Klassen Java Basics - Anfänger-Themen 7
S Field einer abstrakten Klasse wird nicht gesetzt Java Basics - Anfänger-Themen 2
T Instanzen von abstrakten Klassen? Java Basics - Anfänger-Themen 14
S Objektrückgabe durch Factory-Methode in abstrakten Klassen Java Basics - Anfänger-Themen 4

Ähnliche Java Themen

Neue Themen


Oben