Observer with full transparency - java

I'm implementing observer pattern in the following way:
interface Layer{
void adjustString(Set<String> strings);
}
interface NotifiableLayer extends Layer{
void layerAdjusted(Layer layer);
}
abstract class ObservableLayer implements Layer{
Set<NotifiableLayer> observers = new HashSet<>();
void addObserver(NotifiableLayer layer){
observers.add(layer);
}
void removeObserver(NotifiableLayer layer){
observers.remove(layer);
}
void notifyObservers(){
observers.forEach(l -> l.layerAdjusted(this));
}
}
class MyLayer extends ObservableLayer{
#Override
public void adjustString(Set<String> strings) {
this.notifyObservers(); //can this be auto?
}
}
And this works of course, but whoever is implementing ObservableLayer needs to remember to call this.notifyObservers() in the adjustString method. This is not that of a big deal, but I wanted to see if there is a way to completely hide this.
So far, I only have this idea (using template method):
abstract class ObservableLayer implements Layer{
//...methods removed for simplicity
#Override
public void adjustString(Set<String> strings) {
this.doAdjustString(strings);
this.notifyObservers(); //<---- here is auto
}
abstract void doAdjustString(Set<String> strings);
}
class MyLayer extends ObservableLayer{
#Override
public void doAdjustString(Set<String> strings) {
//now notification is in base adjustString
}
}
but here I don't like that method name changed to doAdjustString, and it is not anymore uniform between other layer implementations (layers that directly implement Layer interface).
Is there any easy way to have this functionallity, but to keep public void adjustString(Set<String> strings) signature in MyLayer class?

One way would be to use a Decorator instance that holds an ObservableLayer instance and delegates to it.
final class LayerDecorator implements Layer {
final private ObservableLayer delegate;
public LayerDecorator(ObservableLayer delegate) {
this.delegate = delegate;
}
#Override
public void adjustString(Set<String> strings) {
delegate.adjustString(strings);
delegate.notifyObservers();
}
}
This assumes that calling code is working using references to Layer instead of ObservableLayer.
If calling code has to work using references to ObservableLayer then maybe it is better to refactor ObservableLayer to be an interface having the methods to register listeners, remove them and notify them. This interface also extends the Layer interface.
interface IObservableLayer extends Layer {
void addObserver(NotifiableLayer layer);
void removeObserver(NotifiableLayer layer);
void notifyObservers();
}
The abstract class ObservableLayer changes to implement IObservableLayer instead of Layer directly. This class remains public to support application classes to define variations of observable layers.
Next an internal decorator for observable layers can be defined as shown below.
final class ObservableLayerDecorator implements IObservableLayer {
final private ObservableLayer delegate;
public ObservableLayerDecorator(ObservableLayer delegate) {
this.delegate = delegate;
}
#Override
public void addObserver(NotifiableLayer layer) {
delegate.addObserver(layer);
}
#Override
public void removeObserver(NotifiableLayer layer) {
delegate.removeObserver(layer);
}
#Override
public void notifyObservers() {
delegate.notifyObservers();
}
#Override
public void adjustString(Set<String> strings) {
delegate.adjustString(strings);
this.notifyObservers();
}
}
Please note how the notification is done in this case.
Now instances of IObservableLayer can be created as
IObservableLayer observableLayer = new ObservableLayerDecorator(new MyClass());
Factory methods will be helpful here as they can be defined to handle creation of various application-level observable layer classes so that the instances can be created consistently that return an IObservableLayer which is decorated. That will free up developers from knowing how to use the decorator and allow the decorator to be an internal utility.

Another approach is aspect-oriented programming.
The following example uses AspectJ to intercept any public method execution on a class extending Observable, and invoke notifyObservers() on the same object.
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
#Aspect
public class EventAspect {
#AfterReturning("execution(public * Observable.*(..)) && target(observable)")
public void notifyObservers(Observable observable) {
observable.notifyObservers();
}
}

Related

Java: How can I design this class for having optional generics ParameterType?

I have this class in my code
public abstract class MyAbstractEventListener<E extends IMyEvent> {
public abstract void handleEvent(E e);
}
and I can make instances in this way (let's call it A):
new MyAbstractEventListener<IMyEvent>() {
#Override
public void handleEvent(final IMyEvent e) {
// Method implementation
}
};
But for my purposes, it would be ideal being able also to do this as well when there's no required event info (let's call this B):
new MyAbstractEventListener() { // Or receiving some unused parameter
#Override
public void handleEvent() {
// Method implementation
}
};
without having the warning about the class being raw and reccomending to parameterize it.
To clarify, I want the class to allow either the A or B instantiation, having the personal choice of using the one I prefer each time. If there's some generics parameter, the method receiving the IMyEvent object and if not, the method without parameters.
An example of code using this class would be:
EventBus.getInstance().addEventListener("some.string", new
AbstractEventListener<IMyEvent>() {
#Override
public void handleEvent(final IMyEvent e) {
// Sometimes does use 'e', sometimes doesn't. That's the point
MyConfirmationWindow.showConfirmationWindow(MyWindowType.WARNING, "kk", "lll");
}
});
Is there a way? Any link or resource will be appreciated.
Well, you could make an abstract subclass :
public abstract class BlindListener extends MyAbstractEventListener<IMyEvent> {
public abstract void handleEvent();
#Override
public void handleEvent(IMyEvent iMyEvent) {
handleEvent(); // delegate to abstract method that ignores the argument
}
}
This is actually a class that uses generics, but clients won't ever have to deal with them :
new BlindListener() {
#Override
public void handleEvent() {
}
}
Instances that do need a specific type can still use the MyAbstractEventListener directly
I don't think you will be able to avoid having tow handleEvent methods the way you described here.
But here is another approach using Null Object design pattern and single handleEvent method:
new MyAbstractEventListener<IMyEvent>() {
#Override
public void handleEvent(final IMyEvent e) {
// Method implementation
}
};
new MyAbstractEventListener<NullIMyEvent>() {
#Override
public void handleEvent(final NullIMyEvent e) {
// Method implementation
}
};
public interface IMyEvent{}
public class NullIMyEvent implements IMyEvent{}
public static abstract class MyAbstractEventListener<E extends IMyEvent> {
public abstract void handleEvent(E e);
}
public abstract class MyAbstractEventListener<E extends IMyEvent> {
But for my purposes, it would be ideal being able also to do this as well when there's no required event info (let's call this B):
The question is: what does the class MyAbstractEventListener do with the information that the parameter type E extends IMyEvent? Is there any method in that class working on type IMyEvent?
If not you could simple remove extends IMyEvent to achieve your goal.
Otherwise you need a different class since MyAbstractEventListener relies on type Eextending (or implementing) IMyEvent.

Practical use of composition and interface together in Java?

I am having a difficulty in understanding how to use composition and interface together to favor composition instead of inheritance? An example could be:
Interface:
public interface IMachine {
void TurnOn();
void TurnOff();
}
Machine Class is the parent Class of Printer Class
public class Machine {
protected boolean isOn;
public Machine(boolean isOn) {
this.isOn = isOn;
}
public void TurnOn() {
isOn = true;
System.out.println("Machine is on !");
}
public void TurnOff() {
isOn = false;
}
}
Now if I create a Printer Class which implements IMachine interface, it will implement the methods of the IMachine interface. But let's say I create a Clock Class that implements IMachine interface, then I have to implement those methods again.Is there a more efficient way where we use composition and interface and delegate the methods to Machine class?
With inheritance, you'd have a base class with shared logic, and subclasses using that shared logic. Any public method of that base class is shared API.
With composition, the interface defines the shared API, each implementing class (those that were subclasses before) will delegate those call to a composite class that actually has the shared logic.
Inheritance
public abstract class Machine {
public void turnOn() {/*logic here*/}
public void turnOff() {/*logic here*/}
}
public final class Heater extends Machine {
// heater methods here
}
Composition
public interface Machine {
void turnOn();
void turnOff();
}
final class MachineImpl {
public void turnOn() {/*logic here*/}
public void turnOff() {/*logic here*/}
}
public final class Heater implements Machine {
private MachineImpl impl = new MachineImpl();
#Override public void turnOn() { this.impl.turnOn(); }
#Override public void turnOff() { this.impl.turnOff(); }
// heater methods here
}
Users of Machine will still see the same public API, and users of Heater will still see the same public API, but the logic has been relocated.
This allows Heater to implement multiple independent "features", something that wasn't possible when using inheritance.
Composition is generally referred to in a "has a" relationship. In this case, composition could be used if you had the concept of a PowerSwitch object, for instance. This would be fulfilled in the notice that a Machine "has a" PowerSwitch.
Inheritance is more often referred to as an "is a" relationship, as in your Printer "is a" Machine case.
Using a PowerSwitch object, you could encompass the functionality for both a Printer and a Clock, possibly in an AbstractMachine
public abstract class AbstractMachine implements IMachine {
private PowerSwitch machinePowerSwitch;
public void turnOff() {
machinePowerSwitch.turnOff();
}
public void turnOn() {
machinePowerSwitch.turnOn();
}
public void isOn() {
return machinePowerSwitch.getPowerState();
}
}
Or something similar to that. Printer and Clock could then both extend AbstractMachine.
EDIT: Re-reading the question I see you want composition INSTEAD OF inheritance (I was reading it as you were wanting to use both). In that case, simply use the powerswitch directly in the Printer/Clock classes.

Checking `instanceof` while iterating through a loop

I have class structure where
public abstract class AbstractBuilding implements some non-relevant
interfaces for this question.
public abstract class AbstractAnimalBuilding extends AbstractBuiling
And small number of classes following this structure:
public class AnimalBuildingA extends AbstractAnimalBuilding
public class AnimalBuildingB extends AbstractAnimalBuilding
public class AnimalBuildingC extends AbstractAnimalBuilding
public class AnimalBuildingD extends AbstractAnimalBuilding
In a totally separate class I have the following method:
#FXML
private Button btnAnimalBuildingA;
#FXML
private Button btnAnimalBuildingB;
#FXML
private Button btnAnimalBuildingC;
#FXML
private Button btnAnimalBuildingD;
for (AbstractAnimalBuilding animalBuilding: animalBuildings){
if (animalBuilding instanceof AnimalBuildingA) {
changeButtonDisplay(btnAnimalBuildingA)
} else if (animalBuilding instanceof AnimalBuildingB){
changeButtonDisplay(btnAnimalBuildingB)
} else if (animalBuilding instanceof AnimalBuildingC) {
changeButtonDisplay(btnAnimalBuildingC)
} else if (animalBuilding instanceof AnimalBuildingD){
changeButtonDisplay(btnAnimalBuildingD)
//Do something specific here
}
}
private void changeButtonDisplay(Button buttonToChange){
button.setVisible(true);
}
Where animalBuildings is a Set<AbstractAnimalBuilding> containing any combination of AnimalBuildingX's.
Assuming the structure at the top needs to be kept (eg, AnimalBuildingX HAS to extend AbstractAnimalBuilding), what would be a better approach than the multiple if-then-else statements in determining what kind of building animalBuilding is?
Would it feasible to simply create a new Interface as outlined in this question and have each AnimalBuildingX implement it while still extending AbstractAnimalBuilding or is there a way I can do it using the structure I currently have.
This is difficult to answer in general without more context.
One possibility is to create an abstract method in AbstractBuilding and implement it differently in the subclasses.
Another possibility is to use the visitor pattern.
It depends on the action you want to take on behalf of the derived class type. If an action has to be taken which can be perfomed without the need, that the calling class knows the concrete implementation of AnimalBuilding the interface method is appropriate. This usually is the case if you can find a common method description which is implemented differently for each concrete class (e.g. getName()).
If you need to do specific actions dependent on the concrete class (e.g. AnimalBuildingA differs from AnimalBuldingB), you can implement the visitor pattern:
public abstract class AbstractAnimalBuilding {
...
public abstract void accept(AnimalBuildingVisitor v);
}
public interface class AnimalBuildingVisitor<T> {
public T visit(AnimalBuildingA a);
public T visit(AnimalBuildingB b);
...
}
The implementation of the accept-method usually is the one liner
return v.visit(this);
Then you create an implementation of the Abstract visitor which does the work you want to perform in the loop. The loop then looks like this
ConcreteAnimalBuildingVisitor v;
for (AbstractAnimalBuilding animalBuilding: animalBuildings)
animalBuilding.accept(v);
This way, the concrete class "identifies" itself to the concrete visior which then can perform the appropriate action.
You can keep your current structure and achieve what you desire by using generics:
First we need to define a generic handler interface:
public interface AnimalBuildingHandler<T extends AbstractAnimalBuilding> {
void handle(T type);
}
And then, in your own custom class, we can implement specific function for each types:
/* Here you can define all */
public void handleAnimalBuildingA(AnimalBuildingA animalBuildingA) {
/**
* Implement your custom handling here
*/
System.out.println("Handling AnimalBuildingA" + animalBuildingA);
}
public void handleAnimalBuildingB(AnimalBuildingB animalBuildingB) {
/**
* Implement your custom handling here
*/
System.out.println("Handling AnimalBuildingA" + animalBuildingB);
}
And then, we can create a magic handler class that implements the above AnimalBuildingHandler interface by mapping handlers to types just like this:
private Map<Class<? extends AbstractAnimalBuilding>, AnimalBuildingHandler<? extends AbstractAnimalBuilding>> handlersMapping;
{ /* default instance initializer */
handlersMapping = new HashMap<>();
handlersMapping.put(AnimalBuildingA.class, new AnimalBuildingHandler<AnimalBuildingA>() {
#Override
public void handle(AnimalBuildingA type) {
handleAnimalBuildingA(type);
}
});
handlersMapping.put(AnimalBuildingB.class, new AnimalBuildingHandler<AnimalBuildingB>() {
#Override
public void handle(AnimalBuildingB type) {
handleAnimalBuildingB(type);
}
});
}
#Override
public void handle(AbstractAnimalBuilding type) {
AnimalBuildingHandler abh = handlersMapping.get(type.getClass());
abh.handle(type);
}
And finally, the test method:
public <T extends AbstractAnimalBuilding> void test() {
List<T> allAnimalBuildings = new ArrayList<>();
allAnimalBuildings.add((T) new AnimalBuildingA());
allAnimalBuildings.add((T) new AnimalBuildingB());
for (AbstractAnimalBuilding aab : allAnimalBuildings) {
handle(aab);
}
}

Prevent abstract implementation from overriding certain method

I have an interface called Worker which I want to expose so that the end-user can simply call:
Worker w = WorkerFactory.createInstance();
w.mainBit();
How can I prevent classes which extend my AbstractWorker class from providing their own implementation of the mainBit method?
This is the structure I have so far:
interface Worker {
void mainBit();
}
class WorkerFactory {
public static Worker createInstance() {
return new WorkerImpl();
}
}
abstract class AbstractWorker implements Worker {
#Override
public void mainBit() {
this.doThing1();
this.doThing2();
}
public abstract void doThing1();
public abstract void doThing2();
}
class WorkerImpl extends AbstractWorker {
#Override
public void doThing1() {
}
#Override
public void doThing2() {
}
#Override
public void mainBit() {
// I don't want classes to override this functionality
}
}
You can do that by making the method final.
Use the final keyword.
public final void mainbit ()
...
Mark the method as final, which prevents overriding:
public final void mainBit()
If you want to always use the AbstractWorker's mainBit, make it final in this class. This way, the subclasses won't override it.
Mark it final inside you abstract class (in Java). No other subclass will be allowed to override it.

How to set up different parameter in a Composite Pattern?

for my develop i want to use the component-pattern because a component is part of another component.
But there is one problem. The components need different parameters in the run-function (which must be implement).
Does someone have a idea how to realize it?
Example:
public abstract class componsite{
Componente(){...}
public void run(Object object1){......}
}
public class firstComponent extends composite{
....
public void run(Object object1){......}
#Override
}
public class secondComponent extends composite{
....
#Override
public void run(Object object1,Different Object object2){......}
}
Greetz
Use Java's Varargs as part of the Composite interface
public class secondComponent extends composite{
....
#Override
public void run(Object... object){......}
}
Consider using the Visitor pattern. This allows for an elegant strongly typed solution that avoids type checking using instanceof or downcasting.
public interface ComponentVisitor {
void visitFirstComponent(FirstComponent fc);
void visitSecondComponent(SecondComponent sc);
}
public class ComponentVisitorImpl implements ComponentVisitor {
public void visitFirstComponent(FirstComponent fc) {
fc.firstComponentSpecifiedMethod(a, b, c);
// Make a call *back* to FirstComponent passing in appropriate parameters.
}
}
Then within each Component's run() method you simply call the relevant visitor method which will then make a call back into the component with the relevant parameters; e.g.
public class FirstComponent extends Component {
public void run(ComponentVisitor cv) {
cv.visitFirstComponent(this);
}
}
The drawback of this approach is that the logic can be difficult to follow.

Categories