У меня есть 2 типа, и каждый тип имеет разную логику обработки. На основании этой обработки я готовлю результат и возвращаю его потребителю (приложение mvc, консольное приложение и т.д.)
- Тип 1
- Тип 2
Теперь проблема в том, что некоторый код является общим для обоих типов. Единственная часть, которая отличается, - это класс (Type1Manager,Type2Manager
) для обоих типов, который фактически содержит логику для обработки type1 and type2
и подготовки результата (Type1Model,Type2Model
).
public class Variant
{
public int Id { get; set; }
public string Name { get; set; }
public List<Subvariants> Subvariants { get; set; }
}
public class Subvariants
{
public int Id { get; set; }
public string Name { get; set; }
}
public abstract class BaseManager
{
//Other shared code
public abstract ExecutionResult GetExecutionResult(Variant model);
}
public class ExecutionResult
{
public string Name { get; set; }
public string ErrorMessage { get; set; }
public bool Success { get; set; }
public List<Type1Model> Types1 { get; set; }
public List<Type2Model> Types2 { get; set; }
}
public abstract class BaseModel<T>
{
public string Name { get; set; }
public T Value { get; set; }
public T Coordinates { get; set; }
public decimal OverAllPercentage { get; set; }
}
public class Type1Model : BaseModel<int>
{
public decimal MiscPercentage { get; set; }
public int PerformanceCounter { get; set; }
}
public class Type2Model : BaseModel<decimal> { }
public class Type1 : BaseManager
{
public override ExecutionResult GetExecutionResult(Variant model)
{
var executionResult = new ExecutionResult();
executionResult.Name = model.Name;
var type1Result = new List<Type1Model>();
try
{
for (int counter = 0; counter < model.Subvariants.Count - 1; counter++)
{
var left = model.Subvariants[counter];
var right = model.Subvariants[counter + 1];
using (var t = new Type1Manager(model))
{
for (int i = 0; i < 2; i++)
{
if (i == 0)
{
t.Start(i);
if (counter == 0)
{
type1Result.Add(new Type1Model
{
Name = left.Name,
Value = t.Left
});
}
}
else
{
t.Start(i);
type1Result.Add(new Type1Model
{
Name = right.Name,
Value = t.Right,
Coordinates = t.Left + t.Right,
OverAllPercentage = t.OverAllPercentage,
PerformanceCounter = (t.NetPlus + t.AverageRatio),
MiscPercentage = t.MiscPercentage
});
}
}
}
}
executionResult.Types1 = type1Result;
}
catch (Exception ex)
{
executionResult.Success = false;
executionResult.ErrorMessage = ex.Message;
}
return executionResult;
}
}
internal class Type1Manager : IDisposable
{
private Variant model;
public int Right { get; private set; }
public int Left { get; private set; }
public int NetPlus { get; private set; }
public int AverageRatio { get; private set; }
public decimal OverAllPercentage { get; private set; }
public decimal MiscPercentage { get; private set; }
public Type1Manager(Variant model)
{
this.model = model;
}
public void Start(int i)
{
}
public void Dispose()
{
throw new NotImplementedException();
}
}
public class Type2 : BaseManager
{
public override ExecutionResult GetExecutionResult(Variant model)
{
var executionResult = new ExecutionResult();
executionResult.Name = model.Name;
var type2Result = new List<Type2Model>();
try
{
for (int counter = 0; counter < model.Subvariants.Count - 1; counter++)
{
var left = model.Subvariants[counter];
var right = model.Subvariants[counter + 1];
using (var t = new Type2Manager(model))
{
for (int i = 0; i < 2; i++)
{
if (i == 0)
{
t.Start(i);
if (counter == 0)
{
type2Result.Add(new Type2Model
{
Name = left.Name,
Value = t.Left
});
}
}
else
{
t.Start(i);
type2Result.Add(new Type2Model
{
Name = right.Name,
Value = t.Right,
Coordinates = t.Left + t.Right,
OverAllPercentage = t.OverAllPercentage,
});
}
}
}
}
executionResult.Types2 = type2Result;
}
catch (Exception ex)
{
executionResult.Success = false;
executionResult.ErrorMessage = ex.Message;
}
return executionResult;
}
}
internal class Type2Manager : IDisposable
{
private Variant model;
public decimal Right { get; private set; }
public decimal Left { get; private set; }
public decimal OverAllPercentage { get; private set; }
public Type2Manager(Variant model)
{
this.model = model;
}
public void Start(int i)
{
}
public void Dispose()
{
throw new NotImplementedException();
}
}
Проблема здесь, с которой я сталкиваюсь, заключается в том, что для Type1 needs Type1Model
а для Type2 needs Type2Model
. Даже если я попытаюсь BaseManager
общий код в своем классе BaseManager
, как бы я Type1Model and Type2Model
модели Type1Model and Type2Model
? Часть, с которой я борюсь, - это рефакторинг кода для обоих типов и перемещение некоторой общей логики в базовый класс.
Можно ли реорганизовать дубликаты кода для обоих типов и переместить их в базовый класс?
Обновить :
public abstract class BaseManager
{
public abstract ExecutionResult GetExecutionResult(Variant model);
public abstract void ExecuteAndSave(Variant model, string connectionString);
}
public class Type1 : BaseManager
{
public override void ExecuteAndSave(Variant model, string connectionString)
{
//other logic
var t = new Type1Manager(new SaveData());
}
public override ExecutionResult GetExecutionResult(Variant model)
{
var executionResult = new ExecutionResult();
executionResult.Name = model.Name;
var type1Result = new List<Type1Model>();
try
{
for (int counter = 0; counter < model.Subvariants.Count - 1; counter++)
{
var left = model.Subvariants[counter];
var right = model.Subvariants[counter + 1];
using (var t = new Type1Manager(new Repository()))
{
for (int i = 0; i < 2; i++)
{
if (i == 0)
{
t.Start(null,null);
if (counter == 0)
{
type1Result.Add(new Type1Model
{
Name = left.Name,
Value = t.Left
});
}
}
else
{
t.Start(null,null);
type1Result.Add(new Type1Model
{
Name = right.Name,
Value = t.Right,
Coordinates = t.Left + t.Right,
OverAllPercentage = t.OverAllPercentage,
PerformanceCounter = (t.NetPlus + t.AverageRatio),
MiscPercentage = t.MiscPercentage
});
}
}
}
}
executionResult.Types1 = type1Result;
}
catch (Exception ex)
{
executionResult.Success = false;
executionResult.ErrorMessage = ex.Message;
}
return executionResult;
}
}
internal class Type1Manager : IDisposable
{
public int Right { get; private set; }
public int Left { get; private set; }
public int NetPlus { get; private set; }
public int AverageRatio { get; private set; }
public decimal OverAllPercentage { get; private set; }
public decimal MiscPercentage { get; private set; }
private Repository _repository;
public Type1Manager(Repository repository)
{
this._repository = repository;
}
public void Start(string connectionString,string sqlQuery)
{
}
public void Dispose()
{
throw new NotImplementedException();
}
}
public class Repository
{
//Dont save result here.Used only for Type1
}
public class SaveData : Repository
{
//Save result here.Used only for Type1
}
public class Type2 : BaseManager
{
public override void ExecuteAndSave(Variant model, string connectionString)
{
//using (var t = new Type2Manager(2)//not hardcoded.taken from model
//Save data here returns from Type2Manager instance
}
public override ExecutionResult GetExecutionResult(Variant model)
{
var executionResult = new ExecutionResult();
executionResult.Name = model.Name;
var type2Result = new List<Type2Model>();
try
{
for (int counter = 0; counter < model.Subvariants.Count - 1; counter++)
{
var left = model.Subvariants[counter];
var right = model.Subvariants[counter + 1];
using (var t = new Type2Manager(2)) //not hardcoded.taken from model
{
for (int i = 0; i < 2; i++)
{
if (i == 0)
{
t.Start(null,null);
if (counter == 0)
{
type2Result.Add(new Type2Model
{
Name = left.Name,
Value = t.Left
});
}
}
else
{
t.Start(null,null);
type2Result.Add(new Type2Model
{
Name = right.Name,
Value = t.Right,
Coordinates = t.Left + t.Right,
OverAllPercentage = t.OverAllPercentage,
});
}
}
}
}
executionResult.Types2 = type2Result;
}
catch (Exception ex)
{
executionResult.Success = false;
executionResult.ErrorMessage = ex.Message;
}
return executionResult;
}
}
internal class Type2Manager : IDisposable
{
public decimal Right { get; private set; }
public decimal Left { get; private set; }
public decimal OverAllPercentage { get; private set; }
int precision;
public Type2Manager(int precision)
{
this.precision = precision;
}
public void Start(string connectionString, string sqlQuery)
{
}
public void Dispose()
{
throw new NotImplementedException();
}
}
- Варианты: Регион
- Подварианты: Субрегион
- Тип1: Аналитический калькулятор
- Тип 2: AggregateCalculator