| package scrapbook; | |
| import java.util.ArrayList; | |
| import java.util.HashMap; | |
| import java.util.List; | |
| import java.util.Map; | |
| /** | |
| * Interface that must be implemented by objects that subscribe to messages. | |
| */ | |
| interface Subscriber { | |
| public void receive(String name, Object senders_arg, Object subscribers_arg); | |
| } | |
| /** | |
| * The singleton that manages the messaging system. | |
| */ | |
| class Messager { | |
| // Singleton | |
| private Messager() {} | |
| public static final Messager INSTANCE = new Messager(); | |
| private static final class Subscription { | |
| private Subscriber subscriber; | |
| private Object subscribers_arg; | |
| Subscription(Subscriber subscriber, Object subscribers_arg) { | |
| this.subscriber = subscriber; | |
| this.subscribers_arg = subscribers_arg; | |
| } | |
| public Subscriber getSubscriber() { return subscriber; } | |
| public Object getArg() { return subscribers_arg; } | |
| } | |
| private Map<String, List<Subscription>> map = new HashMap<String, List<Subscription>>(); | |
| /** | |
| * Subscribe a Subscriber object to a message. | |
| */ | |
| public void subscribe(String name, Subscriber subscriber, Object subscribers_arg) { | |
| Subscription new_subscription = new Subscription(subscriber,subscribers_arg); | |
| if (map.containsKey(name)) { | |
| map.get(name).add(new_subscription); | |
| } else { | |
| List<Subscription> subscriptions = new ArrayList<Subscription>(); | |
| subscriptions.add(new_subscription); | |
| map.put(name,subscriptions); | |
| } | |
| } | |
| /** | |
| * Send a message. | |
| */ | |
| public void send(String name, Object senders_arg) { | |
| if (map.containsKey(name)) { | |
| List<Subscription> subscriptions = map.get(name); | |
| for (Subscription subscription : subscriptions) { | |
| Subscriber subscriber = subscription.getSubscriber(); | |
| Object subscribers_arg = subscription.getArg(); | |
| subscriber.receive(name,senders_arg,subscribers_arg); | |
| } | |
| } | |
| } | |
| } | |
| // A class that subscribes to the "foobar" message. | |
| class FooBar { | |
| // Construct a new FooBar instance and subscribe it to the "foobar" message. | |
| FooBar() { | |
| Messager.INSTANCE.subscribe("foobar", new FooBarReceiver(), "two"); | |
| } | |
| // Private inner class is used as a function-object to subscribe to the | |
| // message. | |
| private class FooBarReceiver implements Subscriber { | |
| // Function object calls a method of the outer class. | |
| public void receive(String name, Object senders_arg, Object subscribers_arg) { | |
| // FIXME: Use generics to get rid of these casts. | |
| print(name, (String)senders_arg, (String) subscribers_arg); | |
| } | |
| } | |
| // This method will be called whenever someone sends a "foobar" message. | |
| private void print(String name, String senders_arg, String subscribers_arg) { | |
| System.out.println("Message recevied by "+this); | |
| System.out.println("name: "+name); | |
| System.out.println("senders_arg: "+senders_arg); | |
| System.out.println("subscribers_arg: "+subscribers_arg); | |
| } | |
| } | |
| class Main { | |
| public static void main(String[] args) { | |
| FooBar f = new FooBar(); | |
| // When we do this our FooBar instance print out "Hello foobar". | |
| System.out.println("Sending foobar"); | |
| Messager.INSTANCE.send("foobar","one"); | |
| // When we do this nothing will happen, because no objects are | |
| // subscribed to the barfoo message. | |
| System.out.println("Sending barfoo"); | |
| Messager.INSTANCE.send("barfoo","one"); | |
| // If we make a second FooBar instance and then send a "foobar" message | |
| // again "Hello foobar" will be printed out twice. | |
| FooBar f2 = new FooBar(); | |
| System.out.println("Sending foobar again"); | |
| Messager.INSTANCE.send("foobar","one"); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment