如何使这段代码更好?

时间:2016-05-26 09:38:42

标签: java

我在Java中写了这样的代码:

    //...
    if(dsLen>=4){
        ds.longitude = buff.readInt();
        dsLen-=4;
    }
    else{
        return ds;
    }

    if(dsLen>=4){
        ds.latitude = buff.readInt();
        dsLen-=4;
    }
    else{
        return ds;
    }

    if(dsLen>=2){
        ds.velocity = buff.readShort();
        dsLen-=2;
    }
    else{
        return ds;
    }
    //...

看起来很难看。我怎样才能改进它?

据我所知,Java不支持通过参数引用值。这对我来说真是个谜。

2 个答案:

答案 0 :(得分:0)

您可以像这样定义一个类:

class MaybeReader {
  BufferType buff;
  int dsLen;
  boolean failed = false;

  // Add a constructor to populate buff and dsLen appropriately.

  boolean failed(long obj) {
    return failed;
  }

  int maybeReadInt(int defaultValue) {
    if (dsLen >= 4) {
      dsLen -= 4;
      return buff.readInt();
    } else {
      failed = true;
      return defaultValue;
    }
  }

  short maybeReadShort(short defaultValue) {
    if (dsLen >= 2) {
      dsLen -= 2;
      return buff.readShort();
    } else {
      failed = true;
      return defaultValue;
    }
  }
}

然后你可以像这样合理地调用它:

MaybeReader m = new MaybeReader(...);
if (m.failed(ds.longitude = m.maybeReadInt(ds.longitude))
    || m.failed(ds.latitude = m.maybeReadInt(ds.latitude))
    || m.failed(ds.velocity = m.maybeReadShort(ds.velocity)) {
  return ds;
}

其工作原理如下:

  • 您需要传入该字段的当前值,以便在无法从缓冲区中读取值时将其写回。
  • 如果有足够的数据,maybeRead*方法将从缓冲区中读取;否则,它们返回默认值,并将实例设置为“失败”状态。
  • 然后maybeRead*的结果会传回failed。实际上并没有使用该参数,只是将赋值用作布尔表达式而不是语句。这涉及到long的扩大演员阵容;如果需要,可以为特定的基元类型添加重载。
  • ||的快速评估意味着只要其中一个maybeRead*来电失败,执行就会停止。

然而:我认为这不是特别直观的阅读;特别是,具有多种副作用(分配)的表达被认为难以阅读。我只是接受Java可以是一种冗长的语言,并编写一目了然的代码。

答案 1 :(得分:0)

如果在执行return语句后dsLen的值无关紧要,则可以将代码简化为

    if (dsLen >= 4) {
        ds.longitude = buff.readInt();
    }

    if (dsLen >= 8) {
        ds.latitude = buff.readInt();
    }

    if (dsLen >= 10) {
        ds.velocity = buff.readShort();
    }

    return ds;

其余代码也可以改进。看起来longitudelatitutevelocitypublic的{​​{1}}字段。将它们ds改为封装它们可能是个更好的主意。

如果您确实需要在代码的其他部分更改private的状态,请使用setter。

如果您不需要更改ds的状态,请考虑创建字段ds,在构造函数中指定它们并在您的问题中的方法中返回ds'类型的新对象,

final

然后您的方法中的代码可能如下所示:

public final class WhateverType {

    private final int longitude;
    private final int latitude;
    private final short velocity;

    public WhateverType(int longitude, int latitude, short velocity) {
        this.longitude = longitude;
        this.latitude = latitude;
        this.velocity = velocity;
    }

    // rest of the code
}