This article is excerpted from This is How Design Patterns should Be Learned
1 Implement notification mechanism based on Java API
When a user answers a question in the community, the user will receive an email notification. This is an application scenario of the Observer mode. Some people might think of MQ, asynchronous queues, etc., but the JDK itself provides such apis. To restore such an application scenario in code, we first create a GPer class.
/** * the JDK provides an implementation of the observer, observed */
public class GPer extends Observable{
private String name = "GPer ecosphere";
private static GPer gper = null;
private GPer(a){}
public static GPer getInstance(a){
if(null == gper){
gper = new GPer();
}
return gper;
}
public String getName(a) {
return name;
}
public void publishQuestion(Question question){
System.out.println(question.getUserName() + "In" + this.name + "A question was submitted on."); setChanged(); notifyObservers(question); }}Copy the code
Then create the Question class.
public class Question {
private String userName;
private String content;
public String getUserName(a) {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getContent(a) {
return content;
}
public void setContent(String content) {
this.content = content; }}Copy the code
Then create the Teacher class.
public class Teacher implements Observer {
private String name;
public Teacher(String name) {
this.name = name;
}
public void update(Observable o, Object arg) {
GPer gper = (GPer)o;
Question question = (Question)arg;
System.out.println("= = = = = = = = = = = = = = = = = = = = = =");
System.out.println(name + "Hello, teacher! \n" +
"You have received a letter from + gper.getName() + "I hope you will answer the question. The question reads as follows: \n" +
question.getContent() + "\n" + "Questioner:"+ question.getUserName()); }}Copy the code
Finally write the client test code.
public static void main(String[] args) {
GPer gper = GPer.getInstance();
Teacher tom = new Teacher("Tom");
Teacher jerry = new Teacher("Jerry");
gper.addObserver(tom);
gper.addObserver(jerry);
// User behavior
Question question = new Question();
question.setUserName("Zhang");
question.setContent("What scenarios does the observer model apply to?");
gper.publishQuestion(question);
}
Copy the code
The running result is shown in the figure below.
Easy landing observer mode based on Guava API
I recommend a very useful framework for implementing the Observer pattern with a very simple API, starting with the introduction of Maven dependencies, for example.
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>20.0</version>
</dependency>
Copy the code
Then create the listening event GuavaEvent.
/** * Created by Tom */
public class GuavaEvent {
@Subscribe
public void subscribe(String str){
// Business logic
System.out.println(Execute the subscribe method, passing in the argument:+ str); }}Copy the code
Finally write the client test code.
/** * Created by Tom */
public class GuavaEventTest {
public static void main(String[] args) {
EventBus eventbus = new EventBus();
GuavaEvent guavaEvent = new GuavaEvent();
eventbus.register(guavaEvent);
eventbus.post("Tom"); }}Copy the code
Design the mouse event response API using the observer pattern
Then design a business scenario to help your friends better understand the observer model. The observer mode is also used extensively in JDK source code. For example, java.awt.Event is one of the observer patterns, but Java is rarely used to write desktop programs. Let’s use code to implement this, to help you understand more deeply the implementation principle of the observer mode. First, create the EventListener interface.
/** * Created by Tom. */
public interface EventListener {}Copy the code
Create the Event class.
/** * Created by Tom. */
public class Event {
// The event source, by whom the action was issued
private Object source;
// The event is triggered, and who should be notified (the observer)
private EventListener target;
// Observer's response
private Method callback;
// The event name
private String trigger;
// The event that triggered the event
private long time;
public Event(EventListener target, Method callback) {
this.target = target;
this.callback = callback;
}
public Object getSource(a) {
return source;
}
public Event setSource(Object source) {
this.source = source;
return this;
}
public String getTrigger(a) {
return trigger;
}
public Event setTrigger(String trigger) {
this.trigger = trigger;
return this;
}
public long getTime(a) {
return time;
}
public Event setTime(long time) {
this.time = time;
return this;
}
public Method getCallback(a) {
return callback;
}
public EventListener getTarget(a) {
return target;
}
@Override
public String toString(a) {
return "Event{" +
"source=" + source +
", target=" + target +
", callback=" + callback +
", trigger='" + trigger + '\' ' +
", time=" + time +
'} '; }}Copy the code
Create the EventContext class.
/** * Created by Tom. */
public abstract class EventContext {
protected Map<String,Event> events = new HashMap<String,Event>();
public void addListener(String eventType, EventListener target, Method callback){
events.put(eventType,new Event(target,callback));
}
public void addListener(String eventType, EventListener target){
try {
this.addListener(eventType, target,
target.getClass().getMethod("on"+toUpperFirstCase(eventType), Event.class));
}catch (NoSuchMethodException e){
return; }}private String toUpperFirstCase(String eventType) {
char [] chars = eventType.toCharArray();
chars[0] - =32;
return String.valueOf(chars);
}
private void trigger(Event event){
event.setSource(this);
event.setTime(System.currentTimeMillis());
try {
if(event.getCallback() ! =null) {
// Call the callback function with reflectionevent.getCallback().invoke(event.getTarget(), event); }}catch(Exception e){ e.printStackTrace(); }}protected void trigger(String trigger){
if(!this.events.containsKey(trigger)){return; } trigger(this.events.get(trigger).setTrigger(trigger)); }}Copy the code
Then create the MouseEventType interface.
/** * Created by Tom. */
public interface MouseEventType {
/ / click
String ON_CLICK = "click";
/ / double
String ON_DOUBLE_CLICK = "doubleClick";
/ / bounce
String ON_UP = "up";
/ / press
String ON_DOWN = "down";
/ / move
String ON_MOVE = "move";
/ / rolling
String ON_WHEEL = "wheel";
/ / hover
String ON_OVER = "over";
// Lose focus
String ON_BLUR = "blur";
// Get focus
String ON_FOCUS = "focus";
}
Copy the code
Create the Mouse class.
/** * Created by Tom. */
public class Mouse extends EventContext {
public void click(a){
System.out.println("Call click method");
this.trigger(MouseEventType.ON_CLICK);
}
public void doubleClick(a){
System.out.println("Call double click method");
this.trigger(MouseEventType.ON_DOUBLE_CLICK);
}
public void up(a){
System.out.println("Call the pop-up method");
this.trigger(MouseEventType.ON_UP);
}
public void down(a){
System.out.println("Call down method");
this.trigger(MouseEventType.ON_DOWN);
}
public void move(a){
System.out.println("Call the move method");
this.trigger(MouseEventType.ON_MOVE);
}
public void wheel(a){
System.out.println("Call the scroll method");
this.trigger(MouseEventType.ON_WHEEL);
}
public void over(a){
System.out.println("Call hover method");
this.trigger(MouseEventType.ON_OVER);
}
public void blur(a){
System.out.println("Call the focus method");
this.trigger(MouseEventType.ON_BLUR);
}
public void focus(a){
System.out.println("Call out-of-focus methods");
this.trigger(MouseEventType.ON_FOCUS); }}Copy the code
Create the callback method MouseEventLisenter class.
/** * Created by Tom. */
public class MouseEventListener implements EventListener {
public void onClick(Event e){
System.out.println("=========== Trigger mouse click event ==========" + "\n" + e);
}
public void onDoubleClick(Event e){
System.out.println("=========== Trigger the double mouse click event ==========" + "\n" + e);
}
public void onUp(Event e){
System.out.println("=========== Trigger mouse bouncing event ==========" + "\n" + e);
}
public void onDown(Event e){
System.out.println("=========== trigger mouse press event ==========" + "\n" + e);
}
public void onMove(Event e){
System.out.println("=========== trigger mouse movement event ==========" + "\n" + e);
}
public void onWheel(Event e){
System.out.println("=========== trigger mouse scroll event ==========" + "\n" + e);
}
public void onOver(Event e){
System.out.println("=========== trigger mouse hover event ==========" + "\n" + e);
}
public void onBlur(Event e){
System.out.println("=========== trigger mouse out-of-focus event ==========" + "\n" + e);
}
public void onFocus(Event e){
System.out.println("=========== Trigger mouse to get focus event ==========" + "\n"+ e); }}Copy the code
Finally write the client test code.
public static void main(String[] args) {
EventListener listener = new MouseEventListener();
Mouse mouse = new Mouse();
mouse.addListener(MouseEventType.ON_CLICK,listener);
mouse.addListener(MouseEventType.ON_MOVE,listener);
mouse.click();
mouse.move();
}
Copy the code
Pay attention to “Tom play architecture” reply to “design pattern” can obtain the complete source code.
Tom play architecture: 30 real cases of design patterns (attached source code), the challenge of annual salary 60W is not a dream
This article is “Tom play structure” original, reproduced please indicate the source. Technology is to share, I share my happiness! If this article is helpful to you, welcome to follow and like; If you have any suggestions can also leave a comment or private letter, your support is my motivation to adhere to the creation. Pay attention to “Tom bomb architecture” for more technical dry goods!