• Observer Pattern — Reactive Programming [Android RxJava2](What the hell is this) Part1
  • Hafiz Waleed Hussain
  • The Nuggets translation Project
  • Translator: Zhiw
  • Proofreader: Dubuqingfeng, Vivienmm

Observer Pattern — Responsive Programming [Android RxJava2] (What the hell is this) : Part 1

Oh, we’ve had another day, and it’s time to learn something new to make it great.

Hello everyone, I hope you do better. Today I’m going to start a new series on Rx Java2, but the first 2-3 articles are on reactive programming. Hopefully we can learn something new and clear up all the confusion together.

Motivation:

To be honest, I had a lot of problems learning Rx at first. I tried many tutorials and books, but in the end I couldn’t use Rx in my application. Many tutorials confuse me, as some sections say that the iterator pattern is based on Pull, and similarly Rx is based on Push, and gives examples that are of no use to me. I want to learn ABOUT Rx, I want to learn about its benefits, and I want to know how it will save me from lots of bugs and tedious code. But every time I got a push and pull comparison, sometimes imperative and reactive, I never got the real Rx I was looking for. In several articles, the author mentions that Rx is like the observer model. As time went by, the confusion mounted and the learning curve became difficult. Later I got some tutorials on FRP, lambda expressions and Functional Programming. I’ve seen examples where lambda expressions are used to call functions like map, filter, etc. But I stayed where I was, and I still didn’t know what Rx was or why I chose it. Then I met friends who used Rx and asked if they could give me some guidance on how to use Rx. Here’s what they taught me: You know we have an EditText, if you want to check if the user has entered new text, how do you know? I replied that I would use the change listener.

Oh, you know how difficult this interface is. You can use Rx, which is made very easy by using Debounce and a simple Rx Observable. Do I have to use Rx to save 10 lines of code? They said no. You can use map, filter, or other functions to keep your code clean and simple. I’m not convinced that this is the only benefit, because I can unify these things through a class. On the other hand, I know companies like Netflix and other big companies use this paradigm, and they’re fine with it. So I’m even more confused. The day ended when I said yes. I still don’t understand Rx but I know myself. Although I take breaks sometimes, I never give up, never. I decided that I had learned so much in so many tutorials, but they were just a bunch of jigsaw puzzles to me, and it was time to put the jigsaw puzzle together into the right shape.

Crucially, I would like to thank the authors of all these tutorials and books I have read, they have confused me but also taught me. So everyone has a lot to thank the authors of these tutorials and books.

Another key point about my article is that I give you a 100% guarantee that you will know about 80% of Rx Java2 by the end of this tutorial series, but don’t expect me to start with Rx Java2 directly. I’ll start with the basics and work my way through, but no one will get confused at the end.

That’s a long motive, but it’s important to me. It’s time to attack.

I use IntelliJ to perform coding tasks in this tutorial.

Introduction:

A word of advice, if you’re as confused as I am, try to forget all the jargon mentioned below.

Rx

Observable

Observer

Map

Filter

FlatMap

Lymbda

Higher order functions

Iterator or Pull

Imperative

Reactive

Dataflow

Streams

FRP

Wait…

So we’ll write a component of a real enterprise application. This is the first step in a responsive paradigm. Basically, this won’t give you any information about Rx, but it will set us up for the rest of the tutorial.

Requirements:

Our client has a website that requires that when he posts a new tutorial, all members who subscribe receive an email.

Solution:

I’m not going to implement everything, but I’m going to do it in a way that we can easily grasp the concepts we want.

It’s time to break down our needs.

  1. We have subscribers, and that means we keep information about subscribers.

  2. There should be a database to insert rows when the user makes a new post. Simply put, when a post is published, our data should change. This is what we care about, because I need to notify my subscribers when something changes.

  3. The mail client, that’s not our focus.

The first two points are very important. I need to implement something to do both.

There are many ways you can use it, but I’m going to use the easiest one for me that will convey the message I want to share with you.

So we have a User class that contains only the member’s name and mail. Some might think that we should have an isSubscribed variable. In my opinion, this will make our code more complicated, because then we need to use a loop to determine which subscribers are, as shown in the code below.

public static class User { private String name; private String email; private boolean isSubscribed; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public boolean isSubscribed() { return isSubscribed; } public void setSubscribed(boolean subscribed) { isSubscribed = subscribed; }}Copy the code

So if I were to use this class, then, most likely, I would implement the code to send an email in the main method, which would look something like this.

Public static void sendEmail(List<User> userList){for (User User: userList){if(user.issubscribed){// Send emails to users}}}Copy the code

But I’m going to take a different approach. My User class looks like this:

public static class User { private String name; private String email; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; }}Copy the code

I don’t have any isSubscribed variables, which means that when I call the sendEmail method, I no longer use if, as shown below:

Public static void sendEmail(List<User> userList){for (User User: userList){// sendEmail to User}}Copy the code

Now is a good time to examine how I manage my subscribers. Basically, in this case, I’m fetching data from memory, so I initialize a list of users. In this case, I’m only saving users who clicked the subscribe button. If this were a real application, there would be a table in the database. It’s time to show you some more code.

private static List<User> subscribedUsers = new ArrayList<>();
Copy the code

Suppose we have four users, A, B, C, and D, all subscribed except B. Let me show you the code and see what I did inside the main method.

public static void main(String[] args){ User A = new User("A","[email protected]"); User B = new User("B","[email protected]"); User C = new User("C","[email protected]"); User D = new User("D","[email protected]"); // Now users A,C,D click the subscribe button. Add (A); subscribedUsers.add(C); subscribedUsers.add(D); }Copy the code

Now the first point is done. We need to save information about users who need to subscribe to mail.

It’s time to look at point two. I want to notify users when they post a new tutorial. Here I have a Tutorial class as shown below.

public static class Tutorial{ private String authorName; private String post; public String getAuthorName() { return authorName; } public void setAuthorName(String authorName) { this.authorName = authorName; } public String getPost() { return post; } public void setPost(String post) { this.post = post; }}Copy the code

Here we need a place to save our tutorial. In a real application I would have a table, but in this case I’m going to initialize a list of tutorials to hold all the old and new tutorials, as shown below.

private static List<Tutorial> publishedTutorials = new ArrayList<>();
Copy the code

Here I will increase the complexity of our code :P. For example, I’ve already had three tutorials for Android 1, Android 2, and Android 3. All three articles were published, and then all users subscribed. This means that when I add an Android 4 tutorial, all users will receive an email. First I’ll show you the first part, how I added the first 3 tutorials and then the user subscribed to the mail.

public static void main(String[] args){ Tutorial android1 = new Tutorial("Hafiz", "........" ); Tutorial android2 = new Tutorial("Hafiz", "........" ); Tutorial android3 = new Tutorial("Hafiz", "........" ); publishedTutorials.add(android1); publishedTutorials.add(android2); publishedTutorials.add(android3); // I already have three tutorials, and then the User subscribed to the email User A = new User("A","[email protected]"); User B = new User("B","[email protected]"); User C = new User("C","[email protected]"); User D = new User("D","[email protected]"); // Now users A,C,D click the subscribe button. Add (A); subscribedUsers.add(C); subscribedUsers.add(D); }Copy the code

Now for the most important part, I’ve posted my fourth tutorial, which looks like this:

Public static void main(String[] args){Tutorial android1 = new Tutorial("Hafiz 1", "..." ); Tutorial android2 = new Tutorial("Hafiz 2", "........" ); Tutorial android3 = new Tutorial("Hafiz 3", "........" ); publishedTutorials.add(android1); publishedTutorials.add(android2); publishedTutorials.add(android3); // I already have three tutorials, and then the User subscribed to the email User A = new User("A","[email protected]"); User B = new User("B","[email protected]"); User C = new User("C","[email protected]"); User D = new User("D","[email protected]"); // Now users A,C,D click the subscribe button. Add (A); subscribedUsers.add(C); subscribedUsers.add(D); Tutorial android4 = new Tutorial("Hafiz 4", "........" ); publishedTutorials.add(android4); }Copy the code

How do I determine when the fourth or any new tutorial will be released so THAT I can send emails.

Well, very critical requirement. I’m going to implement polling, which means I’m going to implement a timer that checks if my data has changed after a certain amount of time. Here I’ll set an int object as a notification of data changes, as follows:

private static int lastCountOfPublishedTutorials = 0; Tutorial android1 = new Tutorial("Hafiz 1", "........" ); Tutorial android2 = new Tutorial("Hafiz 2", "........" ); Tutorial android3 = new Tutorial("Hafiz 3", "........" ); publishedTutorials.add(android1); publishedTutorials.add(android2); publishedTutorials.add(android3); lastCountOfPublishedTutorials = publishedTutorials.size(); polling();Copy the code

Now I have a point that I want to focus on, and if this quantity changes, that means something has changed. In this case, I need to send an email for a new tutorial release. It’s time for you to see how I implement polling.

private static void polling(){ Polling polling = new Polling(); Timer timer = new Timer(); The timer. The schedule (the polling, 0100); }Copy the code

This method is called when the service is started or, in this case, when the main method is called. The method will always be active, checking every second to see if my data has changed, as shown below.

public static class Polling extends TimerTask{ @Override public void run() { if(lastCountOfPublishedTutorials < publishedTutorials.size()){ lastCountOfPublishedTutorials = publishedTutorials.size(); sendEmail(subscribedUsers); } System.out.println("Polling"); }}Copy the code

Very simple, I just check to see if the amount has changed, then update the amount and send an email to all subscribers. The output from the IDE is shown below.


Polling

Email send: A

Email send: C

Email send: D

Polling

Polling

Polling


We’ve done everything the user told us to do, but it’s time to review our approach. I think polling is very bad. What other methods can we use?

Yes, of course. It’s time to use the second method to implement this functionality.

Now I’m going to change the code in our class. Guys, I’m going to start with the basics again, so right now there’s no interface, there’s nothing abstract, everything is concrete. Finally, I’m going to do a little refactoring so that we can see exactly how it works in professional software development.

Let’s take a look at the new changes in the Tutorial class, as shown below.

public static class Tutorial{ private String authorName; private String post; public Tutorial() { } public Tutorial(String authorName, String post) { this.authorName = authorName; this.post = post; } private static List<Tutorial> publishedTutorials = new ArrayList<>(); private static List<User> subscribedUsers = new ArrayList<>(); public static void addSubscribedUser(User user){ subscribedUsers.add(user); } public static void publish(Tutorial tutorial){ publishedTutorials.add(tutorial); sendEmail(subscribedUsers); }}Copy the code

In the new code, the Tutorial class will focus on published tutorials and subscribed users. For example, you can use the addSubscribedUser method. Now I’m going to show you the code for the main method. You can easily compare the changes between the two methods.

public static void main(String[] args){ Tutorial android1 = new Tutorial("Hafiz 1", "........" ); Tutorial android2 = new Tutorial("Hafiz 2", "........" ); Tutorial android3 = new Tutorial("Hafiz 3", "........" ); Tutorial.publish(android1); Tutorial.publish(android2); Tutorial.publish(android3); // I already have three tutorials, then the User subscribes to the email User A = new User("A","[email protected]"); User B = new User("B","[email protected]"); User C = new User("C","[email protected]"); User D = new User("D","[email protected]"); / / now users A, C, D click the subscribe button Tutorial. AddSubscribedUser (A); Tutorial.addSubscribedUser(C); Tutorial.addSubscribedUser(D); Tutorial android4 = new Tutorial("Hafiz 4", "........" ); Tutorial.publish(android4); }Copy the code

The Tutorial class is now responsible for publishing tutorials and managing subscribers. So we removed the first poll, which was a huge achievement. Then developers who don’t have to be responsible for writing data to inform the change of logic code, so we have removed the lastCountOfPublishedTutorials object.

That’s great, and the output looks like this.


Email send: A

Email send: C

Email send: D


I know the output above is not very clear because the program exits, so I will implement a logic that will let our program run in memory, never exit, and then post a new tutorial 1 second later. So we can see how the email is being sent.


Email send: A

Email send: C

Email send: D

Email send: A

Email send: C

Email send: D

Email send: A

Email send: C

Email send: D


Never quit

Now it’s time to find something better and more professional. Do we have any?

Yes, we do, but before we do that, I need to explain some English terms.

Can anyone explain Observable?

In English, anything that can be observed, such as a beautiful tree in my garden that I often observe, means it’s an Observable. When I was looking at the tree, there was a thunderstorm, and I observed the leaves falling because of the high wind, what happened? The tree is an Observable. I’m an Observer. When I was an Observer, I could feel the changes in the tree. Now I wasn’t alone. I had my wife with me, but she wasn’t looking at the tree. So when the first leaf falls, I can feel the change, but my wife can’t. Later she began to observe trees, too. When the second leaf falls, we both feel the change. This means that the tree, as an Observable, can inform its observers of changes.

What happens if I use the polling method for the same thing. I count the number of leaves and remember. I count it again a second later and compare it to the last result, so I feel the change, but I have to do it every second. Haha, in real life, I can’t do that.

In the first case, observables are responsible for notifying their observers of changes, which we can call Push (Rx is Push).

In the second case, my polling needs to check for any changes and then notify our users, which you can call Pull.

So it’s time to implement Observables and Observers.

What is an Observable in our app? Yes, it’s a tutorial. Who is the Observer? That’s right, users.

Now I’ll introduce the interface we use for the Observer pattern in professional software development.

Public Interface Observer{// Void notifyMe(); }Copy the code
public interface Observable{

 void register(Observer observer);

 void unregister(Observer observer);

 // New tutorial published to inform all subscribed users
 void notifyAllAboutChange();
}
Copy the code

Now we can look at abstract or generic interfaces. The Observer and the observables.

In our application, the user is an Observer, so I implement the Observer interface in the class, and the tutorial is an Observable, so I implement the Observable interface in the class, as shown below.

public static class User implements Observer{ private String name; private String email; public User() { } public User(String name, String email) { this.name = name; this.email = email; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public void notifyMe() { sendEmail(this); }}Copy the code

Now that the user will be notified of the tutorial, I call the notifyMe() method to publish a new article.

public static class Tutorial implements Observable{ private String authorName; private String post; private Tutorial() {}; public static Tutorial REGISTER_FOR_SUBSCRIPTION = new Tutorial(); public Tutorial(String authorName, String post) { this.authorName = authorName; this.post = post; } private static List<Observer> observers = new ArrayList<>(); @Override public void register(Observer observer) { observers.add(observer); } @Override public void unregister(Observer observer) { observers.remove(observer); } @Override public void notifyAllAboutChange() { for (Observer observer : observers) { observer.notifyMe(); } } public void publish(){ notifyAllAboutChange(); }}Copy the code

So what happens in this class? First I made the user an Observer so that he could register for any new tutorial posts he wanted to know about. In this case, it’s User, because User implements the interface.

Then there are two simple ways to manage subscriptions and unsubscriptions: register and unregister.

For registration and unregistration, we use the object REGISTER_FOR_SUBSCRIPTION of the class. Then there is the notifyAllAboutChange method, which notifies all observers of the change. The last method is publish, which is the method of the current instance. Any time I invoke the Publish method, all registered observers are notified by calling notifyMe().

public static void main(String[] args){ Tutorial android1 = new Tutorial("Hafiz 1", "........" ); android1.publish(); Tutorial android2 = new Tutorial("Hafiz 2", "........" ); android2.publish(); Tutorial android3 = new Tutorial("Hafiz 3", "........" ); android3.publish(); User A = new User("A","[email protected]"); User B = new User("B","[email protected]"); User C = new User("C","[email protected]"); User D = new User("D","[email protected]"); Tutorial.REGISTER_FOR_SUBSCRIPTION.register(A); Tutorial.REGISTER_FOR_SUBSCRIPTION.register(C); Tutorial.REGISTER_FOR_SUBSCRIPTION.register(D); Tutorial android4 = new Tutorial("Hafiz 4", "........" ); android4.publish(); }Copy the code

It’s too simple to explain. Now I feel like everyone should know what observables and observers are. These are the ones that really matter, and they are the only terms that are used 99.9% of the time in Rx. So if you have a clear impression of this and see the huge benefits of using this pattern in our application, then you can easily master the Rx paradigm. Now I’m going to use the Rx library to change the final code. Before we begin, I want to discuss a few points.

  1. This isn’t a great example, but I think you should know what an Observable, Observer, Pull, and Push are.

  2. The functionality I want to implement with RxJava is a very small thing in terms of Rx benefits.

  3. I’m not going to explain to you any of those methods that I’m going to use. Just review the code and don’t panic, you’ll understand later in the tutorial.

  4. Again, this is not the real power of RxJava. Basically I use this example as a foundation for me and my friends.

Integrate RxJava into your project, which you can download here.

It’s time to enjoy how many lines of code you’ve saved by using the Rx library. You can also imagine how much boilerplate code I would have to write if I wanted to implement the observer pattern in eight parts of the project, but with Rx, nothing.

First I remove the Observable and Observer interfaces from my classes.

Now I’ll implement the methods of the RxJava library.

The User class (Observer) with Rx is shown below.

public static class User implements Action1 { private String name; private String email; public User() {} public User(String name, String email) { this.name = name; this.email = email; } public String getName() {return name; } public void setName(String name) {this.name = name; } public String getEmail() {return email; } public void setEmail(String email) {this.email = email; } @Override public void call(Object o) { sendEmail(this); }}Copy the code

We can say that Action1 is a secondary interface to the Observer that the Rx library uses.

The Tutorial class (Observable) with Rx is shown below.

public static class Tutorial { private String authorName; private String post; private Tutorial() {} public static rx.Observable REGISTER_FOR_SUBSCRIPTION = rx.Observable.just(new Tutorial()); public Tutorial(String authorName, String post) { this.authorName = authorName; this.post = post; } public void publish(){ REGISTER_FOR_SUBSCRIPTION.publish(); }}Copy the code

If we compare these two classes to the previous one, we remove a lot of code. By using Rx, I convert my REGISTER_FOR_SUBSCRIPTION into an Rx Observable. Now we know what an Observable is. So any Observer can subscribe to my Observable, and all observers will be notified when the Observable publish method is called.

The main method is shown below.

public static void main(String[] args){ Tutorial android1 = new Tutorial("Hafiz 1", "........" ); android1.publish(); Tutorial android2 = new Tutorial("Hafiz 2", "........" ); android2.publish(); Tutorial android3 = new Tutorial("Hafiz 3", "........" ); android3.publish(); // I have already three tutorials and later user subscribed for email User A = new User("A","[email protected]"); User B = new User("B","[email protected]"); User C = new User("C","[email protected]"); User D = new User("D","[email protected]"); // Now A,C and D click subscribe button Tutorial.REGISTER_FOR_SUBSCRIPTION.subscribe(A); Tutorial.REGISTER_FOR_SUBSCRIPTION.subscribe(C); Tutorial.REGISTER_FOR_SUBSCRIPTION.subscribe(D); Tutorial android4 = new Tutorial("Hafiz 4", "........" ); android4.publish(); }Copy the code

The main method block doesn’t change much, and the output is as follows.


Email send: A

Email send: C

Email send: D


Cheers. Everything works the same, except that we are simpler and easier from an implementation perspective.

Conclusion: As a conclusion, we just tried to learn the observer mode, which is just the basis of Rx. Second, what do you do if I ask you to have 8 modules in the same code that need to implement notification? You need to implement 8 Observer and Observable interfaces and some boilerplate code. But with Rx, you just call the rx.Observable.just() method and the object can act like an Observable. Any Observer can then subscribe to the Observable. And if you get confused again, you can forget about the Rx part. Just remember what observer mode is. In the next article, I’ll use the concept we learned today to properly introduce Rx.

All the code is written below, you can copy and paste it into your IDE and play with it.

All right, bye, everybody. Pull vs Push & Imperative vs Reactive — Reactive Programming Android RxJava2 Part2

Polling method:

import java.util.ArrayList; import java.util.List; import java.util.Timer; import java.util.TimerTask; /** * Created by waleed on 04/02/2017. */ public class Main { private static List<User> subscribedUsers = new ArrayList<>(); private static List<Tutorial> publishedTutorials = new ArrayList<>(); private static int lastCountOfPublishedTutorials = 0; public static void main(String[] args){ Tutorial android1 = new Tutorial("Hafiz 1", "........" ); Tutorial android2 = new Tutorial("Hafiz 2", "........" ); Tutorial android3 = new Tutorial("Hafiz 3", "........" ); publishedTutorials.add(android1); publishedTutorials.add(android2); publishedTutorials.add(android3); lastCountOfPublishedTutorials = publishedTutorials.size(); polling(); // I have already three tutorials and later user subscribed for email User A = new User("A","[email protected]"); User B = new User("B","[email protected]"); User C = new User("C","[email protected]"); User D = new User("D","[email protected]"); // Now A,C and D click subscribe button subscribedUsers.add(A); subscribedUsers.add(C); subscribedUsers.add(D); Tutorial android4 = new Tutorial("Hafiz 4", "........" ); publishedTutorials.add(android4); } public static void sendEmail(List<User> userList){ for (User user : userList) { // send email to user System.out.println("Email send: "+user.getName()); } } public static class User { private String name; private String email; public User() { } public User(String name, String email) { this.name = name; this.email = email; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } } public static class Tutorial{ private String authorName; private String post; public Tutorial() { } public Tutorial(String authorName, String post) { this.authorName = authorName; this.post = post; } public String getAuthorName() { return authorName; } public void setAuthorName(String authorName) { this.authorName = authorName; } public String getPost() { return post; } public void setPost(String post) { this.post = post; } } private static void polling(){ Polling polling = new Polling(); Timer timer = new Timer(); The timer. The schedule (the polling, 0100); } public static class Polling extends TimerTask{ @Override public void run() { if(lastCountOfPublishedTutorials < publishedTutorials.size()){ lastCountOfPublishedTutorials = publishedTutorials.size(); sendEmail(subscribedUsers); } System.out.println("Polling"); }}}Copy the code

First reconstruction method:

/** * Created by waleed on 04/02/2017. */ public class Main { public static void main(String[] args){ polling(); Tutorial android1 = new Tutorial("Hafiz 1", "........" ); Tutorial android2 = new Tutorial("Hafiz 2", "........" ); Tutorial android3 = new Tutorial("Hafiz 3", "........" ); Tutorial.publish(android1); Tutorial.publish(android2); Tutorial.publish(android3); // I have already three tutorials and later user subscribed for email User A = new User("A","[email protected]"); User B = new User("B","[email protected]"); User C = new User("C","[email protected]"); User D = new User("D","[email protected]"); // Now A,C and D click subscribe button Tutorial.addSubscribedUser(A); Tutorial.addSubscribedUser(C); Tutorial.addSubscribedUser(D); Tutorial android4 = new Tutorial("Hafiz 4", "........" ); Tutorial.publish(android4); } private static void polling(){ Polling polling = new Polling(); Timer timer = new Timer(); The timer. The schedule (the polling, 0100); } public static class Polling extends TimerTask{ @Override public void run() { Tutorial android4 = new Tutorial("Hafiz 4 ", "..." ); Tutorial.publish(android4); } } public static void sendEmail(List<User> userList){ for (User user : userList) { // send email to user System.out.println("Email send: "+user.getName()); } } public static class User { private String name; private String email; public User() { } public User(String name, String email) { this.name = name; this.email = email; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } } public static class Tutorial{ private String authorName; private String post; public Tutorial() { } public Tutorial(String authorName, String post) { this.authorName = authorName; this.post = post; } private static List<Tutorial> publishedTutorials = new ArrayList<>(); private static List<User> subscribedUsers = new ArrayList<>(); public static void addSubscribedUser(User user){ subscribedUsers.add(user); } public static void publish(Tutorial tutorial){ publishedTutorials.add(tutorial); sendEmail(subscribedUsers); }}}Copy the code

Professional/observer model approach:

import java.util.*; /** * Created by waleed on 04/02/2017. */ public class Main { public static void main(String[] args){ Tutorial android1 = new Tutorial("Hafiz 1", "........" ); android1.publish(); Tutorial android2 = new Tutorial("Hafiz 2", "........" ); android2.publish(); Tutorial android3 = new Tutorial("Hafiz 3", "........" ); android3.publish(); // I already have three tutorials, later users will subscribe to the email User A = new User("A","[email protected]"); User B = new User("B","[email protected]"); User C = new User("C","[email protected]"); User D = new User("D","[email protected]"); // Now A,C,D click the tutorial.register_for_subscription. Register (A); Tutorial.REGISTER_FOR_SUBSCRIPTION.register(C); Tutorial.REGISTER_FOR_SUBSCRIPTION.register(D); Tutorial android4 = new Tutorial("Hafiz 4", "........" ); android4.publish(); } public static void sendEmail(User user){ System.out.println("Email send: "+user.getName()); } public static class User implements Observer{ private String name; private String email; public User() { } public User(String name, String email) { this.name = name; this.email = email; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @Override public void notifyMe() { sendEmail(this); } } public static class Tutorial implements Observable{ private String authorName; private String post; private Tutorial() {} public static Tutorial REGISTER_FOR_SUBSCRIPTION = new Tutorial(); public Tutorial(String authorName, String post) { this.authorName = authorName; this.post = post; } private static List<Observer> observers = new ArrayList<>(); @Override public void register(Observer observer) { observers.add(observer); } @Override public void unregister(Observer observer) { observers.remove(observer); } @Override public void notifyAllAboutChange() { for (Observer observer : observers) { observer.notifyMe(); } } public void publish(){ notifyAllAboutChange(); } } public interface Observable{ void register(Observer observer); void unregister(Observer observer); Void notifyAllAboutChange(); void notifyAllAboutChange(); } public interface Observer{// void notifyMe(); }}Copy the code

Rx method :(remember to integrate the Rx library into your project)

import rx.*; import rx.Observable; import rx.Observer; import rx.functions.Action; import rx.functions.Action1; import rx.observers.Observers; import java.util.*; /** * Created by waleed on 04/02/2017. */ public class Main { public static void main(String[] args){ Tutorial android1 = new Tutorial("Hafiz 1", "........" ); android1.publish(); Tutorial android2 = new Tutorial("Hafiz 2", "........" ); android2.publish(); Tutorial android3 = new Tutorial("Hafiz 3", "........" ); android3.publish(); // I have already three tutorials and later user subscribed for email User A = new User("A","[email protected]"); User B = new User("B","[email protected]"); User C = new User("C","[email protected]"); User D = new User("D","[email protected]"); // Now A,C and D click subscribe button Tutorial.REGISTER_FOR_SUBSCRIPTION.subscribe(A); Tutorial.REGISTER_FOR_SUBSCRIPTION.subscribe(C); Tutorial.REGISTER_FOR_SUBSCRIPTION.subscribe(D); Tutorial android4 = new Tutorial("Hafiz 4", "........" ); android4.publish(); } public static void sendEmail(User user){ System.out.println("Email send: "+user.getName()); } public static class User implements Action1{ private String name; private String email; public User() {} public User(String name, String email) { this.name = name; this.email = email; } public String getName() {return name; } public void setName(String name) {this.name = name; } public String getEmail() {return email; } public void setEmail(String email) {this.email = email; } @Override public void call(Object o) { sendEmail(this); } } public static class Tutorial { private String authorName; private String post; private Tutorial() {} public static rx.Observable REGISTER_FOR_SUBSCRIPTION = rx.Observable.just(new Tutorial()); public Tutorial(String authorName, String post) { this.authorName = authorName; this.post = post; } public void publish(){ REGISTER_FOR_SUBSCRIPTION.publish(); }}}Copy the code