Felipe
Felipe

Reputation: 11887

Regarding variable initialization order

I'd like to know what's the default approach for those times when you need a variable to have been set in order for a given method/another variable initialization to work.

Like this:

Everything works if I initialize var A after var B. But not the other way around. I wrote the constructor, so I'll do that myself, but I'm not really sure where the code that tests for var B's existence should be. Or even if it should exist at all, for I have written the constructor and I initialize the values the order I see fit, but I feel it's a little insecure because it is not very robust in case anything changes.

Mind you, I'm talking about instance variables, if that helps.

FA

Upvotes: 1

Views: 45

Answers (2)

WReach
WReach

Reputation: 18271

The answer can be influenced by the reason why a must be set before b.

Explicit Object Dependencies

If the reason is that b depends upon a, then the simplest thing to do is to make that dependency explicit at the time that b is created. For example, if a and b were objects then:

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

In this way, it is not possible to initialize the objects out of order. Note that A and B could be newly introduced wrapper objects that contain the original operation parameters.

Fluent Interface

If the reason is that the operation itself must know the value of a in order to perform some configuration in preparation for the arrival of b, then the operation constructor could be replaced by a fluent interface:

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

We must take care to define this fluent interface in such a way that withB can only be called after withA has been called. For example:

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
    }

}

Here, C has been introduced to capture that state that is dependent upon a alone prior to the arrival of b. Note how the constructor of Operation is not visible to client code and that withB cannot possibly be called until after withA has been called.

Upvotes: 1

Sinthia V
Sinthia V

Reputation: 2093

I check before each time I access the variable, but if it is an instance variable and you initialize B in the constructor you should be safe. I use something like-

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

or

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

Upvotes: 1

Related Questions