我们有一个名为Variable的类,它表示单值或复合值。例如,它可以包含整数,布尔值,字符串等...(单值)或某些复合值,可以是字符串,整数或其他变量的列表。
我们序列化这些对象,并且在流中所有这些值都表示为字符串。每当我们序列化或反序列化时,都会发生类型转换。
还有一些可选功能或方法可以填充这些变量中的值。例如,您可以定义要从网页填充的变量 - 对于给定的变量,我们查询缓存以了解是否应该从网页填充它。每当有人对变量进行getValue()时,我们就会填充该值。
我们还想跟踪一些变量的变化。例如,每当读取或更改变量的值时,我都可以选择记录或执行某些操作。
正如您所看到的,这是一个层次结构,因为变量可以包含其他变量。我们想找到解决这个问题的最佳方法。
目前我们只有一个名为Variable的类,它有很多if / else条件且代码非常复杂。 例如,getValue()代码执行以下操作:
if(查询缓存以查看是否需要来自网页的人口) 做一点事 其他( - -) 做一点事 else(如果读取应该记录 - 从缓存中查找) 做点什么......
是否有任何模式来设计我的类,以便我的所有人都来自网页逻辑可以进入一个类,跟踪其他类中的逻辑,在其他类中键入转换逻辑等...来实现它更具可读性。
答案 0 :(得分:2)
Chain of Responsibility Composite中的每个链接元素都可以做到这一点,但你必须花一些时间来配置运行时结构。
可能只是getValue()场景的复合或观察者(但听起来更像是复合词)。
编辑:
有人可能会争辩说,下面的实施实际上是“责任链”的情况,因为复合变量会将设定值的责任委托给其子女。
结束编辑
这是一个使用Observer和Composite的简单示例。没试过只是为了让你对解决方案有一般的感觉......
我没有实现序列化/反序列化等功能。
在此解决方案中,您具有复合值和原子值,并且可以在设置值之前添加一些要执行的观察器。
package dk.asj.variables;
public abstract class VariableBase {
public interface Observer {
void onSet(final Value val, final VariableBase var);
}
private Observer obs = null;
public void setObserver(final Observer obs) {
this.obs = obs;
}
public void setValue(final Value val) {
if (obs != null) {
obs.onSet(val, this);
}
internalSetValue(val);
}
protected abstract void internalSetValue(final Value val);
public abstract Value getValue();
}
package dk.asj.variables;
import java.util.List;
public interface Value {
int getIntValue();
String getStringValue();
List<Value> getCompositeValue();
}
package dk.asj.variables;
public class SimpleVariable extends VariableBase {
private Value val = null;
@Override
protected void internalSetValue(final Value val) {
this.val = val;
}
@Override
public Value getValue() {
return val;
}
}
package dk.asj.variables;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class CompoundVariable extends VariableBase {
final List<VariableBase> children = new LinkedList<VariableBase>();
public void addChild(final VariableBase c) {
children.add(c);
}
@Override
protected void internalSetValue(final Value val) {
for (int i = 0; i < val.getCompositeValue().size(); ++i) {
children.get(i).setValue(val.getCompositeValue().get(i));
}
}
@Override
public Value getValue() {
final List<Value> res = new ArrayList<Value>(children.size());
for (final VariableBase var : children) {
res.add(var.getValue());
}
return new Value() {
@Override
public int getIntValue() {
throw new RuntimeException("This is a composite value");
}
@Override
public String getStringValue() {
throw new RuntimeException("This is a composite value");
}
@Override
public List<Value> getCompositeValue() {
return res;
}
};
}
}
答案 1 :(得分:0)
我不确定这是否能回答你的问题,然而,这可能会带来一些新想法,这就是我在类似情况下提出的想法:
这似乎是一种非常灵活的方法 - 我甚至通过引入InjectionContext
实现了一个简单的依赖注入,{{1}}是一个线程安全的上下文,用于连接对象。
您可能希望在我正在开发的部署工具中查看an example of how this is used。配置管理和共享应用程序逻辑建立在这些变量之上。代码在bear.context包下,但目前它还很原始。