Consider this: public MyClass { private Resource _myResource; public Resource My
ID: 642869 • Letter: C
Question
Consider this:
public MyClass
{
private Resource _myResource;
public Resource MyResource
{
get
{
if(_myResource == null)
{
_myResource = new Resource();
}
return _myResource;
}
}
public void UseResource()
{
MyResource.DoSomething();
}
}
Is this a recognised pattern, or possibly an anti-pattern? I've never seen it suggested in any books, but it does come up time and time again in code I see. I think the logic of this is that _myResource is instantiated 'just in time'. To me, it seems a bit smelly. UserResource() is accessing a public property from within the class, and the resource can never really be accessed through the private member - if someone did, _myResource could be null.
Maybe performance reasons may sometimes necessitate, but I would generally favour instantiating in the constructor, or just having an instance of Resource local to the method.
So is this an accepted pattern, or should it be avoided?
Explanation / Answer
This is an accepted pattern. It's called lazy initialization, a creational pattern. You usually use this for performance reasons, often combined with other patterns, for example the Proxy Pattern. When resources are heavy and you don't need them right away, then this is a good and clean approach to make sure they're only initialized the first time you need them.
Wikipedia calls it a "tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed".
ORMs for example use this pattern to perform lazy initializations of related entities, so you needn't fetch a whole aggregate object-graph eagerly, but only when you really need to operate on the related entities.
Maybe performance reasons may sometimes necessitate, but I would generally favour instantiating in the constructor, or just having an instance of Resource local to the method.
Sure, this might be a cleaner approach. But if the resources are really costly to instantiate, then lazy initialization is a good way to deal with them. Do you really want to wait a long time for instantiating an object that by itself is lightweight, but occasionally needs a heavy resource?
To me, it seems a bit smelly. UserResource() is accessing a public property from within the class, and the resource can never really be accessed through the private member - if someone did, _myResource could be null.
It looks indeed a bit smelly and if it is used everywhere and not by its purpose then it really stinks. As with all optimizations: Don't optmize if you don't need an optimization. But lazy initialization can be a great benefit to your application when used right. And then its inconspicuous smell is a small price to pay for its worth.