2016-05-26 132 views
-4

我写了一些像这样的代码在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不支持通过参数引用值。这对我来说真是一个难题。

+0

* *之前的代码是什么? – Kayaman

回答

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可以是一种冗长的语言,并且一目了然地编写代码。

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; 

的代码的其余部分可能也得到改善。它看起来像longitude,latitutevelocitypublic字段ds。代替它们来封装它们可能是一个更好的主意。

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

如果您不需要改变状态的ds,考虑做田野final,在构造函数中为它们分配和方法在你的问题返回DS'类型的新对象,

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 
} 

然后您的方法中的代码可能看起来像:

int longitude = -1; // or whatever default values you're assigning 
    int latitude = -1; 
    short velocity = -1; 

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

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

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

    return new WhateverType(longitude, latitude, velocity);