Last active
October 2, 2015 17:32
-
-
Save arlobelshee/25a17ce7676b807c1dde to your computer and use it in GitHub Desktop.
Combine 2 methods into one with a discriminator variable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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; } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using FluentAssertions; | |
using NUnit.Framework; | |
namespace Blog_gists | |
{ | |
[TestFixture] | |
public class CarsDrive | |
{ | |
private const int Speed = 50; | |
private const int Distance = 100; | |
[Test] | |
public void DrivingWhileUpdatingFuelGuageShouldMoveTheCarAndRequireGas() | |
{ | |
var testSubject = new Car(); | |
testSubject.FillGasTank(12); | |
testSubject.Drive_WithFuelMonitoring(Speed, Distance); | |
testSubject.IsAtDestination.Should().BeTrue(); | |
testSubject.Odometer.Should().Be(100); | |
testSubject.FuelRemaining.Should().Be(9); | |
testSubject.AverageSpeed.Should().NotHaveValue(); | |
} | |
[Test] | |
public void DrivingWhileUpdatingMilageShouldMoveTheCarAndCalculateMilage() | |
{ | |
var testSubject = new Car(); | |
testSubject.FuelRemaining.Should().Be(0); | |
testSubject.Drive_WithAverageSpeedCalculation(Speed, Distance); | |
testSubject.IsAtDestination.Should().BeTrue(); | |
testSubject.Odometer.Should().Be(100); | |
testSubject.FuelRemaining.Should().Be(0); | |
testSubject.AverageSpeed.Should().Be(50); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment