如何避免对象知道包含它的集合?

时间:2017-10-24 17:43:11

标签: java

假设我有一个对象类,如下所示:

public class MyObject() {
  // ...
  public double distanceTo(MyObject other) {
    // **edit: check if desired distance is contained in distanceMatrix**
    // **of the collection in which this object is contained**
    // **if not:** some time-consuming calculation
  }
}

我还有一个包含这些对象的自定义集合:

public class MyObjectCollection() {
  private List<MyObject> objects;
  private double[][] distanceMatrix;
  // ...
  public void add(MyObject obj) {
    this.objects.add(obj);
  }
  public void calcDistanceMatrix() {
    for (int i = 0; i < objects.size(); i++) {
      for (int j = 0; j < objects.size(); j++) {
        this.distanceMatrix[i][j] = objects.get(i).distanceTo(objects.get(j));
      }
    }
  }
}

因此,我们的想法是仅计算所有MyObject之间的所有距离,并将它们存储在矩阵中。现在当有人在distanceTo上调用MyObject时,它应该使用缓存的值而不是再次计算它。

但是,为了实现这一点,每个MyObject必须知道它所包含的集合 - 或者它是什么?由于分离,我想避免这种情况。

(我知道我可以将MyObject obj1MyObject的所有距离存储为obj1中的字段,但我不想这样做。例如,这意味着每个MyObjectCollection重建MyObject结构(我出于其他原因需要)。{/ p>

1 个答案:

答案 0 :(得分:0)

我认为你需要做两件事,以便将耗时的计算和依赖从收集中分离出来:

1)在MyObject上分离得到缓存距离的逻辑,并将实际计算分成不同的方法。

2)将两个对象之间距离的逻辑移动到Strategy pattern之后的接口:

以下是修改后的代码:

public interface DistanceCalc{

        public double distanceTo(MyObject from, MyObject to);
    }

    public class MyObject{ 

        private DistanceCalc distanceCalc = null;

        public void setDistanceCalc(DistanceCalc distanceCalc) {
            this.distanceCalc = distanceCalc;
        }

        public double distanceTo(MyObject other) {
            return distanceCalc.distanceTo(this, other);
        }

        public double calculateDistance(MyObject to) {
            return 5.0; //this is where time consuming calculation happens
        }
      }

    public class MyObjectCollection implements DistanceCalc{
        private List<MyObject> objects;
        private double[][] distanceMatrix;

        public void add(MyObject obj) {
          this.objects.add(obj);
          obj.setDistanceCalc(this);
        }

        @Override
        public double distanceTo(MyObject from, MyObject to) {
            if (distanceMatrix == null) calcDistanceMatrix();            
            return distanceMatrix[ objects.indexOf(from) ][ objects.indexOf(to) ];
        }

        public void calcDistanceMatrix() {
          for (int i = 0; i < objects.size(); i++) {
            for (int j = 0; j < objects.size(); j++) {
              this.distanceMatrix[i][j] = objects.get(i).calculateDistance( objects.get(j) );
            }
          }
        }
     }