I just learned about the Decorator Pattern. I'm trying to implement a method which always leads to a NullPointerException. I've been looking for missing parameters, but I couldn't find anything. The QuackBehavior seems to "disappear" as soon as I try to apply two Decorators to a Duck Object. Thanks in advance!
PS: The NullPointerException didn't seem to appear when I set the attributes (Duck) to public and let the getters stay the same. But that won't work for me since I want to parse to an XML file later.
Exception in thread "main" java.lang.NullPointerException
at de.ostfalia.swt.progaufgabe_4.HoarseDuckDecorator.quack(HoarseDuckDecorator.java:12)
at de.ostfalia.swt.progaufgabe_4.App.main(App.java:25)
Duck
public abstract class Duck{
private QuackBehavior quack;
private FlyBehavior fly;
private DuckState state;
public Duck() {
setState(DuckState.STANDING);
}
public void fly() {
getFly().fly(this);
}
public void land() {
getFly().land(this);
}
public String quack() {
return quack.quack();
}
public void setQuackBehavior (QuackBehavior quack) {
this.quack = quack;
}
public void setFlyBehavior (FlyBehavior fly) {
this.setFly(fly);
}
public QuackBehavior getQuackBehavior() {
return this.quack;
}
public void setState (DuckState state) {
this.state = state;
}
public DuckState getState() {
return state;
}
public FlyBehavior getFly() {
return fly;
}
public void setFly(FlyBehavior fly) {
this.fly = fly;
}
}
QuackBehavior
public abstract class QuackBehavior {
public String geräusch;
public QuackBehavior() {
this.geräusch = "";
}
public String quack() {
return this.geräusch;
}
public void setGeräusch(String s) {
}
}
Quack (certain QuackBehavior)
public class Quack extends QuackBehavior {
String geräusch = "Quack!";
public String quack() {
return geräusch;
}
public void setGeräusch(String s) {
this.geräusch = s;
}
}
Quiek (certain QuackBehavior)
public class Quiek extends QuackBehavior {
String geräusch = "Quiek!";
public String quack() {
return geräusch;
}
public void setGeräusch(String s) {
this.geräusch = s;
}
FlyBehavior
public abstract class FlyBehavior {
public void fly(Duck parent) {
}
public void land(Duck parent) {
}
}
FlyWithWings (certain FlyBehavior)
public class FlyWithWings extends FlyBehavior{
public void fly(Duck parent) {
if (parent.getState().equals(DuckState.STANDING)){
parent.setState(DuckState.FLYING);
}
}
public void land(Duck parent) {
if (parent.getState().equals(DuckState.FLYING)){
parent.setState(DuckState.STANDING);
}
}
}
FlyNot (certain FlyBehavior)
public class FlyNot extends FlyBehavior {
public void fly(Duck parent) {
}
public void land(Duck parent) {
}
}
DuckState
public enum DuckState {
FLYING, STANDING;
}
RedheadDuck (actual Duck)
public class RedheadDuck extends Duck{
private FlyWithWings fly;
private Quack quack;
public RedheadDuck() {
this.fly = new FlyWithWings();
this.quack = new Quack();
}
}
RubberDuck (not actually a real Duck)
public class RubberDuck extends Duck {
private FlyNot fly;
private Quiek quack;
public RubberDuck() {
this.fly = new FlyNot();
this.quack = new Quiek();
}
}
App (the snippet I am running)
public class App {
public static void main(String[] args) {
Duck duck = new ChattyDuckDecorator(new MallardDuck());
duck = new HoarseDuckDecorator(duck);
ducksim.addDuck(duck);
System.out.println(duck.quack()); //NullPointerException
}
}
DuckDecorator
public abstract class DuckDecorator extends Duck {
public Duck specialDuck;
public DuckDecorator(Duck ducky) {
this.specialDuck = ducky;
}
public String quack(Duck ducky) {
return specialDuck.quack();
}
}
HoarseDuckDecorator (Delete aeiou/This is where the NullPointerException occurs)
public class HoarseDuckDecorator extends DuckDecorator {
public HoarseDuckDecorator(Duck ducky) {
super(ducky);
}
public String quack() {
this.specialDuck.getQuackBehavior().setGeräusch(specialDuck.getQuackBehavior().quack().replaceAll("(?i)[aeiou]", "")); //NullPointerException
return specialDuck.quack();
}
}
ChattyDuckDecorator(Multiply the String)
public class ChattyDuckDecorator extends DuckDecorator {
public ChattyDuckDecorator(Duck ducky) {
super(ducky);
}
public String quack() {
specialDuck.getQuackBehavior().setGeräusch(specialDuck.getQuackBehavior().quack() + specialDuck.getQuackBehavior().quack());
return specialDuck.quack();
}
}