package com.zhaoshuangjian.mode15_观察者模式;
import com.zhaoshuangjian.mode15_观察者模式.mode15.RSS消息订阅.CsdnSystem;
import com.zhaoshuangjian.mode15_观察者模式.mode15.RSS消息订阅.RssUser;
import com.zhaoshuangjian.mode15_观察者模式.mode15.标准简易版.IObserver;
import com.zhaoshuangjian.mode15_观察者模式.mode15.标准简易版.MySubject;
import com.zhaoshuangjian.mode15_观察者模式.mode15.标准简易版.ObserverA;
import com.zhaoshuangjian.mode15_观察者模式.mode15.标准简易版.ObserverB;
/**
* 观察者模式测试
*
* @Author zhaoshuangjian 2023-03-25 下午21:44
*/
public class ObserverTest {
public static void main(String[] args) {
// 1、抽象的、标准的、简易的通知调用
notifyTest();
System.out.println("========================================");
// 2、免费给csdn打广告,博主也是真爱啊
rssTest();
}
private static void notifyTest(){
IObserver observerA = new ObserverA();
IObserver observerB = new ObserverB();
MySubject subject = new MySubject();
subject.add(observerA);
subject.add(observerB);
subject.extend();
}
private static void rssTest(){
String publishContent = "作者Appleyk , 刚刚发表了一篇博文:《Java 23种设计模式Demo案列大全 ☞ 【持续更新】》";
CsdnSystem csdnSystem = new CsdnSystem(publishContent);
csdnSystem.add(new RssUser(10001L,"曹操"));
csdnSystem.add(new RssUser(10002L,"刘备"));
csdnSystem.add(new RssUser(10003L,"孙权"));
csdnSystem.publish();
System.out.println("=========================此时,曹操退出了群聊");
csdnSystem.remove(10001L);
csdnSystem.publish();
}
/**
* 百科如下描述观察者模式:
* 观察者模式(有时又被称为发布/订阅模式)是软件设计模式的一种。
* 在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。
* 这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。
*
* 看了解释,主要记住这句话就行了,又被称为发布/订阅模式
* 优点如下:
* (1)主要或目标对象与被观察之间是完全解耦的,因此二者很容易被扩展
* (2)主对象可以将改变的状态结果通过链条的形式传递给依赖于其的所有被观察者对象,
* 大大节省了通知的代码量(否则需要人工去一个个通知)
* 缺点如下:
* 由于观察者的数量不定,如果数量过大的话,链式的通知方法会严重影响性能!!!
*/
}
package com.zhaoshuangjian.mode15_观察者模式.mode15.RSS消息订阅;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* 抽象一个订阅类,实现rss操作
*
* @Author zhaoshuangjian 2023-03-25 下午21:44
*/
public abstract class AbstractSubscription implements IRsserOperate{
/**
* 存放订阅了消息的用户
*/
private List rsses = new ArrayList<>();
@Override
public void add(IRss rss) {
this.rsses.add(rss);
}
@Override
public void del(IRss rss) {
this.rsses.remove(rss);
}
@Override
public void remove(Long rssId) {
Iterator iterator = rsses.iterator();
while (iterator.hasNext()){
RssUser next = (RssUser)iterator.next();
if(rssId.equals(next.getId())){
iterator.remove();
break;
}
}
}
@Override
public void notifyRssers(String content) {
for (IRss rss : rsses) {
rss.rss(content);
}
}
}
package com.zhaoshuangjian.mode15_观察者模式.mode15.RSS消息订阅;
/**
* CSDN博客系统,可以理解为目标对象,继承订阅抽象类,实现消息的发布
*
* @Author zhaoshuangjian 2023-03-25 下午21:44
*/
public class CsdnSystem extends AbstractSubscription {
/**
* 订阅的消息内容
*/
private String content ;
public CsdnSystem(){
}
public CsdnSystem(String content){
this.content = content ;
}
/**
* 一旦调用该方法,所有依赖于csdn系统的消息订阅者都将收到变更的消息
*/
@Override
public void publish() {
System.out.println("博主通知:广大的童鞋们,如果对我写的文章感兴趣的话,请伸出你的大拇指,给个赞吧!");
notifyRssers(content);
}
public void setContent(String content) {
this.content = content;
}
}
package com.zhaoshuangjian.mode15_观察者模式.mode15.RSS消息订阅;
/**
* 消息订阅接口,提供一个订阅消息内容的实现
*
* @Author zhaoshuangjian 2023-03-25 下午21:44
*/
public interface IRss {
/**
* 消息订阅,主要输出订阅的内容
*/
void rss(String content);
}
package com.zhaoshuangjian.mode15_观察者模式.mode15.RSS消息订阅;
/**
* 订阅者操作接口
*
* @Author zhaoshuangjian 2023-03-25 下午21:44
*/
public interface IRsserOperate {
/**
* 增加一个订阅者
* @param rss 被增加的订阅者
*/
void add(IRss rss);
/**
* 移除一个订阅者
* @param rss 被移除订阅者
*/
void del(IRss rss);
/**
* 根据订阅者的ID移除一个订阅者
* @param rssID 被移除的订阅者的ID
*/
void remove(Long rssID);
/**
* 通知所有订阅者,订阅的内容是什么
*/
void notifyRssers(String content);
/**
* 发布消息
*/
void publish();
}
package com.zhaoshuangjian.mode15_观察者模式.mode15.RSS消息订阅;
/**
*
*
* @Author zhaoshuangjian 2023-03-25 下午21:44
*/
public class RssUser implements IRss {
/**
* 用户ID
*/
private Long id;
/**
* 用户名称
*/
private String name;
public RssUser(Long id , String name){
this.id = id ;
this.name = name ;
}
@Override
public void rss(String content) {
System.out.println("尊敬的用户( id = "+this.id+",name = "+this.name+"),你搜到了一条订阅消息:"+content);
}
public Long getId() {
return id;
}
}
package com.zhaoshuangjian.mode15_观察者模式.mode15.标准简易版;
import java.util.ArrayList;
import java.util.List;
/**
* 抽象一个主类,实现通知接口,并保留扩展方法
*
* @Author zhaoshuangjian 2023-03-25 下午21:44
*/
public abstract class AbstractSubject implements INotify{
private List observers = new ArrayList<>();
@Override
public void add(IObserver observer) {
observers.add(observer);
}
@Override
public void remove(IObserver observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (IObserver observer : observers) {
observer.discover();
}
}
}
package com.zhaoshuangjian.mode15_观察者模式.mode15.标准简易版;
/**
* 通知接口,主要干的事情,就是添加、移除观察者、以及通知所有观察者,我XXX干了什么
*
* @Author zhaoshuangjian 2023-03-25 下午21:44
*/
public interface INotify {
/**
* 添加一个观察者
* @param observer 被添加的观察者对象
*/
void add(IObserver observer);
/**
* 移除一个观察者
* @param observer 被移除的观察者对象
*/
void remove(IObserver observer);
/**
* 通知所有的观察者,可以理解为,只要在监控内的对象,都通知
*/
void notifyObservers();
/**
* 扩展方法,可以交给主体类来实现,比如订阅系统中的源头
*/
void extend();
}
package com.zhaoshuangjian.mode15_观察者模式.mode15.标准简易版;
/**
* 观察者接口,就提供了一个discover方法
*
* @Author zhaoshuangjian 2023-03-25 下午21:44
*/
public interface IObserver {
/**
* 发现,具体发现什么,做什么,交由实现的类吧
*/
void discover();
}
package com.zhaoshuangjian.mode15_观察者模式.mode15.标准简易版;
/**
* 自定义子类,继承抽象主类,只需要干一件事情即可,通知所有观察者之前,先...
*
* @Author zhaoshuangjian 2023-03-25 下午21:44
*/
public class MySubject extends AbstractSubject{
@Override
public void extend() {
System.out.println("大事不妙,有敌情!");
notifyObservers();
}
}
package com.zhaoshuangjian.mode15_观察者模式.mode15.标准简易版;
/**
* 观察者A
*
* @Author zhaoshuangjian 2023-03-25 下午21:44
*/
public class ObserverA implements IObserver{
@Override
public void discover() {
System.out.println("观察者A:不好,发现敌情,敌军还有三秒抵达战场!");
}
}
package com.zhaoshuangjian.mode15_观察者模式.mode15.标准简易版;
/**
* 观察者B
*
* @Author zhaoshuangjian 2023-03-25 下午21:44
*/
public class ObserverB implements IObserver{
@Override
public void discover() {
System.out.println("观察者B:不好,发现敌情,敌军还有两秒抵达战场!");
}
}