我有一些方法是相同的,除了一行(我在对象客户端上调用不同的方法)。 我会有更多这样的方法。
除了使用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]);
}
}
答案 0 :(得分:6)
您可以通过将操作传递给方法来完成此操作。像
这样的东西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]); });
}
答案 1 :(得分:4)
考虑到这不是外部遗留的lib我会建议重构Client类以简化它的API(我会改变更多,但让我们在某些时候停止)
伪代码:
// 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);
}
}
请参阅Extract method方法,
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
的内联调用(当然,如果整个代码库不比你在这里显示的更复杂)
答案 2 :(得分:2)
提取方法的典型路径是找到差异并声明相应的方法参数。我们采用您的initClerks
方法,在里面找到Clerk
这个词。其中有3个,其中一个是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));
}
答案 3 :(得分:0)
创建基类以在其基础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();
}
对init管理员执行相同操作。 区别不仅在于插入方法,pks数组也不同:client.ClerksPKS.Trim(',')。拆分(',') - 用于职员和client.ManagerPK.Trim(',')。拆分(',')为经理。因此简单的提取方法将无法正常工作。