gpt4 book ai didi

java - 在观察者模式中拥有多个观察者列表的最佳方式

转载 作者:行者123 更新时间:2023-12-02 11:17:18 24 4
gpt4 key购买 nike

我正在使用观察者模式编写一个简单的群聊程序。

组 1:A、B 和 C 组 2:A 和 C

A 是一个发件人/主题,有两个列表,一个用于 Group1,一个用于 Group2。

在主题类中有两个列表是实现此目的的好方法吗?

这是否违反了观察者模式的功能?

一个发送者可以有两组观察者。

public class Sender {

private List<Receiver> group1 = new ArrayList<Receiver>();
private List<Receiver> group2 = new ArrayList<Receiver>();
private String msg;
private String name;

public Sender(String name) {
this.name = name;
}

public void sendMsg(int group, String msg, JTextArea display) {
this.msg = msg;
String output = name + ": " + msg;
display.append(output + "\n\r");
if(group == 1) {
notifyAllObservers(group1);
} else {
notifyAllObservers(group2);
}

}

public void register(int group, Receiver receiver) {
if(group == 1) {
group1.add(receiver);
} else {
group2.add(receiver);
}

}

public void notifyAllObservers(List<Receiver> group) {
for (Receiver receiver : group) {
receiver.update(msg);
}
}

public String toString() {
return name;
}

}

public class Receiver {

public Sender sender;
private JTextArea display;
public Receiver(int group, Sender sender, JTextArea display) {
this.sender = sender;
this.display = display;
this.sender.register(group, this);
}

public void update(String msg) {
display.append(sender.toString() + ": " + msg + "\n\r");
}
}

最佳答案

你当前的设计不一定与观察者模式相矛盾,但它是僵化的。截至目前,每Sender最多可以分为两组。如果每个发件人最多属于 10 个组怎么办? 100组?为了保持这种设计的灵 active ,我建议建模 Group s 也作为对象。这个想法是每个 GroupObservable和一个Observer同时。每个Group有一个List<Sender> senders ,它自动注册为 Observer 。如果 Group收到一些Event来自 Observable 之一如果它注册到,它会将此事件转发到其 Observers 。以下代码是我的提案的粗略草图。

public interface Observer {
public void receiveEvent(Observable source, Event event);
}

public interface Observable {
public void addObserver(Observer observer);
public void removeObserver(Observer observer);
public Collection<Observer> getObservers();

default public void notifyAllObservers(Event event) {
for (Observer observer : this.getObservers()) {
observer.receiveEvent(this, event);
}
}
}

public interface Event { }

public abstract class AbstractObservableImpl implements Observable {
private Set<Observer> observers = new HashSet<>();

@Override
public final void addObserver(final Observer observer) {
this.observers.add(observer);
}

@Override
public final void removeObserver(final Observer observer) {
this.observers.remove(observer);
}

@Override
public final Collection<Observer> getObservers() {
return Collections.unmodifiableCollection(this.observers);
}
}

public class Sender extends AbstractObservableImpl { }

public class Group extends AbstractObservableImpl implements Observer {
private List<Sender> senders = new ArrayList<>();

@Override
public final void receiveEvent(final Observable source, final Event event) {
for (Observer observer : this.getObservers()) {
observer.receiveEvent(this, event);
}
}

public final void addSender(Sender sender) {
if (this.senders.contains(sender) == false) {
this.senders.add(sender);
}
this.senders.get(this.senders.indexOf(sender)).addObserver(this);
}

public final void removeSender(Sender sender) {
final int index = this.senders.indexOf(sender));
if (index >= 0) {
this.senders.get(index).removeObserver(this);
}
this.senders.remove(sender);
}
}

关于设计的一些评论:

  • abstract class AbstractObserverImpl不是必需的。我只是懒得重复代码,因为 SenderGroup不继承其他任何东西,我让它们继承AbstractObserverImpl .
  • AbstractObserverImpl 也不是必需的。是 abstract 。对我来说,允许实例化此类是没有意义的,因为它缺少其实际功能(触发 Event 的部分)。
  • 我选择创建一个空的 Event界面。这也是随意的。无论您使用Object作为事件、枚举、接口(interface)、类或不同的方法完全取决于您。正如我所说:这只是一个粗略的草图。
  • 草图不是 null -安全的。有相当多的可能性会导致 NullPointerException

关于java - 在观察者模式中拥有多个观察者列表的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50183111/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com