2013-04-02 2 views
4

Я внедряю деревья Van Emde Boas, и я столкнулся с ситуацией, когда использование рекурсии в конструкторе невероятно полезно.Плохая практика использования рекурсии в конструкторе?

Когда я создаю корневой узел в дереве, этот узел будет иметь указатели на многие другие узлы, и эти узлы будут указывать на многие другие узлы и т. Д. Даже если они инициализированы нулевыми данными, я все равно хочу, чтобы они были там.

EDIT: В ответ на комментарий, я думал, что это может быть плохая практика, потому что мы всегда должны быть осторожны при распределении памяти. В этом случае пользователь может не знать о том, какие эффекты могут быть назначены для нового такого узла, и поэтому они могут выделять больше памяти, чем они предполагали? Другое то, что мне кажется, что просто выделить/опасно выделять память в конструкторе.

Код рекурсивно создает новые узлы, пока не будет создано полное дерево. Это плохая практика? Если это лучший способ сделать это на 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

Вы обычно нарушают "D" из ТВЕРДЫХ принципов:

принцип инверсии зависимостей

Этот принцип гласит:

A. Модули высокого уровня не должны зависеть от низкой -уровневые модули. Оба должны зависеть от абстракций. B. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций .

Действительно, ваш конструктор создает конкретный класс: self => не достаточно гибкий и трудно тестируемый. (рекурсия mocks? :))

Смежные вопросы