The starting point was a configuration class that had the following definition:
public const decimal AdultFactor = 6;
public const decimal ChildrenFactor = 3;
public const decimal GasKwHMinEstThreshold = 4000;
:
These parameters are always used together in the context of a calculation for gas consumption. The client code uses these config values in the following fashion:
calculatedUsageKw = AdjustUsageForRadiators(calculatedUsageKw, GasConfiguration.AdultFactor,
GasConfiguration.ChildrenFactor,
GasConfiguration.RadiatorFactor,
GasConfiguration.PersonsAtPropertyFactor); I wanted to give the setting of the gas consumption parameters a fluid feel in the following style
public static IFluentConfiguration Create()
{
var fluentConfig = new GasConfigurationFluent();
fluentConfig.SetAdultFactor(6).SetChildrenFactor(3).
SetGasKwHMinEstThreshold(4000).SetGasPointsMinThreshold(12).
SetGasPointsToKwHConvFactor(400).SetGasWaterHeatingAmount(10).
SetHobGasCooker(4).SetMainRoomFireOnGas(16).
SetPersonsAtPropertyFactor(2).SetRadiatorFactor(5);
return fluentConfig;
}
The client code accessing the fluent configuration interface was refactored to:
private decimal? AdjustUsageForRadiators(decimal? calculatedUsageKw, IFluentConfiguration fluentConfig)
The GasConfigurationFluent has setters that take the folllowing general approach:
public IFluentConfiguration SetAdultFactor(decimal? adultFactor)
{
AdultFactor = adultFactor;
return this;
}
And yes my setters have a return value which is in effect the current context i.e. my fluent configuration.After applying this refactoring, a few things became apparent,
1. The method chaining enforces the fact that these parameters exist in the same context and somewhat provides a cohesive view of my configuration interface. The setting of the configuration values is much more concise.
2. The cohesive nature of this configuration hints at the fact that a DSL(Domain Specific Language) could possibly be built around the calculation of gas consumption.