|
// Initial state for unifying two similar methods to use a discriminator variable. |
|
// |
|
// Includes 2 methods (Drive_WithFuelMonitoring and Drive_WithAverageSpeedCalculation) |
|
// that are similar in intent and differ only in implementation. This may be a bug or |
|
// may be intentional. We can't tell without asking the domain expert. So we want to |
|
// unify them mechanistically. |
|
// |
|
// The history shows how. |
|
|
|
using System.Collections.Generic; |
|
using System.Linq; |
|
using JetBrains.Annotations; |
|
|
|
namespace Blog_gists |
|
{ |
|
public class Car |
|
{ |
|
[NotNull] private readonly List<TravelSegment> drivingHistory = new List<TravelSegment>(); |
|
|
|
public Car() |
|
{ |
|
Odometer = 0; |
|
IsAtDestination = false; |
|
} |
|
|
|
public void Drive_WithFuelMonitoring(int speed, int distance) |
|
{ |
|
for (var i = 0; i < distance; ++i) |
|
{ |
|
DriveOneMile(speed); |
|
} |
|
FinishDriving(); |
|
FuelRemaining -= CalculateFuelConsumed(speed, distance); |
|
Odometer += distance; |
|
} |
|
|
|
public void Drive_WithAverageSpeedCalculation(int speed, int distance) |
|
{ |
|
for (var i = 0; i < distance; ++i) |
|
{ |
|
DriveOneMile(speed); |
|
} |
|
FinishDriving(); |
|
Odometer += distance; |
|
drivingHistory.Add(new TravelSegment(speed, distance)); |
|
} |
|
|
|
public decimal? AverageSpeed |
|
{ |
|
get |
|
{ |
|
if (drivingHistory.Count == 0) return null; |
|
var totalDriveTime = drivingHistory.Select(h => h.Distance/h.Speed).Sum(); |
|
return Odometer/totalDriveTime; |
|
} |
|
} |
|
|
|
public void FillGasTank(decimal numGallons) |
|
{ |
|
FuelRemaining += numGallons; |
|
} |
|
|
|
private void FinishDriving() |
|
{ |
|
IsAtDestination = true; |
|
} |
|
|
|
public class TravelSegment |
|
{ |
|
public decimal Speed; |
|
public decimal Distance; |
|
|
|
public TravelSegment(int speed, int distance) |
|
{ |
|
Speed = speed; |
|
Distance = distance; |
|
} |
|
} |
|
|
|
private decimal CalculateFuelConsumed(int speed, int distance) |
|
{ |
|
return 3; |
|
} |
|
|
|
private void DriveOneMile(int speed) |
|
{ |
|
IsAtDestination = false; |
|
} |
|
|
|
public int Odometer { get; private set; } |
|
|
|
public decimal FuelRemaining { get; private set; } |
|
|
|
public bool IsAtDestination { get; private set; } |
|
} |
|
} |