mercredi 21 décembre 2022

What should I do when I want a heavy method executed in constructor?

I have a heavy method to run before any other methods in the class, because I need to initialize something (e.g: getting some data from a database and initialize some fields in the class).

I have Provider1 class like this :

public class Provider1
{
    private readonly string _connectionString;
    private readonly List<string> _data;
    private bool _isInitialized;

    public Provider1(string connectionString)
    {
        _connectionString = connectionString;

        // Nothing else to do here 
        // And the caller should to know to call the `Initialize` method him/herself
        // If he/she forgot to Initialize, then I will throw an exception
    }

    public void Initialize_HeavyWorkButItMustBeExecutedBeforeAnyOtherMethods(params string[] tableNames)
    {
        // _data = filling _data from a database

        // 
        _isInitialized = true;
    }

    public void Method_WorkWithData()
    {
        // At this point, I want to be sure that `_data` already populated
        // what should I do?

        // e.g: using a field to determine the initlization:
        if (_isInitialized)
        {
            // Do some works
        }
        else
        {
            throw new Exception("You have to initialize first");
        }
    }
}

And I have Provider2 class as below:

public class Provider2
{
    private readonly string _connectionString;
    private readonly IEnumerable<string> _tableNames;
    private readonly List<string> _data;

    public Provider2(string connectionString, params string[] tableNames)
    {
        _connectionString = connectionString;
        _tableNames = tableNames;

        // call initialize method here in constructore, so the caller don't need to call it seperately
        Initialize_HeavyWorkButItMustBeExecutedBeforeAnyOtherMethods();
    }

    private void Initialize_HeavyWorkButItMustBeExecutedBeforeAnyOtherMethods()
    {
        // _data = filling _data from a database
    }

    public void Method_WorkWithData()
    {
        // Do some works
    }
}

And this is the caller's class:

void Main()
{
    // 1 :
    var theProvider1 = new Provider1("....");

    // The caller have to call this Initialize method before any other methods: 
    theProvider1.Initialize_HeavyWorkButItMustBeExecutedBeforeAnyOtherMethods("table1", "table2", "table3");

    theProvider1.Method_WorkWithData();

    // 2 :
    var theProvider2 = new Provider2("....", "table1", "table2", "table3");
    
    // The caller don't need to initialize anything, because everything happened in one place (constructor)
    // and he/she can call the business method
    
    theProvider2.Method_WorkWithData();
}

What is the best way to initialize a complex object before calling any other methods in the class?

Aucun commentaire:

Enregistrer un commentaire