我应该使用observates还是在parent中使用所有逻辑?

mrfwxfqh  于 2021-07-08  发布在  Java
关注(0)|答案(0)|浏览(161)

我有以下代码: Container 是一个包含一组 Part s。一些零件能够告诉容器它们已经改变了( ObservablePart 通知 Container 通过 someObservableMarketChanged 方法),有些只是更新它们的状态( NonObservablePart ). 万一 ObservablePart 更改后,我需要重新计算,并再次更新所有部分(但此更改仅适用于 NonObservablePart 是的, ObservablePart 它们的值保持不变)。
在这个例子中,我有两个可观察的部分和两个不可观察的部分。每当任何可观察部分发生变化时,我就必须把所有可观察部分的值作为输入,并为不可观察部分计算新的值。如果我使用观察者模式,一旦我更新了第一个可观察对象,它就会通知我——我能不能等到所有可观察对象都更新了(但可能其他可观察对象根本不会改变它的值),然后再重新计算?
如果观测值是异步的——在我看来这会更容易,我只会中断当前的计算,并用新值触发它。
该程序的输出为:

Changing observable id 1 from 1 -> 235
Changing NONobservable id 4 from 1 -> 236
Changing NONobservable id 3 from 1 -> 236
Changing observable id 2 from 1 -> 235
Changing NONobservable id 4 from 236 -> 470
Changing NONobservable id 3 from 236 -> 470
//notice that order of updates even metter
//so here I get this overwritten from first sync observable
Changing NONobservable id 4 from 470 -> 235
Changing NONobservable id 3 from 470 -> 235

正如你所看到的,有太多不必要的电话。我想要的是:

Changing observable id 1 from 1 -> 235
Changing observable id 2 from 1 -> 235
Changing NONobservable id 4 from 1 -> 470
Changing NONobservable id 3 from 1 -> 470

可以很容易地实施此案例:

void doit(){
        allParts.stream()
                .filter(x -> x instanceof ObservablePart)
                .forEach(x -> x.updateMe(235));
        Map<Integer, Part> changed = onlyNonObservableMarketsChange();
        for(Part m : allParts){
            m.updateMe(changed.get(m.getId()).getVal());
        }
    }

所以,基本上 ObservablePart 通知 Container 它的状态改变了,我必须把所有的逻辑放进去 Container ,和 Container 是不是更愚蠢的容器,只是把责任 Part 物体。现在,它必须知道哪些部分是可观察的,哪些是不可观察的,并且它首先需要更新所有可观察的部分,只有这样它才能进行一些计算并更新不可观察的部分。
在这种情况下,使用观察者模式是一种过度杀伤力吗?我应该把这个逻辑放进去吗 Container ,因为代码和推理要简单得多?

import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class Differ {
    public static void main(String[] args) {
        Container m = new Container();
        m.allParts = Set.of(
                new ObservablePart(1,m),
                new ObservablePart(2,m),
                new NonObservablePart(3),
                new NonObservablePart(4)
        );
        m.doit();
    }
}

class Container {
    public Set<Part> allParts = new HashSet<>();

    void doit(){
        for(Part m : allParts){
            m.updateMe(235);
        }
    }

    //this would not be in Container, just needed for example
    int getSumOfObservableMarkets(){
        return allParts.stream()
                .filter(x -> x instanceof ObservablePart)
                .mapToInt(x -> ((ObservablePart) x).val)
                .sum();
    }

    //this would not be in container, but something else would calc. changes
    Map<Integer, Part> onlyNonObservableMarketsChange(){
        int obsSum = getSumOfObservableMarkets();
        return allParts.stream()
                .collect(Collectors.toMap(k -> k.getId(), m -> {
                    if(m.getId()==1 || m.getId()==2){
                        return m;
                    }
                    m.updateMe(obsSum);
                    return m;
                }));
    }

    void someObservableMarketChanged(){
        Map<Integer, Part> changed = onlyNonObservableMarketsChange();
        for(Part m : allParts){
            m.updateMe(changed.get(m.getId()).getVal());
        }
    }
}

interface Part {
    int getId();
    int getVal();
    void updateMe(int val);
}
class ObservablePart implements Part {
    Container container;
    ObservablePart(int id, Container m){this.id=id;
        container =m;}
    public int id;
    int val = 1;
    public int getId() {return id;}
    public int getVal() {return val;}
    public void updateMe(int val) {
        if(this.val != val) {
            System.out.printf("Changing observable id %s from %s -> %s%n", id, this.val, val);
            this.val = val;
            container.someObservableMarketChanged();
        }
    }
}
class NonObservablePart implements Part {
    public int id;
    int val = 1;
    public NonObservablePart(int id) {this.id = id;}
    public int getId() {return id;}
    public int getVal() {return val;}
    public void updateMe(int val) {
        System.out.printf("Changing NONobservable id %s from %s -> %s%n", id, this.val, val);
        this.val = val;
    }
}

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题