#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;
}