Reputation: 11887
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
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
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