每当我制作一个程序时,我倾向于在不同的文件中划分不同的部分,我认为它看起来更整洁。为了使问题更具体,我说这个虚拟代码由四个类组成,
public class dummy {
public static void main(String[] args){
Alpha a = new Alpha();
Beta b = new Beta();
Gamma g = new Gamma();
int x,y,z,j,k,l,o,p,q;
x = a.getGammaX();
y = b.getGammaX();
z = g.getX();
a.setGammaX(1);
j = a.getGammaX();
k = b.getGammaX();
l = g.getX();
b.setGammaX(2);
o = a.getGammaX();
p = b.getGammaX();
q = g.getX();
}
}
class Alpha{
Gamma g = new Gamma();
public int getGammaX(){
return g.getX();
}
public void setGammaX(int x){
g.setX(x);
}
}
class Beta{
Gamma g = new Gamma();
public int getGammaX(){
return g.getX();
}
public void setGammaX(int x){
g.setX(x);
}
}
class Gamma{
int x = 10;
public int getX(){
return x;
}
public void setX(int y){
x = y;
}
}
Alpha和Beta类与Gamma通信。整数的目的是打印出它们的值,并在从不同的类调用setter之后将它们相互比较。我分割部分时遇到的一个普遍问题是,当一个类改变Gamma中的值时,其他类具有过时的值,当setter方法具有时,x,y,z变量仍将具有Gamma中的旧值x被叫,除非我在花了很长时间才找到它之前发现它。
我倾向于通过传递Gamma类的一个引用来绕过这个,
Gamma g = new Gamma();
Alpha a = new Alpha(g);
Beta b = new Beta(g);
像这样,并花费几行代码来更新所有内容。从" main"创建引用的地方课程,其中"主要"不一定是具有main方法的类,而是具有最多动作的类。
我的问题是,有没有一种标准的方法来处理这类问题,其中多个类与另一个类进行通信,更改值等,最终得到过时的值?
我的问题往往比显示的更微妙,但基本上这是我倾向于花一些时间来尝试修复。我很抱歉,如果解释很混乱,我很难把问题弄清楚,如果太难以理解,请在评论中写一下,我会尽量清楚地说清楚它。
答案 0 :(得分:3)
处理此问题的标准方法是所谓的observer pattern。
您应该确保只有一个Gamma
实例,否则您必须确保所有实例都是同步的。
a
和b
要求g
注册为观察员。 g
通知所有观察者其状态发生变化。
class Gamma extends Observable {
int x = 10;
public int getX(){
return x;
}
public void setX(int y){
x = y;
notifyObservers (null);
}
}
class Alpha implements Observer {
// ...
public Alpha (Gamma g) {
g.addObserver (this);
}
public void update(Observable o, Object arg) {
// this method gets called by g whenever g's state changes
// do necessary updates here
// ...
}
}
答案 1 :(得分:3)
使用MVC(模型 - 视图 - 控制)模式或其变体之一,并且具有需要保持相同数据共享模型的类。例如,也许Gamma是你的模型,然后让其他类共享相同的Gamma实例。
如,
public class Dummy {
public static void main(String[] args) {
Gamma g = new Gamma();
Alpha a = new Alpha(g);
Beta b = new Beta(g);
// .........
}
}
class Alpha {
private Gamma g;
public Alpha(Gamma g) {
this.g = g;
}
public int getGammaX() {
return g.getX();
}
public void setGammaX(int x) {
g.setX(x);
}
}
class Beta {
// Gamma g = new Gamma();
private Gamma g;
public Beta(Gamma g) {
this.g = g;
}
public int getGammaX() {
return g.getX();
}
public void setGammaX(int x) {
g.setX(x);
}
}
class Gamma {
int x = 10;
public int getX() {
return x;
}
public void setX(int y) {
x = y;
}
}
要让类通知另一个类的状态更改,然后使用,请使用JohnB建议的观察者模式。
请注意,获得观察者支持的一种方法是使用JavaBean的PropertyChangeSupport。例如:
class Gamma {
public static final String X = "x";
private PropertyChangeSupport support = new PropertyChangeSupport(this);
private int x = 10;
public int getX() {
return x;
}
public void setX(int x) {
int oldValue = x;
int newValue = this.x;
this.x = x;
support.firePropertyChange(X, oldValue, newValue);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
support.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
support.removePropertyChangeListener(listener);
}
}
注意:使用共享Gamma类注入A和B类可能是最好和最干净的方法是通过依赖注入,例如可以从Spring的一个模块或Guice框架获得。
答案 2 :(得分:0)
如果你真的想这样做......使用JohnB提到的观察者模式。
但是,我并不完全同意你的理由。 跨类拆分代码不是使用观察者模式的好理由。应该有比这更好/更多功能的要求。当然我不知道确切的要求所以我不能概括。
我建议采用一种截然不同的方法。从添加一点功能的基类开始,然后逐层扩展以添加更多功能。
这将让您拥有精美清晰的代码,这些代码具有可读性和可维护性,同时还能保持您的对象模型代表功能。