The Problem
Recently I was told to refactor i.e. move some initialization logic from the constructor. I came up with something similar to the posted code. In actual there are bunch of loader classes inheriting from ILoader and doing all kind of stuff (TPL, DB access,XML parsing, CSV Writing) One of our UBER Developers reviewed my code and give some really appreciative comments particularly with the line of code marked with //<--:
Wow – I have seen a lot but that would make the http://thedailywtf.com/ for sure. HOW can you think of having a Getter method have a initialization SIDE EFFECT??
What is your opinion guys. What should I've done to avoid such appreciative comments?
The Solution
using System;
public class Program
{
public static void Main()
{
var obj = new TestLoader("testing");
Console.WriteLine("Calling Run() first time....");
obj.Run();
Console.WriteLine("Calling Run() again...");
obj.Run();
Console.WriteLine("Calling SomeOtherMethod()...");
obj.SomeOtherMethod();
}
}
//Class to make sure initialize will only be called once
public abstract class DataInitializer<T>
{
public bool IsInitialized { get { return _isInitialized.Value; } }//<--
readonly Lazy<bool> _isInitialized;
protected DataInitializer(T param)
{
Console.WriteLine("Inside DataInitializer constructor");
_isInitialized = new Lazy<bool>(Initialize);
}
protected abstract bool Initialize();
}
//Some loader class
public class TestLoader :DataInitializer<string>, ILoader
{
public TestLoader(string test):base(test)
{
}
protected override bool Initialize()
{
Console.WriteLine("Inside Initialize()");
return true;
}
public void Run()
{
if(IsInitialized)
{
Console.WriteLine("Inside Run()");
}
}
public void SomeOtherMethod()
{
if(IsInitialized)
{
Console.WriteLine("Inside SomeOtherMethod()");
}
}
}
interface ILoader
{
void Run();
void SomeOtherMethod();
}