A friend and I have a discussion of how to implement an observer pattern with two packages.
Here is a fictional example: Package "Gaming" contains the class "Battlefield". Package "Players" contains "IPlayer" (and various implementations of this interface).
Now we want the battlefield to observe the player. For this reason we create an interface "IPlayerObserver" and "IOberservablePlayer". IPlayer inherits IOberservablePlayer.
In which package should we put "IPlayerObserver"?
// Package: Players
public interface IPlayer extends IOberservablePlayer {}
// Package: Gaming
public class Battlefield implements IPlayerObserver {}
// Which package?
public interface IPlayerObserver {
void notify(IPlayer player);
}
public interface IOberservablePlayer {
void addObserver(IPlayerObserver observer);
}
Thanks for all answers in advantage.
core
^ ^
| |
| player
| ^
| |
gaming
Player
-focused items with playerObservable
interface as I have done below and put it in the common "core" packagepackage com.yourname.player;
public interface Player extends Oberservable<PlayerObserver>
package com.yourname.gaming;
public class Battlefield implements PlayerObserver
package com.yourname.player;
public interface PlayerObserver {
void notify(Player player);
}
package com.yourname.core;
public interface Oberservable<T> {
void addObserver(T observer);
}
Further, it is slightly cleaner not to implement such listeners directly on other important classes as it exposes methods like Battlefield.notify(Player)
to everyone when only Player
is meant to call it.
Try doing this inside Battlefield
:
player.addObserver(this::playerNotification)
...
private void playerNotification(Player p) {}