Refactoring methods that use the same code but different methods inside

I have several methods that are the same except for one line (I call different methods on the object client). I will have more of these methods.

Is there any solution for this other than using Reflection?

 private void initClerks(Client client)
            {
                string[] pks = client.ClerksPKS.Trim(','). Split(',');

                foreach (string pk in pks)
                {
                    string data = JObject.Parse(DBUtils.GetData(Constants.DBProcedures.GetProcedures.GetWorkerDetailsByPkid, pk))[Constants.ResponseJson.Data].ToString();

                    client.addClerk(JsonConvert.DeserializeObject<Clerk[]>(data)[0]);

                }

            }


private void initManagers(Client client)
            {
                string[] pks = client.ManagerPK.Trim(',').Split(',');



                foreach (string pk in pks)
                {
                    string data = JObject.Parse(DBUtils.GetData(Constants.DBProcedures.GetProcedures.GetWorkerDetailsByPkid, pk))[Constants.ResponseJson.Data].ToString();
                    client.addManager(JsonConvert.DeserializeObject<Manager[]>(data)[0]);

                }

            }
+4
source share
4 answers

You can do this by passing an action to a method. Sort of

private void actOnData(Client client, string[] pks, Action<Client, string> addThing)
{
    foreach (string pk in pks)
    {
        string data = JObject.Parse(DBUtils.GetData(Constants.DBProcedures.GetProcedures.GetWorkerDetailsByPkid, pk))[Constants.ResponseJson.Data].ToString();
        addThing(client, data);
    }
}

private void initClerks(Client client)
{
    string[] pks = client.ClerksPKS.Trim(',').Split(',');
    actOnData(client,pks,(c,d) => { c.addClerk(JsonConvert.DeserializeObject<Clerk[]>(d)[0]); });
}

private void initManagers(Client client)
{
    string[] pks = client.ManagerPK.Trim(',').Split(',');
    actOnData(client, pks, (c, d) => { c.addManager(JsonConvert.DeserializeObject<Manager[]>(d)[0]); });
}
+6
source

Taking into account that this is not an external obsolete library, I would suggest refactoring the Client class, as well as simplify its API (I would change more, but let me stop at some point)

pseudo code:

// taking into account Client, manager all are workers
class Client
{
    // further whenever you need filter out managers use LINQ OfType<>
    List<Workers> workers;

    public void Add<T>(T worker) where T: Worker
    {
        workers.Add(client);
    }
}

. ,

private void Initialize<T>(Client client, string[] pks)
{
    foreach (string pk in pks)
    {
        string data = JObject.Parse(DBUtils.GetData(Constants.DBProcedures.GetProcedures.GetWorkerDetailsByPkid, pk))[Constants.ResponseJson.Data].ToString();
        client.Add(JsonConvert.DeserializeObject<T[]>(data)[0]);    
    }
}

private void initClerks(Client client)
{
    string[] pks = client.ClerksPKS.Trim(',').Split(',');
    Initialize<Clerk>(client, pks);
}

private void initManagers(Client client)
{
    string[] pks = client.ManagerPK.Trim(',').Split(',');
    Initialize<Manager>(client, pks);           
}

, intiClerks/initmanagers , Initialize (, , )

+4

. initClerks Clerk . , Type, T, Clerk. -

(1) client.ClerksPKS Func<Client, string>
(2) JsonConvert.DeserializeObject<Clerk[]> JsonConvert.DeserializeObject<T[]>
(3) client.addClerk Action<Client, T>

,

void Init<T>(Client client, Func<Client, string> getPKS, Action<Client, T> addItem)
{
    string[] pks = getPKS(client).Trim(','). Split(',');
    foreach (string pk in pks)
    {
        string data = JObject.Parse(DBUtils.GetData(Constants.DBProcedures.GetProcedures.GetWorkerDetailsByPkid, pk))[Constants.ResponseJson.Data].ToString();
        addItem(client, JsonConvert.DeserializeObject<T[]>(data)[0]);
    }
}

private void initClerks(Client client)
{
    Init<Clerk>(client, c => c.ClerksPKS, (c, x) => c.addClerk(x));
}

private void initManagers(Client client)
{
    Init<Manager>(client, c => c.ManagerPK, (c, x) => c.addManager(x));
}
+2

Init. , BaseClientInitializer, Insert. .

public abstract class BaseClientInitializer
  {
    private string[] keys;
    public BaseClientInitializer(string[] keys)
    {
      this.keys = keys;
    }
public abstract void Insert(string data);

public void Init()
{
  foreach (string pk in keys)
  {
    var data = JObject.Parse(DBUtils.GetData(Constants.DBProcedures.GetProcedures.GetWorkerDetailsByPkid, pk))[
        Constants.ResponseJson.Data].ToString();
    this.Insert(data);
  }
}   


 }

public class Clerks : BaseClientInitializer
  {
    private Client client;
    public Clerks(Client client) : base(client.ClerksPKS.Trim(','). Split(','))
    {
      this.client = client;
    }

    public override void Insert(string data)
    {
      client.addClerk(JsonConvert.DeserializeObject<Clerk[]>(data)[0]);
    }
  }

private void initClerks(Client client)
{
     var clerksInitializer = new ClerksInitializer(client);
    clerksInitializer.Init();
}

. , pks : client.ClerksPKS.Trim(','). Split (',') - client.ManagerPK.Trim(','). (',') . , .

0

Source: https://habr.com/ru/post/1622201/


All Articles