Java 我应该使用可观察的还是在父级中使用所有逻辑?
我有以下代码:Java 我应该使用可观察的还是在父级中使用所有逻辑?,java,oop,design-patterns,observer-pattern,solid-principles,Java,Oop,Design Patterns,Observer Pattern,Solid Principles,我有以下代码: 容器是一个包含一组零件的对象。一些部件能够告诉容器它们已更改(observeablepart通过someobservemarketchanged方法通知container),而一些部件只是更新它们的状态(nonobservepart)。如果observedpart发生变化,我需要重新计算,并再次更新所有部分(但此变化仅适用于nonobservedparts,observedparts的值保持不变) 在这个例子中,我有两个可观察的部分和两个不可观察的部分。无论何时任何可观测部分发生
容器
是一个包含一组零件的对象。一些部件能够告诉容器它们已更改(observeablepart
通过someobservemarketchanged
方法通知container
),而一些部件只是更新它们的状态(nonobservepart
)。如果observedpart
发生变化,我需要重新计算,并再次更新所有部分(但此变化仅适用于nonobservedpart
s,observedpart
s的值保持不变)
在这个例子中,我有两个可观察的部分和两个不可观察的部分。无论何时任何可观测部分发生变化,我都必须将所有可观测值作为输入,并计算不可观测值的新值。如果我使用观察者模式,当我更新它通知的第一个观察者时——我是否可以以某种方式等待,直到所有观察者都被更新(但可能其他观察者根本不会改变它的值),然后再重新计算
若观测值是异步的——在我看来这会更容易,我会中断当前的计算,并用新的值触发它
该程序的输出为:
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());
}
}
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;
}
}