C#消除各种字段的方法

时间:2017-01-02 16:05:46

标签: c# oop

不确定问题是否足够精确,一旦您阅读了我的问题的解释,请纠正我。

控制台应用程序。简单的游戏。 所以我有9个燃油泵,每个都将为车辆提供服务。现在 - 我需要使用计时器加油方法(或者只使用基于主游戏计时器的普通变量)。

我的问题是接近它的最佳方法是什么?要么为每个泵制作单独的方法,要么为每个泵使用一种方法(消除变量等)。

提前谢谢。

编辑:http://pastebin.com/JFVZHU41

3 个答案:

答案 0 :(得分:1)

这似乎是一个广泛的问题所以我只想给你一些想法。您已使用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);

一切都取决于你的情景...

答案 1 :(得分:0)

我会创建一个类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

这是最好的方法吗?这是非常主观的,很难回答,因为你的问题的细节水平很低。但是,这是一种简单的方法。

答案 2 :(得分:0)

你需要忘记编写代码和编程,但首先要确定要求并将它们放入简单,简单的英语句子中。这将帮助您设想您正在解决的问题,并提出一个更好的心理模型。现在我不知道你的要求,但我会尝试做出假设。例如,以下是编写需求的方法:

  1. 制作游戏
  2. 游戏将由组成。泵将为其分配编号。
  3. 播放器会输入代表泵的数字来选择
  4. 当玩家选择时,它将被占用一段时间。之后,泵将可用。
  5. 要启动泵,车辆将需要在泵上。
  6. 根据这些要求,不要过于花哨,使用OO概念,你可以找到名词,那些将成为你的类(还有其他先进的方法,但一开始这非常好)。所有粗体项目都是名词,因此您需要以下课程:

    1. 游戏(而不是称之为程序,称之为游戏。这就是整个事情开始的地方。)
    2. 泵 - 这将是所有泵的列表
    3. 玩家 - 玩游戏的玩家。但是如果你没有跟踪玩家并且假设只有一个玩家正在玩,你可能不需要这个。
    4. 泵 - 一个泵。
    5. 车辆
    6. 现在让我们专注于Pump项目。

      现在仔细查看措辞:&#34;泵将被占用&#34;,这意味着我们的Pump类需要一个属性来存储它。 &#34;它将被占用一段时间&#34;,这意味着它还需要一些东西来跟踪时间。 &#34;要启动泵,它需要一辆车&#34;,这意味着我们需要一个&#34;开始&#34;财产,但听起来不对。属性是属性,这听起来像一个动作。因此,&#34;开始&#34;应该是一种方法。

      对于物业总是认为&#34;形容词&#34;例如身高,体重等。对于方法总是认为&#34;动词&#34;特别是动作动词,如Start,Stop,Walk等。

      <强>设计

      好的,让我们设计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或其他控制台引用。这个班是独立的。当泵可用或一旦被占用时,由类的用户决定在何处写消息。也许用户想要写入控制台,或者用户想要显示对话框(窗口)或者可能用户想要向真实灯发送信号并将灯变为绿灯等。它还要确保它始终处于良好状态:如果它被占用,它将不会返回&#34; Free&#34 ;状态。此外,它不允许任何其他人将状态设置为免费。

      该类还会在泵被占用和空闲时暴露事件。如果班级的用户感兴趣,他们将订阅该活动并做他们需要的任何事情。

      所以有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);
          }
      }
      
      祝你好运!