Относительно порядка инициализации переменных

#language-agnostic #initialization

#не зависит от языка #инициализация

Вопрос:

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

Вот так:

Все работает, если я инициализирую var A после var B . Но не наоборот. Я написал конструктор, поэтому я сделаю это сам, но я не совсем уверен, где должен быть код, который проверяет var B его существование. Или даже если он вообще должен существовать, потому что я написал конструктор и инициализирую значения в том порядке, который считаю нужным, но я чувствую, что это немного небезопасно, потому что он не очень надежен на случай, если что-то изменится.

Имейте в виду, я говорю о переменных экземпляра, если это поможет.

FA

Ответ №1:

На ответ может повлиять причина a , по которой он должен быть установлен раньше b .

Явные зависимости объектов

Если причина в том, что это b зависит от a , то самое простое, что нужно сделать, это сделать эту зависимость явной во время b создания. Например, если a и b были объектами, то:

 var a = new A(...);
var b = new B(a, ...);
var op = new Operation(b);
op.perform();
  

Таким образом, невозможно инициализировать объекты не по порядку. Обратите внимание, что A и B могут быть недавно введенными объектами-оболочками, которые содержат исходные параметры операции.

Свободный интерфейс

Если причина в том, что сама операция должна знать значение a , чтобы выполнить некоторую настройку при подготовке к прибытию b , тогда конструктор операции можно заменить свободным интерфейсом:

 Operation op = Operation.withA(a).withB(b);
op.perform();
  

Мы должны позаботиться о том, чтобы определить этот свободный интерфейс таким образом, чтобы withB он мог быть вызван только после withA того, как он был вызван. Например:

 public class Operation {

    private final C _c;
    private final B _b;

    private Operation(C c, B b) {
        _c = c;
        _b = b;
    }

    public static BStep withA(final A a) {
        return new BStep() {
            public Operation withB(B b) {
                C c = setUpStateDependentUponA(a);
                return new Operation(c, b);
            }
        };
    };

    public interface BStep {
        Operation withB(B b);
    }

    public void perform() {
        // do something with _c and _b
    }

}
  

Здесь C было введено для захвата того состояния, которое зависит от a одного до прибытия b . Обратите внимание, что конструктор Operation не виден для клиентского кода и withB не может быть вызван до тех withA пор, пока не будет вызван.

Ответ №2:

Я проверяю перед каждым обращением к переменной, но если это переменная экземпляра, и вы инициализируете B в конструкторе, вы должны быть в безопасности. Я использую что-то вроде-

 if (isset(var B)
{ do something with var A }
else 
{ error handler }
  

или

 try 
    {
        if (isset(var B))
            do something with a;
        else
            throw new Exception("attribute B has not been set.");
    } 
    catch (Exception $e) 
    {
        echo $e->getMessage();
        return NULL;
    }