0

Let's assume I have a class that downloads data from API, cleans it and saves to database. What methods should I expose?

class ApiConnector1
{
    public string GetDataFromApi()
    {
        // ...
    }

    /// <summary>
    /// removes unnecessary records
    /// </summary>
    public string CleanApiData(string apiData)
    {
        // ...
    }

    public bool SaveToDb(string processedData)
    {
        // ...
    }
}

class ApiConnector2
{
    public string GetDataFromApi()
    {
        // ...
    }

    public bool SaveData(string processedData)
    {
        SaveToDb(CleanApiData(processedData));
    }

    /// <summary>
    /// removes unnecessary records
    /// </summary>
    private string CleanApiData(string apiData)
    {
        // ...
    }

    private bool SaveToDb(string processedData)
    {
        // ...
    }
}

class ApiConnector3
{
    public bool GetDataToDb()
    {
        SaveToDb(CleanApiData(GetDataFromApi()));
    }

    private string GetDataFromApi()
    {
    }
    private string CleanApiData(string apiData)
    {
    }
    private bool SaveToDb(string processedData)
    {
    }
}

and usage

// ApiConnector1 usage
var apiConnector = new ApiConnector1();
var apiData = apiConnector.GetDataFromApi();
// show information that data was successfull downloaded
var cleanData = apiConnector.CleanApiData(apiData);
apiConnector.SaveToDb(cleanData);


// ApiConnector2 usage
var apiConnector2 = new ApiConnector2();
var apiData2 = apiConnector2.GetDataFromApi();
// show information that data was successfull downloaded
apiConnector2.SaveData(apiData2);


// ApiConnector3 usage
var apiConnector3 = new ApiConnector3();
apiConnector3.GetDataToDb();

My thoughts: In Approach 1 when somebody want to use class he have to call method in proper order, which can create bugs if he not. On the other hand in approach 3 is easy to use but introduces little magic (he doesn't know what will happen), and is hard to unit test.

3 Answers 3

2

Case #1 and #2 are not easy to unit test, they are in fact more difficult to properly unit test. They have lots of invalid call sequences that you have to specify the behavior of.

Case #3 is simplest to both use and test; this is generally true because tests should mirror usage. Greater complexity of usage is almost always going to mean greater complexity of testing. #1 or #2 should only be used if there is a use case where the individual steps are necessary (e.g load data but don't save to db).

Even then you can probably do better by setting up a fluent api so that invalid call sequences are inherently impossible, something like:

api.loadDataSet().clean().saveToDatabase();
0

Unless is makes sense to call these operations separately then option 3 should be used.

If these operations should only be called in a specific order then they should be grouped into a single cohesive interface.

I would only look at splitting these up if they were useful individually or perhaps option 3 resulted in many hidden side effects.

0

You should not open any business logic method to outer class.

class ApiConnector
{
    private string GetDataFromApi()
    {
        //Logic
    }
    private void CleanApiData(string apiData)
    {
        //Logic
    }
    private void SaveToDb(string processedData)
    {
        //Logic
    }

    public GetDataAndSeaveToDB()
    {
       var appdata=null;

       appdata = GetDataFromApi();

       //validateData received data

       CleanApiData(appdata);
       SaveToDb(appdata);
    }
}


var apiConnectorObj = new ApiConnector();
apiConnectorObj.GetDataAndSeaveToDB();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.