gpt4 book ai didi

java - 应用于大规模记录更新的可观察模式

转载 作者:行者123 更新时间:2023-11-30 08:36:24 25 4
gpt4 key购买 nike

我正在尝试将Observer 模式应用于包含一组记录的类。

在 Java 伪代码中,我的类是:

public class MyClass<E> extends Observable
{
private ArrayList<E> items = new ArrayList<E>();

public MyClass()
{
}

public void add(E e)
{
this.items.add(e);

setChanged();
notifyObservers();
}

public void remove(E e)
{
if(this.items.remove(e))
{
setChanged();
notifyObservers();
}
}

...
}

我的问题是:在某些情况下,在程序执行期间,我必须对结构中的记录进行大量删除和插入操作,并且出于性能目的,我希望在整个操作结束时只通知观察者对象一次。

当然我可以添加一些标志变量来处理对 setChangednotifyObservers 的调用,但我想知道处理此类问题的“最佳”方法是什么.

所以我的问题是:设计代码以在对观察对象进行大量修改后仅通知一次观察对象的最佳方法是什么?

最佳答案

我认为您有 2 个常规选项

  • 让客户端代码明确禁用通知
  • 将变化封装在自己的类中并使用模板方法

让我们来看看这两个选项。我将使用一个简单的 Observer 作为示例。

public class StdoutObserver implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println("Observable changed: " + o);
}
}

客户端代码明确禁用通知

public class MyClass<E> extends Observable {
private ArrayList<E> items = new ArrayList<E>();

private boolean changing;

public void setIsChanging(boolean changing){
this.changing = changing;
if(!changing && hasChanged()){
notifyObservers();
}
}

public void add(E e) {
this.items.add(e);
notifyChanged();
}

public void remove(E e) {
if (this.items.remove(e)) {
notifyChanged();
}
}

private void notifyChanged(){
setChanged();
if(!changing){
notifyObservers();
}
}
}

客户端代码如下所示

MyClass<String> stringMyClass = new MyClass<String>();
stringMyClass.addObserver(new StdoutObserver());

System.out.println("setting changing: true");
stringMyClass.setIsChanging(true);

stringMyClass.add("C");
stringMyClass.add("D");
stringMyClass.add("E");

System.out.println("setting changing: false");
stringMyClass.setIsChanging(false);

输出将是

setting changing: true
setting changing: false
Observable changed: MyClass@229ed927

此解决方案的问题是客户端代码可能会忘记启用通知(或告诉可观察者更改已完成)。在这种情况下,通知可能会永远关闭。

将变化封装在自己的类中并使用模板方法

定义一个接口(interface)来表示变化

public interface ObservableChange<T extends Observable> {
public void doChange(T observable);
}

您的 Observable 将使用模板方法来确保在更改完成后重置 changing 状态。

public class MyClass<E> extends Observable {

private ArrayList<E> items = new ArrayList<E>();

private boolean changing;

public void update(ObservableChange<MyClass2<E>> observableChange) {
setIsChanging(true);
try {
observableChange.doChange(this);
} finally {
setIsChanging(false);
}

}

private void setIsChanging(boolean changing) {
this.changing = changing;
if (!changing && hasChanged()) {
notifyObservers();
}
}

public void add(E e) {
this.items.add(e);
notifyChanged();
}

public void remove(E e) {
if (this.items.remove(e)) {
notifyChanged();
}
}

private void notifyChanged() {
setChanged();
if (!changing) {
notifyObservers();
}
}
}

客户端代码将如下所示;

MyClass<String> stringMyClass = new MyClass<String>();
stringMyClass.addObserver(new StdoutObserver());


stringMyClass.update(new ObservableChange<MyClass<String>>() {
@Override
public void doChange(MyClass<String> observable) {
observable.add("A");
observable.add("B");
observable.add("C");
observable.add("D");
}
});

输出将是

Observable changed: MyClass2@33837697

使用模板方法可确保仅在更改完成后才禁用通知,因为观察者对此进行控制。

关于java - 应用于大规模记录更新的可观察模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37807102/

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