是否有可能重构此Java代码?

时间:2009-05-06 06:07:13

标签: java refactoring

我在下面有一个简单的代码:

import java.util.ArrayList;

public class BoidList extends ArrayList
{
  synchronized public Boid GetBoid( int idx_ ) throws ArrayIndexOutOfBoundsException
  {
    if( idx_ <  super.size() &&
        idx_ >= 0 )
    {
      return (Boid) super.get(idx_);
    }
    else
    {
      throw new ArrayIndexOutOfBoundsException();
    }
  }
  synchronized public void RemoveBoid( int idx_ ) throws ArrayIndexOutOfBoundsException
  {
    if( idx_ <  super.size() &&
        idx_ >= 0 )
    {
      super.remove(idx_);
    }
    else
    {
      throw new ArrayIndexOutOfBoundsException();
    }    
  }
}

两种方法之间有很多相似之处,但它们做了两件不同的事情。有可能重构这个吗?

9 个答案:

答案 0 :(得分:20)

BoidList的真正目的是什么?请考虑以下事项:

List<Boid> boids = Collections.synchronizedList(new ArrayList<Boid>());

这行代码或多或少等同于您尝试创建的子类:

  • 在编译时强制执行类型安全
  • 如果索引无效,
  • ArrayList已经抛出IndexOutOfBoundsException
  • Collections.synchronizedList()确保对列表的同步访问

根据您提供的源代码,我认为没有任何理由创建您自己的子类。

答案 1 :(得分:12)

public class BoidList extends ArrayList<Boid> {

    private void checkIndex(int idx) {
        if (idx >= super.size() || idx < 0) {
            throw new ArrayIndexOutOfBoundsException(String.valueOf(idx));
        }
    }

    synchronized public Boid getBoid(int idx) {
        checkIndex(idx);
        return super.get(idx);
    }

    synchronized public void removeBoid(int idx) {
        checkIndex(idx);
        super.remove(idx);
    }
}

这可以通过多种方式修复您的代码:

  • checkIndex()方法就是你想要的
  • 从不声明抛出RuntimeException,因为它是编程错误
  • 遵循java命名约定(GetBoid - &gt; getBoid,RemoveBoid - &gt; removeBoid)
  • 删除无用的强制转换只是扩展ArrayList

修改

您可能还想查看CopyOnWriteArrayList&lt; Boid&gt;

答案 2 :(得分:4)

仅为了您的信息,ArrayList类具有执行边界检查的getremove方法,如果指定的索引超出范围,则抛出IndexOutofBoundsException列表。

除非目标平台在Java 5下,否则使用generics可能是更优选的方法。使用泛型,可以确保ArrayList的内容都是相同的类型,这将消除执行类型转换,类型检查和面对可能ClassCastException的需要。

例如:

List<String> list = new ArrayList<String>();
list.add("Hello");
list.add("World");
String s = list.remove(0);    // No need for typecasting.

list.add(10);                 // Compile error, as 10 is not of type String.

答案 3 :(得分:3)

您可以将检查有效性的代码提取到单独的方法中:

private void checkIndex(int i) throws ArrayIndexOutOfBoundsException
{
  if (idx < 0 || idx_ >= super.size()) {
    throw new ArrayIndexOutOfBoundsException();
  }
}

synchronized public void RemoveBoid( int idx_ ) throws ArrayIndexOutOfBoundsException
{
  checkIndex(idx_);
  super.remove(idx_);
}

此外,您还需要扩展java.util.ArrayList [Boid]。

但扩展java.util.ArrayList似乎是一个坏主意。你为什么要这样做?

答案 4 :(得分:1)

我认为它们是完全不同的,一个通过指定索引获取一个对象,另一个删除它,无论代码是否相似,方法执行的任务都是完全相反的。

答案 5 :(得分:1)

你为什么要打扰?

较少的代码不是目标(除了perl one liner竞赛:-))。

编码风格应该有三个目标: - 清晰度,正确性和运行时效率。

原始代码足够清晰,大概是正确的,并且可以像使用java集合的任何东西一样有效地运行。

任何重构尝试都会使类本身不那么清晰,并且使得使用该类的任何代码都不太清楚。任何更改都可能会引发错误,因此它不太正确,并且不太可能更有效地使用数组类。

答案 6 :(得分:0)

您可以编写如下函数:

private boolean checkIndex( int _idx ) throws ArrayIndexOutOfBoundsException {
    if ( idx_ <  super.size() && idx_ >= 0 ) {
         return true;
    } else {
         throw ArrayIndexOutOfBoundsException();
    }
}

然后使用此方法进行检查。但是,这可能只比您已使用的代码提供了一个小优势。

你绝对不应该做的是尝试在你已经拥有的2个方法中制作1个方法。这基本上违反了我所知道的每个OO原则; - )

答案 7 :(得分:0)

您可以将其重构为getOrRemoveBoid方法,其中参数可以处理决策。但这看起来像代码味道。这些方法具有不同的语义,应该分开。

该类的大部分内容是关于异常处理和语言语法。你不应该混合方法,它们足够干燥。

答案 8 :(得分:-1)

不要为了它而重构!

唯一可能的部分:

idx_ <  super.size() && idx_ >= 0

可能是浪费时间(如果多次执行此操作,进入新的“isValidIndex(int)”方法可能会对未经修改的代码造成性能损失。)