Observer Pattern Class (JAVA) - java

I'm stuck on this assignment. I'm given an abstract Observer class with only 1 constructor in it, a constructor with parameters/arguments. (refer below)
public static void main(String[] args) {
PairOfNumbers numbers1 = new PairOfNumbers();
PairOfNumbers numbers2 = new PairOfNumbers();
SumObserver sum = new SumObserver(numbers1);
ProductObserver prod = new ProductObserver(numbers2);
MultiSubjectObserver m = new MultiSubjectObserver();
m.addSubject(numbers1);
m.addSubject(numbers2);
numbers1.setNumbers(20, 10);
numbers2.setNumbers(-10, 15);
}
class Subject {
private List<Observer> observers=new ArrayList<Observer>();
public void attachObserver(Observer observer) {
this.observers.add(observer);
}
public void detachObserver(Observer observer) {
this.observers.remove(observer);
}
public void notifyObservers() {
for (Observer observer: this.observers)
observer.update(this);
}
}
class PairOfNumbers extends Subject {
private double number1, number2;
public double getNumber1() { return this.number1; }
public double getNumber2() { return this.number2; }
public void setNumbers(double d1, double d2) {
this.number1=d1; this.number2=d2;
this.notifyObservers(); // don't forget to do this!
}
}
abstract class Observer {
public Observer(Subject subject) {
subject.attachObserver(this);
}
abstract public void update(Subject subject);
}
class SumObserver extends Observer {
public SumObserver(PairOfNumbers pair) {
super(pair);
}
public void update(Subject subject) {
PairOfNumbers numbers=(PairOfNumbers)subject;
System.out.println("New sum is: "+(numbers.getNumber1()+numbers.getNumber2()));
}
}
class ProductObserver extends Observer {
public ProductObserver(PairOfNumbers pair) {
super(pair);
}
public void update(Subject subject) {
PairOfNumbers numbers=(PairOfNumbers)subject;
System.out.println("New product is: "+(numbers.getNumber1()*numbers.getNumber2()));
}
}
Okay, now I'm suppose to create another class which inherits from the above class.
class MultiSubjectObserver extends Observer{
public MultiSubjectObserver(PairOfNumbers pair){
super(pair);
}
public void addSubject(PairOfNumbers pair){
pair.attachObserver(this);
}
public void update(Subject subject){
PairOfNumbers numbers=(PairOfNumbers)subject;
System.out.println("MultiSubjectObserver activated with numbers: " + (numbers.getNumber1())+", "+(numbers.getNumber2()));
}
}
Is there a way to create a constructor inside the MSO Class which requires no parameter/argument? For example
public MultiSubjectObserver(){
//enter code here
}
Please guide me on this one. Had been thinking for days. Thanks in advance! :D
The instruction is to: Modify the source code to handle any number of Subject objects per Observer.
Expected output:
New sum is: 30.0
MultiSubjectObserver activated with numbers: 20.0, 10.0
New product is: -150.0
MultiSubjectObserver activated with numbers: -10.0, 15.0

Yes you can do this, create a no-arg child class, but you still must call the arg-needing super constructor within the child constructor.
This:
class Child extends Super {
public Child() {
super(args_are_needed);
}
}
The tricky part would be -- what to pass into the super constructor in this default case? In your case this could be:
public MultiSubjectObserver(){
super(null);
}
Caveat: and this will lead to a NullPointerException when the super's constructor is called, due to the line, subject.attachObserver(this);, so no, you can't do this.
A better solution: make sure that MultiSubjectObserver does not extend from Observer!
Perhaps something like:
class MultiSubjectObserver {
private List<Observer> observerList = new ArrayList<Observer>();
public void addSubject(PairOfNumbers numbers1) {
observerList.add(new InnerObserver(numbers1));
}
private class InnerObserver extends Observer {
public InnerObserver(Subject subject) {
super(subject);
}
#Override
public void update(Subject subject) {
System.out.println("From multi-observer: " + subject);
}
}
}
But for this to work, you'd have to give PairOfNumbers a decent toString method, perhaps,
#Override
public String toString() {
return String.format("[%.4f, %.4f]", number1, number2);
}
Edit
Based on the output:
class MultiSubjectObserver {
private static final String FORMAT_STRING = "MultiSubjectObserver activated with numbers: %.1f, %.1f%n";
private List<Observer> observerList = new ArrayList<Observer>();
public void addSubject(PairOfNumbers numbers1) {
observerList.add(new InnerObserver(numbers1));
}
private class InnerObserver extends Observer {
public InnerObserver(Subject subject) {
super(subject);
}
#Override
public void update(Subject subject) {
System.out.printf(FORMAT_STRING, ((PairOfNumbers)subject).getNumber1(), ((PairOfNumbers)subject).getNumber1());
}
}
}
Although that casting is a bit skanky. I like the toString() version much better.

Related

How call subclass method by superclass object

I have 2 subclass extended from the same superclass, and 3 objects will be created and store into an array of the superclass. I am wondering how can I call a subclass method by a superclass object, I try to convert the data type from Ship to CruiseShip or CargoShip but it does not work. If anyone can help I will be appreciated that.
Here is the superclass:
public class Ship {
private String name;
private String year;
public Ship() {}
public Ship(String n,String y) {...}
public void setName() {...}
public void setYear() {...}
public void getName() {...}
public void getYear() {...}
}
These two subclass basically are there same.
public class CruiseShip extends Ship {
private int passenger;
public CruiseShip() {}
public CruiseShip() {...}
public void setPassenager() {...}
public int getPassenager() {...}
public Strting showInfo() {this.getName()...etc}
}
public class CargoShip extends Ship {
private int capacity;
public CargoShip() {}
public CargoShip() {...}
public void setCapacity() {...}
public int getCapacity() {...}
public Strting showInfo() {this.getName()...etc}
}
Here is the main method:
public class report {
public static void main(String[] args) {
Ship[] shipList new Ship[3];
for (int i=0;i<3;i++) {//using for loop to create 3 objects randomly and pass into array}
for (int i=0;i<3;i++) {
if (shipList[i] instanceof CruiseShip) {
((CruiseShip)shipList[i]).showInfo(); //This way is not work.
}
else {
((CargoShip)shipList[i]).showInfo(); //This way is not work.
}
Take a look at Polymorphisms and Late Bindig. Basically late binding says that the appropriate method to be executed is determined at runtime based on the actual type of the object. So
class Ship {
public String showInfo() {return "I'm a ship";}
}
class CruiseShip extends Ship {
public String showInfo() {return "I'm a cruiseShip";}
}
class CargoShip extends Ship {
public String showInfo() {return "I'm a cargoShip";}
}
class Main {
public static void main(String argv[]) {
Ship[] ships = new Ship[]{new Ship(), new CargoShip(), new CruiseShip()};
for (Ship ship: ships) {
System.out.println(ship.showInfo());
// I'm a ship
// I'm a cargoShip
// I'm a cruiseShip
}
}
}
I'm not sure about the question you are trying to ask,
but this may answer the question you did ask.
public abstract class Ship
{
public final boolean hoot()
{
return implementHoot();
}
protected abstract boolean implementHoot();
}
public class BlamShip
extends Ship
{
protected boolean implementHoot()
{
return true;
}
}
Subclass methods (overrides) are automatically called even if the reference is of type super-class. You don't have to do anything.

Observer pattern infinite loop

I have an situation when i have an Observer to be a also a subject.
So let's image with have two entites A and B.
When Changes occurs in A's Model other entites should know including B (C,D...Etc).
When Changes occurs in B's Model other entites should know including A (C,D...Etc).
By implmenting the Observer pattern in this way i get an infinite loop betteween A and B.
Is the observer pattren not implmented correctly or do i need another pattren to handle this kind of design ?
Any way her my implementation
public interface ISubject {
public void registreObserver(IObserver obs);
public void removeObserver(IObserver obs);
public void notifyObservers();
}
And the Observer Interface
public interface IObserver {
public void update(ISubject subject);
}
The Model
import java.util.ArrayList;
import java.util.List;
public class AModel implements ISubject {
private List<IObserver> listObservers = new ArrayList<>();
#Override
public void registreObserver(IObserver obs) {
listObservers.add(obs);
}
#Override
public void removeObserver(IObserver obs) {
listObservers.remove(obs);
}
public void loadData(){
notifyObservers();
}
#Override
public void notifyObservers() {
for (IObserver obv : listObservers) {
obv.update(AModel.this);
}
}
}
BModel
import java.util.ArrayList;
import java.util.List;
public class BModel implements ISubject {
private List<IObserver> listObservers = new ArrayList<>();
#Override
public void registreObserver(IObserver obs) {
listObservers.add(obs);
}
#Override
public void removeObserver(IObserver obs) {
listObservers.remove(obs);
}
public void loadData(){
notifyObservers();
}
#Override
public void notifyObservers() {
for (IObserver obv : listObservers) {
obv.update(BModel.this);
}
}
}
The A controller
public class AController implements IObserver {
private AModel model;
public void setModel(AModel model) {
this.model = model;
}
#Override
public void update(ISubject subject) {
System.out.println(" A Changed");
model.loadData();
}
}
The B controller
public class BController implements IObserver {
private BModel model;
public void setModel(BModel model) {
this.model = model;
}
#Override
public void update(ISubject subject) {
System.out.println(" B Changed");
model.loadData();
}
}
Main Program
public class Main {
public static void main(String[] args) {
AModel aModel = new AModel();
AModel bModel = new BModel();
AController aController = new AController();
aController.setModel(aModel);
AController bController = new BController();
bController.setModel(bModel);
aModel.registreObserver(bController);
bModel.registreObserver(aController);
// Here the updates starts a notify b and b notify a and so on
aModel.notifyObservers();
}
}
The reason why you are getting an infinite loop is because each time you update your Observable, you notify its observers, but this notifying process then updates the model again and so it repeats.
Here is an example of how to use the Observer pattern in the way you are looking for:
import java.util.Observable;
import java.util.Observer;
public class Example {
public static void main(String[] args) {
Model modelA = new Model();
Model modelB = new Model();
Observer aController = (observable, arg) -> {
System.out.println("A controller: " + arg);
};
Observer bController = (observable, arg) -> {
System.out.println("B controller: " + arg);
};
modelA.addObserver(bController);
modelB.addObserver(aController);
modelA.update("test");
modelB.update("test2");
}
}
class Model extends Observable {
private String data;
public void update(String data) {
this.data = data;
setChanged();
notifyObservers(data);
}
}
Output:
B controller: test
A controller: test2
Although #arizzle's answer works, I think you are misusing the Observer pattern.
Observer
Define a one-to-many dependency between objects so that when one object changes > state, all its dependents are notified and updated automatically.
Source
Your problem seems more like a many-to-many relationship. In this case, I'd recomend you to use the Mediator Pattern to hide this complexity.
This is the canonic UML Diagram for this pattern:
I'll skip the interface/abstract class definition here to avoid bloating the answer.
Basic implementation:
class Mediator {
private Map<String, Colleague> participants = new HashMap<String, Colleague>();
public void register(Colleague c) {
participants.put(c.getName(), c);
c.setMediator(this);
}
public void send(Colleague from, String message, String to) {
Colleague c = participants.get(to);
if (c != null && c != from) {
c.receive(message, from);
}
}
public void send(Colleague from, String message) {
for (Map.Entry<String, Colleague> e: participants.entrySet()) {}
Colleague c = e.getValue();
if (c != from)) {
c.receive(message, from);
}
}
}
}
abstract class Colleague {
private Mediator mediator;
private String name;
public Colleague(String name) {
this.name = name;
}
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
public void send(String msg, String to) {
this.mediator.send(this, msg, to);
}
public void send(String msg) {
this.mediator.send(this, msg);
}
abstract public void receive(String msg, Colleague from);
}
class ConcreteColleague1 {
public void receive(String msg, String from) {
// do something
System.out.println("Received msg: " + msg + " from: " + from.getName());
}
}
class ConcreteColleague2 {
public void receive(String msg, String from) {
// do other thing
System.out.println("Received msg: " + msg + " from: " + from.getName());
}
}
Using it:
Mediator m = new Mediator();
Colleague c1 = new ConcreteColleague1('foo');
Colleague c2 = new ConcreteColleague2('bar');
Colleague c3 = new ConcreteColleague1('baz');
c1.send("test");
c2.send("test");
c3.send("test");
Will print:
"Received msg: test from: foo"
"Received msg: test from: foo"
"Received msg: test from: bar"
"Received msg: test from: bar"
"Received msg: test from: baz"
"Received msg: test from: baz"
This way, when you broadcast a message, you can know for sure that everyone received it, so you don't need to make another broadcast for each colleague to communicate the new state.

Extending abstract classes

MyMath's constructor is supposed to call Homework's constructor, but super(); returns an error 'cannot find symbol'. It should not have any arguments.
Also, I am confused about how to call the method createAssignment using an arraylist, but I have to use it. Any advice?
Homework
public abstract class Homework {
private int pagesToRead;
private String typeHomework;
public Homework(int pages, String hw) {
// initialise instance variables
pagesToRead = 0;
typeHomework = "none";
}
public abstract void createAssignment(int p);
public int getPages() {
return pagesToRead;
}
public void setPagesToRead(int p) {
pagesToRead = p;
}
public String getTypeHomework() {
return typeHomework;
}
public void setTypeHomework(String hw) {
typeHomework = hw;
}
}
MyMath
public class MyMath extends Homework {
private int pagesRead;
private String typeHomework;
public MyMath() {
super();
}
public void createAssignment(int p) {
setTypeHomework("Math");
setPagesToRead(p);
}
public String toString() {
return typeHomework + " - " + pagesRead;
}
}
public class testHomework {
public static void main(String[] args) {
ArrayList<Homework> list = new ArrayList<Homework>();
list.add(new MyMath(1));
list.add(new MyJava(1));
for (Homework s : list) {
s.createAssignment();
}
}
}
Compiler error:
Regarding the compiler error, you have to change the MyMath constractor to somthing like:
public MyMath() {
super(someInt, someString);
}
Or, you can add a non-arg constructor to the Homework class:
public Homework() {
this(someInt,someString);
}
You can learn about the super() keyword in the Javadocs tutoriel:
If a constructor does not explicitly invoke a superclass constructor,
the Java compiler automatically inserts a call to the no-argument
constructor of the superclass. If the super class does not have a
no-argument constructor, you will get a compile-time error. Object
does have such a constructor, so if Object is the only superclass,
there is no problem.
Code Suggestion:
As there is many other issues in your question, i modified all your classes like below:
Homework.java:
public abstract class Homework {
private int pagesToRead;
private String typeHomework;
{
// initialise instance variables
pagesToRead = 0;
typeHomework = "none";
}
public Homework(int pages, String hw) {
this.pagesToRead = pages;
this.typeHomework = hw;
}
public abstract void createAssignment(int p);
public int getPages() {
return pagesToRead;
}
public void setPagesToRead(int p) {
pagesToRead = p;
}
public String getTypeHomework() {
return typeHomework;
}
public void setTypeHomework(String hw) {
typeHomework = hw;
}
}
MyMath.java
public class MyMath extends Homework {
private int pagesRead;
private String typeHomework;
public MyMath(int pages, String hw) {
super(pages,hw);
}
public void createAssignment(int p) {
setTypeHomework("Math");
setPagesToRead(p);
}
public String toString() {
return typeHomework + " - " + pagesRead;
}
}
TestHomework.java:
class TestHomework {
public static void main(String[] args) {
ArrayList<Homework> list = new ArrayList<Homework>();
// will create a homework with type Math and one page to read
list.add(new MyMath(1,"Math"));
// Assuming MyJava is similar to MyMath
list.add(new MyJava(1,"Java"));
for (Homework s : list) {
if (s instanceof MyMath) {
// modify the number of pages to read for the Math homework
s.createAssignment(3);
} else if (s instanceof MyJava) {
// modify the number of pages to read for the Java homework
s.createAssignment(5);
} else {
s.createAssignment(7);
}
}
}
}

How does Decorator pattern work in Java?

I was trying to understand Decorator Pattern. Below is the code am trying to understand how it works.
public static void main(String[] args)
{
Room myRoom = new CurtainDecorator(new ColorDecorator(new SimpleRoom()));
System.out.println(myRoom.showRoom());
}
Below is my Concrete Class
public class SimpleRoom implements Room{
#Override
public String showRoom()
{
return "show room";
}
}
Below is my abstract Decorator class
public abstract class RoomDecorator implements Room{
public Room roomReference;
#Override
public String showRoom()
{
return roomReference.showRoom();
}
}
Below is my Decorator implementation1
public class ColorDecorator extends RoomDecorator{
#Override
public String showRoom()
{
return addColors(); //How does showRoom() method gets invoked here?
}
public ColorDecorator(Room room)
{
this.roomReference = room;
}
public String addColors()
{
return "Blue";
}
}
Below is my Decorator implementation 2
public class CurtainDecorator extends RoomDecorator{
public CurtainDecorator(Room room)
{
this.roomReference = room;
}
#Override
public String showRoom()
{
return this.roomReference.showRoom() + addCurtains(); //What will showRoom method invoke?
}
public String addCurtains()
{
return "Curtain";
}
}
Output is - BlueCurtain
My question are placed in the comment..
In the end you have:
CurtainDecorator(ref=ColorDecorator(ref=SimpleRoom)))
When you call showRoom from main, it calls the method of CurtainDecorator, which in turn first goes to it's reference (ColorDecorator in this case) that outputs 'Blue', then CurtainDecorator adds it's bit 'Curtain'.

How to remove decorated object from Decorator Pattern in Java

I'm reading "Design Pattern for Dummies". I read and practiced Decorator Pattern. With Decorator Pattern, we can decorate an object with anything. Now, I want to remove decorated object before decorated.I have solved this problem by an ArrayList but I still feel it's not good. Can you tell me how to remove a decorated object? And what is a better way?
this is my way:
Computer.java
public class Computer {
public Computer() {
}
public String description() {
return "computer";
}
}
ComponentDecorator.java
public abstract class ComponentDecorator extends Computer {
#Override
public abstract String description();
}
CD.java
public class CD extends ComponentDecorator {
private Computer computer;
public CD() {
}
public CD(Computer computer) {
this.computer = computer;
}
#Override
public String description() {
return computer.description() + " and a CD";
}
}
Disk.java
public class Disk extends ComponentDecorator {
private Computer computer;
public Disk() {
}
public Disk(Computer c) {
computer = c;
}
#Override
public String description() {
return computer.description() + " and a disk";
}
}
Monitor.java
public class Monitor extends ComponentDecorator {
private Computer computer;
public Monitor() {
}
public Monitor(Computer computer) {
this.computer = computer;
}
#Override
public String description() {
return computer.description() + " and a monitor";
}
}
Main.java
import java.util.ArrayList;
import java.util.Arrays;
public class Main {
static ArrayList<ComponentDecorator> list = new ArrayList<>();
public static void main(String[] args) {
addComponent(new CD(), new Disk(), new Monitor());
System.out.println(list.size());
Computer penIII = getComputer();
removeComponent(new Monitor());
penIII = getComputer();
System.out.println(penIII.description());
}
private static void addComponent(ComponentDecorator... comp) {
list.addAll(Arrays.asList(comp));
}
private static void removeComponent(ComponentDecorator comp) {
for(ComponentDecorator c : list) {
if(c.getClass() == comp.getClass()) {
list.remove(list.indexOf(c));
break;
}
}
}
private static Computer getComputer() {
Computer c = new Computer();
Class e;
for(ComponentDecorator d : list) {
e = d.getClass();
try {
c = (Computer) e.getConstructor(new Class[]{Computer.class}).newInstance(c);
} catch(Exception ex) {
ex.printStackTrace();
}
}
return c;
}
}
A nicer way would be adding the "removeDecorator" method to your ComponentDecorator class.
public abstract class ComponentDecorator {
private ComponentDecorator subject;
public ComponentDecorator(ComponentDecorator subject) {
this.subject = subject;
}
#Override
public abstract String description();
}
public void removeDecorator(ComponentDecorator toRemove) {
if (subject == null) {
return;
} else if (subject.equals(toRemove)) {
subject = subject.getSubject();
} else {
subject.removeDecorator(toRemove);
}
}
public ComponentDecorator getSubject() {
return subject;
}
// Computer
public class Computer extends ComponentDecorator{
public Computer() {
super(null);
}
public String description() {
return "computer";
}
// CD
public class CD extends ComponentDecorator {
public CD(ComponentDecorator computer) {
super(computer);
}
#Override
public String description() {
return getSubject().description() + " and a CD";
}
}
// main
public static void main(String[] args) {
ComponentDecorator penIII = new Computer();
penIII = new CD(penIII);
penIII = new Monitor(penIII);
System.out.println(penIII.description());
}
}
If you don't have the reference of the decorator to remove, you can create another method that the a Class instead.
You'll need to the decorated object as "ComponentDecorator" instead of "Computer" however. I suggest to make the Computer class extends ComponentDecorator instead of the other way around.
I suspect I'm misunderstanding your question, but to get the decorated (inner) object out of the decorator, you can just add a get method to the decorators. Add
public abstract Computer getDecorated();
to ComponentDecorator and
public Computer getDecorated(){return computer;}
to each subclass (CD, Monitor, ...). Is that what you were looking for?
Add two methods to an interface, undecorate() and removeDecoration(String className):
ThingInterface.java
public interface ThingInterface {
public ThingInterface undecorate();
public ThingInterface removeDecoration(String className);
public String nonDecoratedString();
public String decoratedString();
}
Your base class will simply return itself for those methods:
BaseThing.java
public class BaseThing implements ThingInterface {
private String basicString;
public BaseThing(String string) {
basicString = string;
}
#Override
public ThingInterface undecorate() {
return this;
}
#Override
public ThingInterface removeDecoration(String className) {
return this;
}
#Override
public String nonDecoratedString() {
return basicString;
}
#Override
public String decoratedString() {
return basicString;
}
}
Now the real meat of what you need is in the abstract class:
AbstractThingDecorator.java
public abstract class AbstractThingDecorator implements ThingInterface {
private ThingInterface thing;
public AbstractThingDecorator(ThingInterface thing) {
this.thing = thing;
}
#Override
public ThingInterface removeDecoration(String className) {
ThingInterface undecorate = this;
if(this.getClass().getName() == className) {
undecorate = this.undecorate();
}
else {
ArrayList<String> classStack = new ArrayList();
while(undecorate != undecorate.undecorate()) {
if(undecorate.getClass().getName() != className) {
classStack.add(undecorate.getClass().getName());
}
undecorate = undecorate.undecorate();
}
for(int i = classStack.size()-1;i == 0;i--) {
try {
Class<?> clazz = Class.forName(classStack.get(i));
Constructor<?> ctor = clazz.getConstructor(ThingInterface.class);
Object object = ctor.newInstance(new Object[] { undecorate });
undecorate = (ThingInterface) object;
}
catch(Exception e) {
System.out.println("Exception:" + e.getMessage());
}
}
}
return undecorate;
}
#Override
public ThingInterface undecorate() {
return this.thing;
}
#Override
public String nonDecoratedString() {
return thing.nonDecoratedString();
}
#Override
public String decoratedString() {
return thing.decoratedString();
}
}
I'm adding two simple decorators, ThingDecorator and FancyThingDecorator:
ThingDecorator.java
public class ThingDecorator extends AbstractThingDecorator {
public ThingDecorator(ThingInterface thing) {
super(thing);
}
#Override
public ThingInterface undecorate() {
return super.undecorate();
}
#Override
public String decoratedString() {
return super.decoratedString() + ", decorated";
}
}
FancyThingDecorator.java
public class FancyThingDecorator extends AbstractThingDecorator {
public FancyThingDecorator(ThingInterface thing) {
super(thing);
}
#Override
public ThingInterface undecorate() {
return super.undecorate();
}
#Override
public String decoratedString() {
return super.decoratedString() + ", fancy";
}
}
Finally, my java main:
Decorator.java
public class Decorator {
/**
* #param args
*/
public static void main(String[] args) {
ThingInterface thing = new BaseThing("Basic string");
ThingInterface decorator = new ThingDecorator(thing);
ThingInterface fancyDecorator = new FancyThingDecorator(thing);
ThingInterface extraFancy = new FancyThingDecorator(new ThingDecorator(thing));
ThingInterface undecorate = new FancyThingDecorator(new ThingDecorator(thing));
System.out.println("Basic thing is: " + thing.decoratedString()+".");
System.out.println("Decorated thing is: " + decorator.decoratedString()+".");
System.out.println("Fancy thing is: " + fancyDecorator.decoratedString()+".");
System.out.println("Decorated fancy thing is: " + extraFancy.decoratedString()+".");
while(extraFancy.undecorate() != extraFancy) {
extraFancy = extraFancy.undecorate();
System.out.println("Rolling back decorations: " + extraFancy.decoratedString()+".");
}
System.out.println("Decoration chain before removal is: " + undecorate.decoratedString());
System.out.println("Removing decoration for " + ThingDecorator.class.getName());
undecorate = undecorate.removeDecoration(ThingDecorator.class.getName());
System.out.println("Decoration chain after removal is: " + undecorate.decoratedString()+".");
}
}
The output is:
Basic thing is: Basic string.
Decorated thing is: Basic string, decorated.
Fancy thing is: Basic string, fancy.
Decorated fancy thing is: Basic string, decorated, fancy.
Rolling back decorations: Basic string, decorated.
Rolling back decorations: Basic string.
Decoration chain before removal is: Basic string, decorated, fancy
Removing decoration for ThingDecorator
Decoration chain after removal is: Basic string, fancy.

Categories

Resources