inheritance - Your object's family tree - Beehive Management System
Head First C#: A Learner’s Guide to Real-World Programming with C# and .NET Core (Andrew Stellman(著)、Jennifer Greene(著)、O’Reilly Media)のChapter 6(inheritance - Your object’s family tree)、p.320(Long Exercise)の解答を求めてみる。
コード
Bee.cs
using System;
namespace BeehiveManagementSystem
{
public class Bee
{
public string Job { get; private set; }
public virtual float CostPerShift { get; }
public Bee(string job)
{
Job = job;
}
public void WorkTheNextShift()
{
if (HoneyValut.ConsumeHoney(CostPerShift))
{
DoJob();
}
}
protected virtual void DoJob() { }
}
}
コード
EggCare.cs
using System;
namespace BeehiveManagementSystem
{
public class EggCare : Bee
{
private const float CARE_PROGRESS_PER_SHIFT = 0.15f;
private Queen queen;
public override float CostPerShift
{
get
{
return 1.35f;
}
}
public EggCare(Queen queen) : base("Egg Care")
{
this.queen = queen;
}
protected override void DoJob()
{
queen.CareForEggs(CARE_PROGRESS_PER_SHIFT);
}
}
}
コード
HoneyManufacturer.cs
using System;
namespace BeehiveManagementSystem
{
public class HoneyManufacturer : Bee
{
private const float NECTAR_PROCESSED_PER_SHIFT = 33.15f;
public override float CostPerShift
{
get
{
return 1.7f;
}
}
public HoneyManufacturer() : base("Honey Manufacturer")
{
}
protected override void DoJob()
{
HoneyValut.ConvertNectarToHoney(NECTAR_PROCESSED_PER_SHIFT);
}
}
}
コード
HoneyVault.cs
using System;
namespace BeehiveManagementSystem
{
public static class HoneyValut
{
private const float NECTAR_CONVERSION_RATIO = 0.19f;
private const float LOW_LEVEL_WARNING = 10f;
private static float honey = 25f;
private static float nectar = 100f;
public static string StatusReport
{
get
{
string s = $"amount of honey: {honey:0.0}\n" +
$"amount of nectar: {nectar:0.0}";
if (honey <= LOW_LEVEL_WARNING)
{
s += $"\nWarning: LOW HONEY - ADD A HONEY MANUFACTURER";
}
if (nectar <= LOW_LEVEL_WARNING)
{
s += $"\nWarning: LOW NECTAR - ADD A NECTAR COLLECTOR";
}
return s;
}
}
public static void CollectNectar(float amount)
{
if (amount > 0)
{
nectar += amount;
}
}
public static void ConvertNectarToHoney(float amount)
{
if (nectar < amount)
{
amount = nectar;
}
nectar -= amount;
honey += amount * NECTAR_CONVERSION_RATIO;
}
public static bool ConsumeHoney(float amount)
{
if (amount <= honey)
{
honey -= amount;
return true;
}
return false;
}
}
}
コード
NectarCollector.cs
using System;
namespace BeehiveManagementSystem
{
public class NectarCollector : Bee
{
private const float NECTAR_COLLECTED_PER_SHIFT = 33.25f;
public override float CostPerShift
{
get
{
return 1.95f;
}
}
public NectarCollector() : base("Nectar Collector")
{
}
protected override void DoJob()
{
HoneyValut.CollectNectar(NECTAR_COLLECTED_PER_SHIFT);
}
}
}
コード
Queen.cs
using System;
namespace BeehiveManagementSystem
{
public class Queen : Bee
{
private const float EGGS_PER_SHIFT = 0.45f;
private const float HONEY_PER_UNASSIGNED_WORKER = 0.5f;
private Bee[] workers = Array.Empty<Bee>();
private float eggs = 0;
private float unassignedWorkers = 3;
public override float CostPerShift
{
get
{
return 2.15f;
}
}
public string StatusReport { get; private set; }
public Queen() : base("Queen")
{
AssignBee("Egg Care");
AssignBee("Honey Manufacturer");
AssignBee("Nectar Collector");
}
protected override void DoJob()
{
eggs += EGGS_PER_SHIFT;
foreach (Bee worker in workers)
{
worker.WorkTheNextShift();
}
HoneyValut.ConsumeHoney(HONEY_PER_UNASSIGNED_WORKER * workers.Length);
updateStatusReport();
}
public void AddWorker(Bee worker)
{
if (unassignedWorkers > 0)
{
unassignedWorkers--;
Array.Resize(ref workers, workers.Length + 1);
workers[workers.Length - 1] = worker;
}
}
public void AssignBee(string job)
{
switch (job)
{
case "Egg Care":
AddWorker(new EggCare(this));
break;
case "Honey Manufacturer":
AddWorker(new HoneyManufacturer());
break;
case "Nectar Collector":
AddWorker(new NectarCollector());
break;
default:
break;
}
updateStatusReport();
}
public void CareForEggs(float eggsToConvert)
{
if (eggs >= eggsToConvert)
{
eggs -= eggsToConvert;
unassignedWorkers += eggsToConvert;
}
}
private void updateStatusReport()
{
int nectarCollectorBeeCount = 0;
int honeyManufacturerBeeCount = 0;
int eggCareBeeCount = 0;
foreach (Bee worker in workers)
{
switch (worker.Job)
{
case "Nectar Collector":
nectarCollectorBeeCount++;
break;
case "Honey Manufacturer":
honeyManufacturerBeeCount++;
break;
case "Egg Care":
eggCareBeeCount++;
break;
default:
break;
}
}
string nectors = "bee";
string honeys = "bee";
string eggCares = "bee";
if (nectarCollectorBeeCount > 1)
{
nectors += "s";
}
if (honeyManufacturerBeeCount > 1)
{
honeys += "s";
}
if (eggCareBeeCount > 1)
{
eggCares += "s";
}
StatusReport = $"Vault report:\n{HoneyValut.StatusReport}\n\n" +
$"Egg count: {eggs:0.0}\n" +
$"Unassigned workers: {unassignedWorkers:0.0}\n" +
$"{nectarCollectorBeeCount} NectarCollector {nectors}\n" +
$"{honeyManufacturerBeeCount} Honey Manufacturer {honeys}\n" +
$"{eggCareBeeCount} Egg Care {eggCares}\n" +
$"TOTAL WORKERS: {workers.Length}";
}
}
}