0
How to code cleanly on observer pattern
Refer code below: I have a question on the said code. Query 1 : How can I have a cleaner or better code for below lines: yt1.AddObserver(&h1); yt1.AddObserver(&h2); yt1.AddObserver(&h3); h1.setSubject(&yt1); h2.setSubject(&yt1); h3.setSubject(&yt1); Query 2: How can I have channel name and video name into human class update method? https://sololearn.com/compiler-playground/cpPj4yuEO2Fl/?ref=app
9 Réponses
+ 1
Sounds good @Bob_Li.
0
Hi Bob_Li, thanks
I should have stated my query more precisely. if i had to add three objects to be observed, it is ok to have them added one by one. (Nothing wrong to have initializer list, but that is not my concern as of now).
What I was looking for is different and it is related to one object at a time. In other words, below two statements should be combined.
yt1.AddObserver(&h1);
h1.setSubject(&yt1);
One might forget to add one statement at a time. I need a good way to combine these two operations to avoid the user errors of calling two different statements.
0
Regarding the query 2 response, It is nice way compared to no way present in my code.
But is it not restricting the subject to follow two string method for all the subjects? ISubject is generic and we should not be restricting it to have two string all the times as new class derived from isubject may not need two strings.
0
Ketan Lalcheta
maybe something like:
struct Isubject{
//use initializer list
void AddObserver(initializer_list<Iobserver*> obs){
for(auto& o: obs){
// callobserver's setSubject method
o->setSubject({this});
p_observers.push_back(o);
}
}
I updated my code to try this out.
It seems to be working, and I was able to comment out the individual setSubject calls.
Also, you can modify your data struct so that it fits your actual subject data.
I avoided a more generic approach to keep the example as simple as possible. Generic containers are generally harder to implement. Perhaps it should be a vector instead, but I was thinking it should also have a timestamp so it will be easier to determine if the data was updated or not.
But if the observer pattern is not enough, maybe an mvc or pub-sub pattern is a better choice?
In the end, use what works, even if you end up with hybrid patterns. There is no rule that the patterns have to be as pure as the textbook examples.
0
One problem with the Isubject automatically calling the observer's setSubject and adding itself to it is that the observer loses the ability to remove the subject. The subject can force itself to be added whenever it wants to.
Perhaps it is better to let the make the setSubject private?
0
oops, I messed up my code while playing with it.
0
Ketan Lalcheta
I think that the approach of enabling the Subject to be able to add Observer directly is problematic.
It would create a dependency and data state conflict if two classes are controlling the state of the program.
Better to only allow the Isubject to update and notify, while the ability to add and remove subject is done only by the Iobserver.
https://sololearn.com/compiler-playground/coYeeGA8N49r/?ref=app
0
First of all, Thanks a lot @Bob_Li for your extended hand of support.
I have checked your latest code and have few doubts:
1. Subject should not be able to add or remove Observer directly so that there would be no conflict with Observer add or remove operations.
Above is something application demands. I mean you tube channel is subject and its owner need to have provision who is to be subscribed to it.
2. Why you moved almost all to public section? It violates basic principles.
I agree that subject should be added when we were adding observer in your previous code. Also, getting you tube channel name from human is still confusing for me.
0
Ketan Lalcheta
I am also wondering if I was doing something unsafe with this arrangement.
Youtube channel is the subject. It's main concern is to upload videos and send general notification.
In this idealized situation, it cannot just choose any human and add it to the channel's observer vector. Giving it the control to the addObserver method seems unrealistic. Real youtube channels cannot do this.
If this is possible, every channel would have billions of subscribers.
The viewers add the channel to their watchlist only if they like it.
But this creates a problem: where to put the observer vector? The Youtube channel needs the vector to notify the observers. Making it private was the solution I used. There might be a better way.
The ability to removeObserver might have to be moved to public, though. Youtube channels should have the ability to remove or ban certain viewers/Observer.