重构箭头反模式

时间:2012-04-30 05:48:53

标签: java refactoring

我有一些我在单一方法中查询的数据。 它已经达到了箭头反模式的程度。 它看起来像这样:

void queryData()
{
    int masterIndex = getMasterIndex();
    if (masterIndex != -1)
    {
        byte[] pageData = getMasterPage(masterIndex);
        if (pageData) != null)
        {
            Item1 i1 = getItem1(pageData);
            Item2 i2 = getItem2(pageData);

            if (i1 != null && i2 != null)
            {
                showResults(i1, i2);
            }
        }
    }
}

想象一下上面但更大。更多if语句和每个被调用的方法都有相当多的逻辑。

现在我可以做的是重构上面的方法,所以所有if语句都是正数,如果为true则提前返回。

我觉得将每个查询和有效性检查分解为他们自己的类会更干净。 每个操作都将继承/实现如下界面:

public interface Action
{
    public void run();
    public boolean wasSuccessful();
}

我会创建所需操作的列表,并一次一个地运行它们。 通过这种方式,可以清楚地看到每个动作属于哪个逻辑。

这是架构吗?以上是我不知道的现有模式吗?

提前致谢。

2 个答案:

答案 0 :(得分:4)

我首先会滥用IDE的“提取方法”功能(如果有的话)并将每个逻辑分支拉出到自己的方法中。这样你就可以使代码更具可读性。

您可能希望首先开始编写单元测试,以确保重构的结果不会破坏或更改代码本身的业务逻辑。一旦您重构为较小的方法并确信代码仍然按原定的方式工作,您就可以查看是否可以创建类并将代码提取到那些代码中。

我不会说创建类以使您的查询和有效性检查过度设计,只要它有意义且可读。如您所说,您可以拥有List<Action>,然后循环调用每个run()方法,然后在每个方法上检查wasSuccessful()并根据需要输出信息。

这样,如果您想要更改给定操作的验证或查询,只需更改功能封装的类,您就不必更改实际的执行代码。

答案 1 :(得分:2)

看看早期的回报是多么清洁:

void queryData()
{
    int masterIndex = getMasterIndex();
    if (masterIndex == -1) 
        return;
    byte[] pageData = getMasterPage(masterIndex);
    if (pageData == null)
        return;
    Item1 i1 = getItem1(pageData);
    Item2 i2 = getItem2(pageData);
    if (i1 == null || i2 == null)
        return;
    showResults(i1, i2);
}

我认为这比创建额外的类结构更好。