[英]C# Disambiguation of methods for various fields
不知道问题是否足够精确,因此请在阅读完我的问题的解释后纠正我。
控制台应用程序。 简单的游戏。 因此,我有9个燃油泵,每个都将维修车辆。 现在-我需要使用计时器加油的方法(或仅使用基于主游戏计时器的普通vars)。
我的问题是最好的解决方法是什么? 要么为每个泵创建一个单独的方法,要么有一种方法为每个泵使用一个方法(消除变量等)。
先感谢您。
编辑: http : //pastebin.com/JFVZHU41
这似乎是一个广泛的问题,所以我将给您一些想法。 您已用OOP标记问题。 如果您询问“面向对象”的实现方法,则其中一种方法可能是使用方法加油创建类Pump。 然后,您将创建类Pump的实例(每个泵9次)。 如果泵具有不同的属性(例如加油时间),则可以将其作为公共属性。 这只是给您一个想法:
public class Pump
{
public int RefuellingTimeSeconds { get; set; }
public void Refuel(Vehicle vehicle)
{
//refuelling code here
}
}
然后,您可以实例化每个泵:
var firstPump = new Pump { RefuellingTimeSeconds = 120 };
var secondPump = new Pump { RefuellingTimeSeconds = 90 };
以上假设所有泵都具有相同的加油程序,只是在某些可以从外部设置的参数上有所不同。
另一方面,如果您有不同类型的泵,并且它们共享的只是加油接口,则可以创建具有不同泵实现的泵接口:
public interface IPump
{
void Refuel(Vehicle vehicle)
}
public class SlowRefuelPump
{
public void Refuel(Vehicle vehicle)
{
//slow refuelling
}
}
public class FastRefuelPump
{
public void Refuel(Vehicle vehicle)
{
//fast refuelling
}
}
然后,您可以根据需要创建泵,并在应用程序中使用它们的接口:
var pumps = new List<IPump> { new SlowRefuelPump(), new FastRefuelPump() };
并将它们用作:
pumps[0].Refuel(_vehicle);
pumps[1].Refuel(_vehicle);
这完全取决于您的情况...
我将创建一个Pump
类,其中包含为Car
实例加油的逻辑。
这些泵实例中的每一个在泵送时都会引用汽车。 Pump
类可以具有一种基于游戏循环增加汽车燃油的方法。
就像是:
public class Pump
{
private int _fuelRate;
public Car ServicingCar { get; set; }
public Pump(int fuelRate = 10)
{
_fuelRate = fuelRate;
}
public void IncreaseFuel()
{
if (ServicingCar == null) return;
ServicingCar.Fuel += _fuelRate;
}
}
然后在游戏的某个地方初始化泵:
var pump1 = new Pump();
var pump2 = new Pump(20); // this one is faster
等等...
当您想给汽车加油时,只需分配ServicingCar
属性即可。
pump1.ServicingCar = car1;
您可以检查其他汽车是否已经在加油,等等。这将是您要解决的任务。
在您的游戏循环中,您将为每个泵调用“ IncreaseFuel
燃料”。
这是最好的方法吗? 由于您的问题的详细程度较低,因此这是非常主观的且难以回答。 但是,这是一种简单的方法。
您无需忘记编写代码和编程,而是先确定需求,然后将其放入简单明了的英语句子中。 这将帮助您设想要解决的问题,并提出更好的心理模型。 现在我不知道您的要求,但我会尝试做一些假设。 例如,以下是编写要求的方法:
基于这些要求,不要太花哨,使用OO概念,您可以找到名词,这些名词将成为您的类(还有其他一些高级方法,但是从头开始这确实很棒)。 所有粗体均为名词,因此您需要以下类:
现在让我们集中讨论Pump
项。
现在,仔细查看以下措辞:“泵将被占用”,这意味着我们的Pump
类将需要一个属性来存储它。 “它将占据一段时间”,这意味着还需要一些东西来跟踪时间。 “要启动泵,将需要车辆”,这意味着我们需要“启动”属性,但这听起来不正确。 属性是一个属性,听起来像一个动作。 因此,“开始”应该是一种方法。
对于属性,请始终考虑“形容词”,例如身高,体重等。对于方法,请始终考虑“动词”,尤其是动作动词,例如“开始”,“停止”,“行走”等。
设计
好的,让我们设计Pump
类。 但是在我们这样做之前,让我们澄清一下设计目标。 我们班级的设计应该使我们班级的用户永远不能将泵置于不良状态。 例如,如果水泵已被占用,我们将无法接受其他车辆。 此类用户不应启动泵并为其提供车辆,还应说泵是自由的。 泵将需要某种信号来指示它是空的还是已占用的。
好的,足够的理论,现在有一些代码:
class Pump
{
public event EventHandler<PumpEventArgs> StatusChanged;
private System.Timers.Timer timer;
private Vehicle vehicle;
public Pump(string name)
{
if (string.IsNullOrWhiteSpace(name))
{
throw new ArgumentException("The name for the pump is not valid. It cannot be null or empty.");
}
this.Name = name;
this.timer = new System.Timers.Timer();
this.timer.Elapsed += Timer_Elapsed;
this.timer.Interval = 100;
this.timer.AutoReset = true;
}
public string Name { get; private set; }
private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
// If the pump is not occupied, we do nothing
if (!this.IsOccupied)
{
return;
}
// Looks like the pump was occupied and
// the timer went off so lets make the pump available by setting the
// vehicle at this pump to null
this.Vehicle = null;
}
// Private set so the only way to set this is to call the start method
public Vehicle Vehicle
{
get
{
return this.vehicle;
}
private set
{
this.vehicle = value;
if (value == null)
{
this.IsOccupied = false;
}
else
{
this.IsOccupied = true;
}
// If anyone has subscribed to the pump change event, notify them and send them the status
if (this.StatusChanged != null)
{
this.StatusChanged(this, new PumpEventArgs { Status = this.Status });
}
}
}
// private set so the only way a pump is occupied if start has been called.
// Other classes should not be able to set IsOccupied to false if there is a vehicle at the
// pump.
public bool IsOccupied { get; private set; }
// This is a read-only property. It depends on the IsOccupied property.
public string Status
{
get
{
if (this.IsOccupied)
{
return "Occupied";
}
return "Free";
}
}
public void Start(Vehicle vehicle)
{
// This object should take care of its own rules. If someone calls Start
// and the pump is busy and they call start again, do not allow it.
if (this.IsOccupied)
{
throw new InvalidOperationException("This pump is already occupied.");
}
// Set using property so the property can carry out the other rules
this.Vehicle = vehicle;
// Start the pump timer as well
this.timer.Start();
}
}
请注意,该类没有Console.WriteLine
或其他控制台引用。 此类独立于所有这些。 在泵可用时或一旦被占用等情况下,班级用户可以决定在哪里写消息。也许用户想写到控制台,或者也许用户想显示一个对话框(窗口),或者用户想要将信号发送到真实的灯光并将其变为绿色等。它还应确保确保其始终处于良好状态:如果被占用,则不会返回“自由”状态。 另外,不允许其他人将状态设置为免费。
当泵被占用或空闲时,该类还公开一个事件。 如果班级用户感兴趣,他们将订阅该活动并做他们需要的任何事情。
因此,有Pump
类,它应该为您提供有关如何创建良好封装的良好类的许多想法。
这是Vehicle
类,但显然还没有结束。
class Vehicle
{
}
这是Game
类的方式,但是您需要对其进行更改并向其中添加更多代码。 例如,当水泵被占用时,您可能需要做一些事情。 免费时,您可能还需要其他东西。 我只是在向控制台写一条消息。
class Program
{
static void Main(string[] args)
{
while (true)
{
Pump p1 = new Pump("Pump1");
// Lets make sure to subscribe to StatusChanged event before you start the pump
// with a new vehicle.
p1.StatusChanged += StatusChanged;
p1.Start(new Vehicle());
Pump p2 = new Pump("Pump2");
p2.StatusChanged += StatusChanged;
p2.Start(new Vehicle());
//Console.Write("Finished...");
Console.ReadLine();
}
}
// we can use the same handler for all pumps and we can do different things
// depending on who the sender is.
// Or if you prefer, you can have different event handlers
private static void StatusChanged(object sender, PumpEventArgs e)
{
var pump = sender as Pump;
Console.WriteLine("{0} status changed to {1}.", pump.Name, e.Status);
}
}
祝好运!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.