inheritance - Your object's family tree - beehive management system class model
Head First C Sharp: A Learner’s Guide to Real-World Programming with C Sharp and .NET (Andrew Stellman(著)、Jennifer Greene(著)、O’Reilly Media)の Chapter 6(inheritance - Your object’s family tree)、p.320(Long Exercise)の解答を求めてみる。
コード
Program.cs
static class HoneyVault
{
public const float NECTAR_CONVERSION_RATIO = .19f;
public const float LOW_LEVEL_WARNING = 10f;
public static string StatusReport
{
get
{
string statusReport = $"{honey:0.0} units of honey\n" +
$"{nectar:0.0} units of nector";
if (honey < LOW_LEVEL_WARNING)
{
statusReport += $"\nLOW HONEY - ADD A HONEY MANUFACTURER";
}
if (nectar < LOW_LEVEL_WARNING)
{
statusReport += $"\nLOW NECTAR - ADD A NECTAR MANUFACTURER";
}
return statusReport;
}
}
private static float honey = 25f;
static private float nectar = 100f;
public static void CollectedNectar(float amount)
{
if (amount > 0)
{
honey += 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 (honey >= amount)
{
honey -= amount;
return true;
}
return false;
}
}
class Bee
{
public string Job { get; private set; }
public virtual float CosntPerShift { get; }
public Bee(string job)
{
Job = job;
}
public void WorkTheNextShift()
{
if (HoneyVault.ConsumeHoney(CosntPerShift))
{
DoJob();
}
}
protected virtual void DoJob() { }
}
class Queen : Bee
{
private const float EGGS_PER_SHIFT = 0.45f;
private const float HONEY_PER_UNASSIGNED_WORKER = 0.5f;
public string StatusReport { get; private set; } = "";
private Bee[] workers = new Bee[0];
private float eggs = 0;
private float unassignedWorkers = 3;
public override float CosntPerShift => 2.15f;
protected override void DoJob()
{
eggs += EGGS_PER_SHIFT;
foreach (Bee worker in workers)
{
worker.WorkTheNextShift();
}
HoneyVault.ConsumeHoney(HONEY_PER_UNASSIGNED_WORKER * workers.Length);
UpdateStatusReport();
}
public void AssignBee(string job)
{
switch (job)
{
case "Honey Manufacturer":
AddWorker(new HoneyManufacturer());
break;
case "Nectar Collector":
AddWorker(new NectarCollector());
break;
case "Egg Care":
AddWorker(new EggCare());
break;
}
UpdateStatusReport();
}
private void AddWorker(Bee worker)
{
if (unassignedWorkers >= 1)
{
unassignedWorkers--;
Array.Resize(ref workers, workers.Length + 1);
workers[workers.Length - 1] = worker;
}
}
public void CareForEggs(float eggsToConvert)
{
if (eggs >= eggsToConvert)
{
eggs -= eggsToConvert;
unassignedWorkers += eggs;
}
}
private void UpdateStatusReport()
{
int nectarCollector = 0;
int honeyManufacturer = 0;
int eggCare = 0;
foreach (Bee worker in workers)
{
switch (worker.Job)
{
case "Nectar Collector":
nectarCollector++;
break;
case "Honey Manufacturer":
honeyManufacturer++;
break;
case "Egg Care":
eggCare++;
break;
}
}
StatusReport = "Vault report:\n" +
HoneyVault.StatusReport + "\n" +
$"Egg count: {eggs}\n" +
$"Unassigned workers: {unassignedWorkers}\n" +
$"{nectarCollector} Nectar Collector bee";
if (nectarCollector > 1) StatusReport += "s";
StatusReport += $"\n{honeyManufacturer} Honey Manufacturer bee";
if (honeyManufacturer > 1) StatusReport += "s";
StatusReport += $"\n{eggCare} Egg Care bee";
if (eggCare > 1) StatusReport += "s";
StatusReport += $"\nTOTAL WORKERS: {workers.Length}";
}
public Queen() : base("Queen")
{
string[] jobs = ["Heny manufacturer", "Nectar Collectar", "Egg Care"];
foreach (string job in jobs)
{
AssignBee(job);
}
}
}
class HoneyManufacturer : Bee
{
private const float NECTAR_PROCESSED_PER_SHIFT = 33.15f;
public override float CosntPerShift => 1.7f;
protected override void DoJob()
{
HoneyVault.ConvertNectarToHoney(NECTAR_PROCESSED_PER_SHIFT);
}
public HoneyManufacturer() : base("Honey Manufacturer") { }
}
class NectarCollector : Bee
{
private const float NECTAR_COLLECTED_PER_SHIFT = 33.25f;
public override float CosntPerShift => 1.95f;
protected override void DoJob()
{
HoneyVault.CollectedNectar(NECTAR_COLLECTED_PER_SHIFT);
}
public NectarCollector() : base("Nectar Collector") { }
}
class EggCare : Bee
{
private Queen queen;
private const float CARE_PROGRESS_PER_SHIFT = 0.15f;
public override float CosntPerShift => 1.35f;
protected override void DoJob()
{
queen.CareForEggs(CARE_PROGRESS_PER_SHIFT);
}
public EggCare() : base("Egg Care")
{
queen = new Queen();
}
}