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



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

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之间的所有距离,并将它们存储在一个矩阵中。现在,当有人在MyObject上调用distanceTo时,它应该使用缓存的值而不是再次计算它。

但是,要使其正常工作,每个MyObject都必须知道它包含的集合 - 或者知道吗?由于分离,我想避免这种情况。

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

我认为您需要做两件事才能将耗时的计算和依赖性与集合分开:

1)在MyObject上,将获取缓存距离的逻辑和进行实际计算的逻辑分成不同的方法。

2) 按照策略模式将获取两个对象之间距离的逻辑移动到接口中:

以下是显示它的修改代码:

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) );
            }
          }
        }
     }

相关内容

最新更新