Reputation: 17701
I have code where i am passing bunch of inputs to the method and adding to the database with entities inside that method like the below
public class SpaceTypeServices
{
public Guid CreateRequest(
SpaceTypeInput spaceTypeInput,
MasterSection masterSection,
RequestInput requestInputs,
APIDbContext dbContext)
{
var id = Guid.NewGuid();
var mechanicalData = new MechanicalData();
var mechanicalTypeData = new MechanicalTypeData();
var environmentCondition = new EnvironmentConditions
{
ConditionType = spaceTypeInput.EnvironmentConditionsInput.ConditionType,
CoolingSetPointOccupied = spaceTypeInput.EnvironmentConditionsInput.CoolingSetPointOccupied ?? 0,
CoolingSetPointUnOccupied = spaceTypeInput.EnvironmentConditionsInput.CoolingSetPointUnOccupied ?? 0,
HeatingSetPointOccupied = spaceTypeInput.EnvironmentConditionsInput.HeatingSetPointOccupied ?? 0,
RelativeHumidityMax = spaceTypeInput.EnvironmentConditionsInput.RelativeHumidityMax ?? 0,
RelativeHumidityMin = spaceTypeInput.EnvironmentConditionsInput.RelativeHumidityMin ?? 0
};
var exhaustType = new Exhaust
{
AirflowPerArea = spaceTypeInput.ExhaustInput.AirflowPerArea ?? 0,
AirflowPerFixture = spaceTypeInput.ExhaustInput.AirflowPerFixture ?? 0,
MaxExhaustAirChange = spaceTypeInput.ExhaustInput.MaxExhaustAirChange ?? 0,
MinExhaustAirChange = spaceTypeInput.ExhaustInput.MinExhaustAirChange ?? 0,
ExhaustSource = spaceTypeInput.ExhaustInput.ExhaustSource
};
var thermalComfort = new ThermalComfort
{
AirSpeed = spaceTypeInput.ThermalComfortInput.AirSpeed ?? 0,
ClothingInsulation = spaceTypeInput.ThermalComfortInput.ClothingInsulation ?? 0,
MetabolicRate = spaceTypeInput.ThermalComfortInput.MetabolicRate ?? 0
};
// bunch of code same like as above object initialization
mechanicalData.Exhaust = exhaustType;
mechanicalData.Environment = environmentCondition;
mechanicalData.ThermalComfort = thermalComfort;
// bunch of assigning objects
mechanicalTypeData.MechanicalData = mechanicalData;
var spaceType = new SpaceType
{
MechanicalTypeData = mechanicalTypeData,
Description = spaceTypeInput.Description,
};
dbContext.SpaceTypes.Add(spaceType);
dbContext.SaveChanges();
return id;
}
I am looking a way to convert this procedural to more generic way refactoring but could not be able to figure it out to do the same.
Could any one have any idea or any suggestions on how to refactor these things in more OO approach or generic way that would be very grateful to me.
many thanks in advance
update :
i am looking kind of generic method like this
public T myFunction<T>(int id, string name) where T : class1, new()
{
T obj = new T();
obj.id = id;
obj.name = name;
return obj;
}
Upvotes: 0
Views: 135
Reputation: 13930
Could any one have any idea or any suggestions on how to refactor these things in more OO approach or generic way that would be very grateful to me.
Constructing an object with anything other than a parameter-less constructor creates some level of responsibility on the caller to know details about that object. The more complex the object construction is, the more burdensome it is on the caller. For example:
var environmentCondition = new EnvironmentConditions
{
ConditionType = spaceTypeInput.EnvironmentConditionsInput.ConditionType,
CoolingSetPointOccupied = spaceTypeInput.EnvironmentConditionsInput.CoolingSetPointOccupied ?? 0,
CoolingSetPointUnOccupied = spaceTypeInput.EnvironmentConditionsInput.CoolingSetPointUnOccupied ?? 0,
HeatingSetPointOccupied = spaceTypeInput.EnvironmentConditionsInput.HeatingSetPointOccupied ?? 0,
RelativeHumidityMax = spaceTypeInput.EnvironmentConditionsInput.RelativeHumidityMax ?? 0,
RelativeHumidityMin = spaceTypeInput.EnvironmentConditionsInput.RelativeHumidityMin ?? 0
};
This example shows that we're responsible for not only knowing that EnvironmentConditions
depends on an EnvironmentConditionsInput
(not so bad), but we also must know the properties of both and worse, we must perform the error checking/default values. Because this is done explicitly in the callers, the construction code is required to be repeated correctly everywhere an EnvironmentConditions
is created. This becomes a real issue if these classes change.
Let's assume the definition of EnvironmentConditions
requires another property. That will require every instance of this code to be changed to support the new property correctly. If there is "a bunch of code" doing this, the request code has a bunch of reasons to change possibly for different reasons, at different times, at different frequencies; does the service and its developers really need to worry about all that? Why not just pass the input object into the conditions class and have this code change applied everywhere at once?
public class EnvironmentConditions
{
...
public EnvironmentConditions(EnvironmentConditionsInput input)
{
ConditionType = input.ConditionType;
CoolingSetPointOccupied = input.CoolingSetPointOccupied ?? 0;
CoolingSetPointUnOccupied = input.CoolingSetPointUnOccupied ?? 0;
HeatingSetPointOccupied = input.HeatingSetPointOccupied ?? 0;
RelativeHumidityMax = input.RelativeHumidityMax ?? 0;
RelativeHumidityMin = input.RelativeHumidityMin ?? 0;
// some new property
}
}
// new EnvironmentConditions(spaceTypeInput.EnvironmentConditionsInput);
This could be done for all similar code and the SpaceType
as well. If so, the remaining space related code could be as simple as:
public class SpaceTypeServices
{
public Guid CreateRequest(...)
{
// rest
var spaceType = new SpaceType(spaceTypeInput);
dbContext.SpaceTypes.Add(spaceType);
dbContext.SaveChanges();
return id;
}
}
This is a low impact, low effort refactoring that at the very least makes the code easier to maintain and reduces complexity.
Upvotes: 2