Относительно порядка инициализации переменной - PullRequest
1 голос
/ 03 ноября 2011

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

Как это:

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

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

FA

Ответы [ 2 ]

1 голос
/ 06 ноября 2011

Ответ может зависеть от причины, по которой 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 могут быть вновь введенными объектами-обертками, которые содержат исходные параметры операции.

Fluent Interface

Если причина в том, что сама операциянеобходимо знать значение 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.

1 голос
/ 03 ноября 2011

Я проверяю перед каждым обращением к переменной, но если это переменная экземпляра, и вы инициализируете 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;
    }
...