-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathObserverPattern.js
More file actions
135 lines (122 loc) · 3.9 KB
/
Copy pathObserverPattern.js
File metadata and controls
135 lines (122 loc) · 3.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
'use strict';
/**
* Observer Pattern - Defines a one-to-many relationships where there is a Subject
* and many Observers. Like the name suggests, the Observers observe the Subject,
* receive notifications from the Subject when something has changed. This concept
* is similar to Followers and Following in Twitter.
*
* Example - In picture sharing application like Instagram, on your dashboard you
* find pictures of the users you are following. That user may or may not know
* you are following him/her. The observer in this case refers to you following a
* user and the user becomes the subject.
*
*/
class NotificationData {
constructor(data) {
if(this.validData(data)) {
this.data = data;
} else {
this.data = {};
}
}
validData(data) {
// Data validation before you can return the correct data
console.log("No need validation")
// Create your logic if you need validation if not return true
return true;
}
}
class Subject {
constructor(name) {
// Create a new Array of Observers
this.observers = [];
this.name = name;
}
addObserver(observer) {
this.observers.push(observer);
}
removeObserver(observer) {
var index = this.observers.indexOf(observer);
this.observers.splice(index, 1);
}
notifyObservers(notificationData) {
this.observers.forEach((observer) => observer.update(notificationData));
}
}
class Observer {
constructor(name) {
this.newPosts = [];
this.isOnline = false;
this.name = name;
}
update() {
// When notification received, update something
console.log("Nothing to update over here");
}
}
class NewPost extends NotificationData {
validData(data) {
// Check if data has url and description if not it is not a valid data
if(data.hasOwnProperty('name') && data.hasOwnProperty('url') && data.hasOwnProperty('description')) {
return true;
} else {
return false;
}
}
}
class User extends Subject {
createPost(url, description) {
var data = {
name: this.name,
url: url,
description: description
}
var newPost = new NewPost(data).data;
this.notifyObservers(newPost);
}
}
class Follower extends Observer {
update(data) {
// After updating, send out notifications to Followers
this.newPosts.push(data);
if(this.isOnline) {
this.display();
this.seen();
}
}
seen() {
this.newPosts = [];
}
setOnline(b) {
this.isOnline = b;
// Display new data after going online
this.display();
this.seen();
}
display() {
console.log(this.name + ":" + JSON.stringify(this.newPosts));
this.seen();
}
}
// Initiate a really popular woman
let chloe = new User("Chloe");
// Initiate the Followers
let tom = new Follower("Tom");
let jack = new Follower("Jack");
// Let the guys follow Chloe
chloe.addObserver(tom);
chloe.addObserver(jack);
// Let Tom be offline while Jack be online, so Jack will receive instant notification
jack.setOnline(true);
// Chloe creates a post and Jack will receive updates while Tom has to wait to be online
console.log("Only Jack received the new post");
chloe.createPost("http://www.myselfie.com/selfie1.png", "Selfie taken at home");
console.log("Now Jack received another new post");
chloe.createPost("http://www.mymodelshoot.com/modelshoot1.png", "Model shoot");
console.log("Now Tom goes online");
tom.setOnline(true);
console.log("Now Chloe creates another post and both guys receive it");
chloe.createPost("http://www.ootd.com/ootd.png", "#ootd");
console.log("Chloe finds Tom creepy, removes him, then creates a new post");
chloe.removeObserver(tom);
chloe.createPost("http://www.ootd2.com/ootd2.png", "#ootd");