Le migliori pratiche nell'esporre l'interfaccia

0

Supponiamo di avere una classe che scarica i dati dall'API, la pulisce e la salva nel database. Quali metodi devo esporre?

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)
    {
    }
}

e utilizzo

// 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();

I miei pensieri: Nell'approccio 1 quando qualcuno vuole usare la classe deve chiamare il metodo nell'ordine corretto, che può creare bug se non lo fa. D'altra parte in approccio 3 è facile da usare, ma introduce poca magia (non sa cosa accadrà), ed è difficile da test unitario.

    
posta Szel 17.12.2015 - 12:11
fonte

3 risposte

2

I casi n. 1 e n. 2 sono non semplici test unitari, sono infatti più difficili per correttamente test unitario. Hanno molte sequenze di chiamate non valide che devi specificare il comportamento di

Il caso n. 3 è il più semplice da usare e testare; questo è generalmente vero perché i test dovrebbero rispecchiare l'utilizzo. Una maggiore complessità di utilizzo quasi sempre comporterà una maggiore complessità dei test. # 1 o # 2 dovrebbero essere usati solo se esiste un caso d'uso in cui sono necessari i singoli passaggi (ad es. Caricare i dati ma non salvare in db).

Anche allora probabilmente puoi fare di meglio impostando una fluent api in modo che le sequenze di chiamate non valide siano intrinsecamente impossibili, qualcosa come:

api.loadDataSet().clean().saveToDatabase();
    
risposta data 17.12.2015 - 12:30
fonte
0

A meno che non abbia senso chiamare queste operazioni separatamente, l'opzione 3 dovrebbe essere utilizzata.

Se queste operazioni devono essere chiamate solo in un ordine specifico, devono essere raggruppate in un'unica interfaccia coesiva.

Vorrei solo dividerli se fossero utili individualmente o forse l'opzione 3 ha portato a molti effetti collaterali nascosti.

    
risposta data 17.12.2015 - 12:52
fonte
0

Non dovresti aprire alcun metodo di business logic alla classe esterna.

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();
    
risposta data 17.12.2015 - 13:31
fonte

Leggi altre domande sui tag