here's a programming style question about the best strategy to map input keys to actions in a class that implement the state pattern.
I'm dealing with two classes:
The first implements the state pattern, which controls a multi-state physical device:
class DeviceController {
State _a, _b, _current;
// Actions that may prompt a transition from one state to another
public void actionA() { ... }
public void actionB() { ... }
public void actionC() { ... }
public State getStateA() { ... }
public State getStateB() { ... }
public void setCurrentState() { ... }
};
The second is a KeyListener that retrieves all keyboard input and calls the appropriate action from the device controller when a pressed input key matches a (for the time being) hard-coded bindings table:
class KeyDemo implements KeyListener {
DeviceController _controller;
...
#Override
public void keyPressed(KeyEvent arg0) {
char key = Character.toUpperCase(arg0.getKeyChar());
switch (key) {
case 'A':
_controller.actionA();
break;
case 'B' :
...
}
...
}
Is there a best-practice coding style to bind the keys to the actions in the controller ? Do I have to go through a switch statement, as in the sample code ? It seems to me that this solution is somewhat dirty code: isn't the state pattern supposed to eliminate unmaintanable if and switch control structures ?
Thank you for your suggenstions.
Using polymorphism you can achive your goal. I've used enum but maybe it would be more appropriated to use interfaces or an abstract class and then implement each of the key processors. What do you think?
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
enum KeyProcessor {
A {
void executeAction() {
_controller.actionA();
}
},
B {
void executeAction() {
_controller.actionB();
}
};
private static final DeviceController _controller = new DeviceController();
void executeAction() {
System.out.println("no action defined");
}
}
class DeviceController {
State _a;
State _b;
State _current;
// Actions that may prompt a transition from one state to another
public void actionA() {
System.out.println("action A performed.");
}
public void actionB() {
System.out.println("action B performed.");
}
public void actionC() {
}
public State getStateA() {
return null;
}
public State getStateB() {
return null;
}
public void setCurrentState() {
}
} // end class DeviceController
public class KeyDemo implements KeyListener {
DeviceController _controller;
// ...
#Override
public void keyPressed(KeyEvent arg0) {
keyPressed(Character.toUpperCase(arg0.getKeyChar()));
// ...
}
public void keyPressed(char c) {
KeyProcessor processor = KeyProcessor.valueOf(c + "");
if (processor != null) {
processor.executeAction();
}
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
}
public static final void main(String[] args) {
KeyDemo main = new KeyDemo();
main.keyPressed('A');
main.keyPressed('B');
}
} // end class KeyDemo
class State {
}
Related
I have 2 enums and 2 interfaces that I am trying to create in a specific way. The goal is to form a hierarchy where I can declare a list of methods that belong to one enum and a differnent list of values that belong to the combination of both enums.
For example: the methods declared within LevelOneOperations should belong to LevelOne only. Then methods declared witin LevelTwoOperations should belong to the combination of both together like A.1, A.2, A.3, etc.
public enum LevelOne implements LevelOneOperations {
A {
public boolean isValid(Request obj){ // logic }
public void prepare(Request obj){ // logic }
},
B {
public boolean isValid(Request obj){ // logic }
public void prepare(Request obj){ // logic }
} ...
}
public enum LevelTwo implements LevelTwoOperations {
1 {
public void process(LevelOne lev1, Request obj){
switch(lev1){
case A: // do something
case B: // do something else
case C: // do something else
case D: // do the last thing
}
}
},
2 {
public void process(LevelOne lev1, Request obj){ // logic }
} ...
}
public interface LevelOneOperations {
public boolean isValid(Request obj);
public void prepare(Request obj);
}
public interface LevelTwoOperations {
public void process(LevelOne lev1, Request obj);
}
public class myService {
public void runProcess(Request obj){
LevelOne l1 = LevelOne.valueOf(obj.getLevel1());
LevelTwo l2 = LevelTwo.valueOf(obj.getLevel2());
if(l1.isValid()){
l1.prepare();
l2.process(l1, obj);
}
}
}
Is there a way I can create an enum hierarchy so that I don't need to use switch statements to control the flow of the application. I want to call the process like: LevelOne.LevelTwo.process(obj);
I need methods that apply to LevelOne for all types and some methods that apply to LevelOne.LevelTwo together so that I have a grouped enum like : A.1, A.2, A.3, B.1, B.2, B.3, C.1, C.2, C.3, D.1, D.2, D.3, etc. I am also trying to make it easy to expand upon in the future because these lists are only subsets of what we are expecting for this project.
Tomorrow if I want to add a new LevelOne like E or a new LevelTwo 4 then it shouldn't require a lot of rework to introduce and support a new constant like that. The internal business logic between each element is different. Even between sub levels like: A.1 and A.2 will be different because both enumerators are taken into consideration and effect the output of the process.
The only way that I can think of to implement any thing like this is through switch/case statements. Can you please let me know if there is another way that I can achieve this?
I don't want separate classes for each variation because it will be a lot of different service classes and this is for only one part of my application. Currently I would have 5 elements in my first enumerator and 2 elements in my second enumerator for a total of 10 combinations.
You can use the Visitor pattern for this.
If you add a new enum to either of them, you're forced to implement all the new methods before the code will compile, unlike with a switch where you won't get compilation error if you miss one.
interface VerbAction {
void run();
void walk();
void jump();
}
enum Verb {
Run { #Override void perform(VerbAction action) { action.run(); } },
Walk { #Override void perform(VerbAction action) { action.walk(); } },
Jump { #Override void perform(VerbAction action) { action.jump(); } };
abstract void perform(VerbAction action);
}
enum Noun {
Dog {
#Override
void perform(Verb verb) {
verb.perform(new VerbAction() {
#Override
public void run() {
// Running dog
}
#Override
public void walk() {
// Walking dog
}
#Override
public void jump() {
// Jumping dog
}
});
}
},
Cat {
#Override
void perform(Verb verb) {
verb.perform(new VerbAction() {
#Override
public void run() {
// Running cat
}
#Override
public void walk() {
// Walking cat
}
#Override
public void jump() {
// Jumping cat
}
});
}
},
Pony {
#Override
void perform(Verb verb) {
verb.perform(new VerbAction() {
#Override
public void run() {
// Running pony
}
#Override
public void walk() {
// Walking pony
}
#Override
public void jump() {
// Jumping pony
}
});
}
};
abstract void perform(Verb verb);
}
I'm using a multiplayer Game Client that's called AppWarp (http://appwarp.shephertz.com), where you can add event listeners to be called back when event's happen, let's assume we'll be talking about the Connection Listener, where you need to implement this interface:
public interface ConnectionRequestListener {
void onConnectDone(ConnectEvent var1);
void onDisconnectDone(ConnectEvent var1);
void onInitUDPDone(byte var1);
}
My goal here is to mainly create a Reactive version of this client to be used in my Apps Internally instead of using the Client itself directly (I'll also rely on interfaces later instead of just depending on the WarpClient itself as in the example, but that's not the important point, please read my question at the very end).
So what I did is as follows:
1) I introduced a new event, named it RxConnectionEvent (Which mainly groups Connection-Related events) as follows:
public class RxConnectionEvent {
// This is the original connection event from the source client
private final ConnectEvent connectEvent;
// this is to identify if it was Connection / Disconnection
private final int eventType;
public RxConnectionEvent(ConnectEvent connectEvent, int eventType) {
this.connectEvent = connectEvent;
this.eventType = eventType;
}
public ConnectEvent getConnectEvent() {
return connectEvent;
}
public int getEventType() {
return eventType;
}
}
2) Created some event types as follows:
public class RxEventType {
// Connection Events
public final static int CONNECTION_CONNECTED = 20;
public final static int CONNECTION_DISCONNECTED = 30;
}
3) Created the following observable which emits my new RxConnectionEvent
import com.shephertz.app42.gaming.multiplayer.client.WarpClient;
import com.shephertz.app42.gaming.multiplayer.client.events.ConnectEvent;
import rx.Observable;
import rx.Subscriber;
import rx.functions.Action0;
import rx.subscriptions.Subscriptions;
public class ConnectionObservable extends BaseObservable<RxConnectionEvent> {
private ConnectionRequestListener connectionListener;
// This is going to be called from my ReactiveWarpClient (Factory) Later.
public static Observable<RxConnectionEvent> createConnectionListener(WarpClient warpClient) {
return Observable.create(new ConnectionObservable(warpClient));
}
private ConnectionObservable(WarpClient warpClient) {
super(warpClient);
}
#Override
public void call(final Subscriber<? super RxConnectionEvent> subscriber) {
subscriber.onStart();
connectionListener = new ConnectionRequestListener() {
#Override
public void onConnectDone(ConnectEvent connectEvent) {
super.onConnectDone(connectEvent);
callback(new RxConnectionEvent(connectEvent, RxEventType.CONNECTION_CONNECTED));
}
#Override
public void onDisconnectDone(ConnectEvent connectEvent) {
super.onDisconnectDone(connectEvent);
callback(new RxConnectionEvent(connectEvent, RxEventType.CONNECTION_DISCONNECTED));
}
// not interested in this method (for now)
#Override
public void onInitUDPDone(byte var1) { }
private void callback(RxConnectionEvent rxConnectionEvent)
{
if (!subscriber.isUnsubscribed()) {
subscriber.onNext(rxConnectionEvent);
} else {
warpClient.removeConnectionRequestListener(connectionListener);
}
}
};
warpClient.addConnectionRequestListener(connectionListener);
subscriber.add(Subscriptions.create(new Action0() {
#Override
public void call() {
onUnsubscribed(warpClient);
}
}));
}
#Override
protected void onUnsubscribed(WarpClient warpClient) {
warpClient.removeConnectionRequestListener(connectionListener);
}
}
4) and finally my BaseObservable looks like the following:
public abstract class BaseObservable<T> implements Observable.OnSubscribe<T> {
protected WarpClient warpClient;
protected BaseObservable (WarpClient warpClient)
{
this.warpClient = warpClient;
}
#Override
public abstract void call(Subscriber<? super T> subscriber);
protected abstract void onUnsubscribed(WarpClient warpClient);
}
My question is mainly: is my implementation above correct or should I instead create separate observable for each event, but if so, this client has more than 40-50 events do I have to create separate observable for each event?
I also use the code above as follows (used it in a simple "non-final" integration test):
public void testConnectDisconnect() {
connectionSubscription = reactiveWarpClient.createOnConnectObservable(client)
.subscribe(new Action1<RxConnectionEvent>() {
#Override
public void call(RxConnectionEvent rxEvent) {
assertEquals(WarpResponseResultCode.SUCCESS, rxEvent.getConnectEvent().getResult());
if (rxEvent.getEventType() == RxEventType.CONNECTION_CONNECTED) {
connectionStatus = connectionStatus | 0b0001;
client.disconnect();
} else {
connectionStatus = connectionStatus | 0b0010;
connectionSubscription.unsubscribe();
haltExecution = true;
}
}
}, new Action1<Throwable>() {
#Override
public void call(Throwable throwable) {
fail("Unexpected error: " + throwable.getMessage());
haltExecution = true;
}
});
client.connectWithUserName("test user");
waitForSomeTime();
assertEquals(0b0011, connectionStatus);
assertEquals(true, connectionSubscription.isUnsubscribed());
}
I suggest you avoid extending the BaseObservable directly since it's very error prone. Instead, try using the tools Rx itself gives you to create your observable.
The easiest solution is using a PublishSubject, which is both an Observable and a Subscriber. The listener simply needs to invoke the subject's onNext, and the subject will emit the event. Here's a simplified working example:
public class PublishSubjectWarpperDemo {
public interface ConnectionRequestListener {
void onConnectDone();
void onDisconnectDone();
void onInitUDPDone();
}
public static class RxConnectionEvent {
private int type;
public RxConnectionEvent(int type) {
this.type = type;
}
public int getType() {
return type;
}
public String toString() {
return "Event of Type " + type;
}
}
public static class SimpleCallbackWrapper {
private final PublishSubject<RxConnectionEvent> subject = PublishSubject.create();
public ConnectionRequestListener getListener() {
return new ConnectionRequestListener() {
#Override
public void onConnectDone() {
subject.onNext(new RxConnectionEvent(1));
}
#Override
public void onDisconnectDone() {
subject.onNext(new RxConnectionEvent(2));
}
#Override
public void onInitUDPDone() {
subject.onNext(new RxConnectionEvent(3));
}
};
}
public Observable<RxConnectionEvent> getObservable() {
return subject;
}
}
public static void main(String[] args) throws IOException {
SimpleCallbackWrapper myWrapper = new SimpleCallbackWrapper();
ConnectionRequestListener listner = myWrapper.getListener();// Get the listener and attach it to the game here.
myWrapper.getObservable().observeOn(Schedulers.newThread()).subscribe(event -> System.out.println(event));
listner.onConnectDone(); // Call the listener a few times, the observable should print the event
listner.onDisconnectDone();
listner.onInitUDPDone();
System.in.read(); // Wait for enter
}
}
A more complex solution would be to use one of the onSubscribe implementations to create an observable using Observable.create(). For example AsyncOnSubscibe. This solution has the benefit of handling backperssure properly, so your event subscriber doesn't become overwhelmed with events. But in your case, that sounds like an unlikely scenario, so the added complexity is probably not worth it.
I am trying to replicate my Java code in C# and I wish to know how can I replicate this Java functionality in C#.
Util.java
public class Util
{
public void function(String s, final SetAvailabilityStatusListener setStatusListener)
{
// ....
}
public static interface SetAvailabilityStatusListener {
public void setAvailabilityStatus(Status status);
}
}
Activity.java
public class Activity
{
public void anotherFunction()
{
util.function("name", new SetAvailabilityStatus()
{
#Override
public void setAvailabilityStatus(Status status) {
loginSetAvailabilityStatus(status);
}
}
}
}
Use delegates. They are used in C# instead of Java anonymous classes that implement interfaces.
public class Util
{
public void Function(String s, Action<Status> setStatusListener)
{
// ....
setStatusListener("myStatus");
}
}
public class Activity
{
private Util util = new Util();
public void AnotherFunction()
{
util.Function("name", status => LoginSetAvailabilityStatus(status));
}
public void LoginSetAvailabilityStatus(string status){
//do something with status
}
}
I was unable to find suitable duplicate, so:
1. C# does not have anonymous classes like Java does, but no one stops you from creating needed listener classes manually
public class Util
{
public void Function(String s, ISetAvailabilityStatusListener setStatusListener)
{
// ....
}
public interface ISetAvailabilityStatusListener {
public void SetAvailabilityStatus(Status status);
}
}
public class Activity
{
private class MySetAvailabilityStatusListener: Util.ISetAvailabilityStatusListener
{
public void SetAvailabilityStatus(Status status)
{
// do your handling, but nested classes have some differences with anonymous Java classes, so it may require additional infrastructure.
}
}
public void AnotherFunction()
{
utilObj.Function("name",
new MySetAvailabilityStatusListener())
}
}
It is so-called observer design pattern (just without unregistration method!!).
2. As it has been already suggested by #AndreySarafanov you can use Action Delegates and lambda expressions:
public class Util
{
public void Function(String s, Action<Status> statusChangeListener)
{
// ....
}
}
public class Activity
{
public void AnotherFunction()
{
utilObj.Function("name",
(status) =>
{
loginSetAvailabilityStatus(status);
}
}
}
3. C# has another more simple mechanism to deal with event-handling(subsrciption) mechanics - events and delegates
public class StatusEventArgs : EventArgs
{
//...
}
public class Util
{
public void SomeFunction()
{
// ....
if (this.OnAvailabilityChanged != null)
OnAvailabilityChanged(this, new StatusEventArgs(status));
}
public event EventHandler<StatusEventArgs> OnAvailabilityChanged
}
public class Activity
{
public void AvailabilityStatusChangedHandler(object sender, EventArgs<Status> eventArgs)
{
}
public void AnotherFunction()
{
utilObj.OnAvailabilityChanged += this.AvailabilityStatusChangedHandler;
}
}
It does not allow you to associate the name property with event handler, well, you can overcome it with special registration method, but it will reduce the usability of events, so you should probably stick with another solution.
So I tried to make a subscription model with generics.. it looked nice, but now I'm running into some issues.
Receiver
public interface Receiver<E> {
public void receive(E event);
}
Subscription registry
public class ClientRegistry<T> {
private Set<Receiver<T>> clients = new HashSet<Receiver<T>>();
public void subscribe(Receiver<T> client) {
clients.add(client);
}
public void unsubscribe(Receiver<T> client) {
clients.remove(client);
}
public void broadcast(T eventObject) {
for(Receiver<T> client: clients) {
client.receive(eventObject);
}
}
}
Sounds good so far, eh?
Now the problems come:
public class Screen implements Receiver<KeyEvent>, Receiver<MouseMoveEvent> {
#Override
public void receive(KeyEvent event)
{
// work
}
#Override
public void receive(MouseMoveEvent event)
{
// work
}
}
Now this is invalid syntax:
The interface Receiver cannot be implemented more than once
with different arguments: Receiver<MouseMoveEvent> and Receiver<KeyEvent>
How can I alter my system to keep it as generic as possible, but make it work?
Don't make the Screen class itself implement the two Receiver interfaces. Instead, use composition:
public class Screen {
private Receiver<KeyEvent> keyReceiver = new Receiver<KeyEvent>() {
...
};
private Receiver<MouseEvent> mouseReceiver = new Receiver<MouseEvent>() {
...
};
}
I would reverse the order, and use a Visitor Pattern:
import java.util.*;
interface Event{
void receive(Receiver receiver);
}
class KeyEvent implements Event{
#Override
public void receive(Receiver receiver){
receiver.receive(this);
}
}
class MouseEvent implements Event {
#Override
public void receive(Receiver receiver){
receiver.receive(this);
}
}
interface Receiver {
void receive(KeyEvent event);
void receive(MouseEvent event);
}
class ClientRegistry {
private Set<Receiver> clients = new HashSet<Receiver>();
public void subscribe(Receiver client) {
clients.add(client);
}
public void unsubscribe(Receiver client) {
clients.remove(client);
}
public void broadcast(Event eventObject) {
for(Receiver client: clients) {
eventObject.receive(client);
}
}
}
public class Screen implements Receiver {
public void receive(KeyEvent event) {
//work
System.out.println("Processing key event");
}
public void receive(MouseEvent event) {
//work
System.out.println("Processing mouse event");
}
public static void main(String[] args){
ClientRegistry registry = new ClientRegistry();
registry.subscribe(new Screen());
registry.broadcast(new MouseEvent());
}
}
There is not way to generify the Receiver interface, but it is indeed type safe and as you can see, I reverse the order, since now it is the event the one which chooses the receiver and not otherwise.
Suppose I have a class hierarchy in Java:
interface Item { ... };
class MusicBox implements Item { ... };
class TypeWriter implements Item { ... };
class SoccerBall implements Item { ... };
and I have another class in the same package:
class SpecialItemProcessor {
public void add(Item item)
{
/* X */
}
}
where I want to do something different for each item type, but I don't want to define that action in the different Item classes (MusicBox, TypeWriter, SoccerBall).
One way to handle this is:
class SpecialItemProcessor {
public void add(Item item)
{
if (item instanceof MusicBox)
{
MusicBox musicbox = (MusicBox)item;
... do something ...
}
else if (item instanceof MusicBox)
{
TypeWriter typewriter = (TypeWriter)item;
... do something ...
}
else if (item instanceof SoccerBall)
{
SoccerBall soccerball = (SoccerBall)item;
... do something ...
}
else
{
... do something by default ...
}
}
}
This works but it seems really clunky. Is there a better way to do this, when I know of special cases? (obviously if Item contains a method doSomethingSpecial then I can just call that item's method without caring what type it is, but if I don't want that differentiation to occur within the item itself how do I deal with it?)
In Java you can do multiple dispatch with a visitor(-like) pattern. The Item implementations don't need to contain the processing logic, they just need an accept() type of method.
public interface Item {
/** stuff **/
void processMe(ItemProcessor processor);
}
public interface ItemProcessor {
void process(MusicBox box);
void process(SoccerBall ball);
//etc
}
public class MusicBox implements Item {
#Override
public void processMe(ItemProcessor processor) {
processor.process(this);
}
}
public class ItemAddingProcessor implements ItemProcessor {
public void add(Item item) {
item.processMe(this);
}
#Override
public void process(MusicBox box) {
//code for handling MusicBoxes
//what would have been inside if (item instanceof MusicBox) {}
}
//etc
}
I think I'm going to use the idea of inversion of control and the visitor pattern:
interface Item {
public void accept(Visitor visitor);
...
public interface Visitor {
public void visit(Item item);
}
}
class MusicBox implements Item {
public interface Visitor extends Item.Visitor {
public void visitMusicBox(MusicBox item);
}
...
#Override public accept(Item.Visitor visitor)
{
if (visitor instanceof MusicBox.Visitor)
{
((MusicBox.Visitor)visitor).visitMusicBox(this);
}
}
}
class TypeWriter implements Item {
public interface Visitor extends Item.Visitor {
public void visitTypeWriter(TypeWriter item);
}
...
#Override public accept(Item.Visitor visitor)
{
if (visitor instanceof TypeWriter.Visitor)
{
((TypeWriter.Visitor)visitor).visitTypeWriter(this);
}
}
}
class SoccerBall implements Item {
public interface Visitor extends Item.Visitorr {
public void visitSoccerBall(SoccerBall item);
}
...
#Override public accept(Item.Visitor visitor)
{
if (visitor instanceof SoccerBall.Visitor)
{
((SoccerBall.Visitor)visitor).visitSoccerBall(this);
}
}
}
and then do the following, which at least reduces the instanceof to one check per add() call:
class SpecialItemProcessor
implements
MusicBox.Visitor,
TypeWriter.Visitor,
SoccerBall.Visitor,
Item.Visitor
{
public void add(Item item)
{
item.accept(this);
}
#Override public void visitMusicBox(MusicBox item)
{
...
}
#Override public void visitTypeWriter(TypeWriter item)
{
...
}
#Override public void visitSoccerBall(SoccerBall item)
{
...
}
#Override public void visit(Item item)
{
/* not sure what if anything I should do here */
}
}
Why not define some callback function to Item interface?
public Interface Item {
void onCallBack();
}
Then in each class that implements Item, such as MusicBox, it should implement the callback function.
public class MusicBox {
#override
public void onCallBack() {
// business logic
...
...
}
}
Then you could create a dispatcher, which you name is "SpecialItemProcessor".
public SpecialItemProcessor {
private final Item _item;
public SpecialItemProcessor(Item item) {
_item = item;
}
public dispatch() {
_item.onCallBack()
}
}
And then, in the Client class which contains the SpecialItemProcessor could just call the method, like:
public void XXXX() {
....
SpecialItemProcessor specialItemProcessor = new SpecialItemProcessor(new MusicBox());
specialItemProcessor.dispatch();
....
}
Actually, in C++, this is Dynamic Binding. And this is why pure abstract class exists...
You could create a bridge pattern for Item, in which the other side were the associated processes to do when add() is called. You could also add a factory method to the mix.
class SpecialItemProcessor {
public void add(Item item)
{
Process p = Item.createCorrespondingProcessor( p );
p.doWhenAddin();
}
}
Hope this helps.