2013-04-02 53 views
4

我正在实施van Emde Boas树,并且遇到了在构造函数中使用递归非常有用的情况。在构造函数中使用递归是不好的做法?

当我在树中创建根节点时,该节点将具有指向许多其他节点的指针,并且这些节点将指向许多其他节点,依此类推。即使这些数据是空数据,我仍然希望他们都在那里。

编辑:在回答评论时,我认为这可能是不好的做法,因为我们在分配内存时总是需要小心。在这种情况下,用户可能不知道分配新节点可能会产生的效果,因此他们可能会分配更多的内存,然后他们打算这么做?除此之外,我认为在构造函数中分配内存似乎很奇怪/很危险。

该代码以递归方式创建新节点,直到创建完整的树为止。这是一种不好的做法吗?如果是的话,有没有更好的方式在Java中做到这一点?

//Constructor 
public VEBNode(int universeSize) 
{ 
    this.universeSize = universeSize; 
    min = vEBTree.NULL; 
    max = vEBTree.NULL; 

    if(universeSize <= 2) 
    { 
     summary = null; 
     cluster = null; 
    } 
    else 
    { 
     int childUnivereSize = (int)Math.sqrt(universeSize); 

     summary = new VEBNode(childUnivereSize); 
     cluster = new VEBNode[childUnivereSize]; 

     for(int i = 0; i < childUnivereSize; i++) 
     { 
      cluster[i] = new VEBNode(childUnivereSize); 
     } 
    } 
} 
+2

你为什么认为这可能是一个不好的做法? –

+0

在您的位置,我可能会保持构造函数非常基本,并将所有这些逻辑移至静态工厂方法,但这是一种风格判断调用。 –

+0

我认为递归是相当适合你的情况的方式,无论是构造函数还是其他函数。 – skuntsel

回答

1

一般来说,在构造函数中做资源密集型的东西可能会被建议。

将“构造函数”与“构建整棵树”分开如何?

另外,你打算有子类?

+0

我不打算继承这个。 – CPlayer

2

我不能认为这可能被认为是不好的做法。

构造函数意味着完全构建一个类的实例,所以如果需要递归,那么使用它就没有错。

但是,为了清楚起见,您可能希望保留一个简单的构造函数并在另一个(私有)方法中实现递归......但这取决于您。当然,如果你把递归放在另一个方法中,你可以从你的构造函数中调用它。结果是一样的,但代码可能看起来更清晰和更清晰。

+0

我同意将逻辑移至init方法或工厂方法会更可取。好建议。 – CPlayer

+1

请确保您不会从构造函数传递任何对'this'的引用,但...... –

0

构造函数是一个地方,你生下你的对象。它应该简单而直接。

如果您需要用某些值初始化对象 - 将这些值的计算外化。

据我所知,从构造函数调用方法是一种不好的做法。我会使用一个委托类,它封装了所有的逻辑。

将所有复杂的逻辑放在一个单独的服务类中(但又是 - 不在构造函数中)并使用 - 将所有计算委托给该服务类。

构造函数只是太敏感的地方来保存复杂的(其中包括递归)逻辑。

0

如果你打算继承这个类 - 那么递归会给你带来很多痛苦,因为你将无法重载这个构造器,所以你创建了一个子类的实例。

3

您通常违反的SOLID原则 “d”:

依赖倒置原则

该原则指出:

A.高层模块不应该依赖于 低级模块。两者都应该依赖于抽象。 B.抽象 应该不取决于细节。细节应取决于 抽象。

事实上,你的构造函数实例化一个具体的类:自身=>没有足够的灵活性和难以测试。 (递归的模拟?:))

相关问题