【问题标题】:Ruby program for managing locker reservations用于管理储物柜预订的 Ruby 程序
【发布时间】:2015-07-13 14:46:07
【问题描述】:

我遇到了一个对我来说有点太高级的问题。我真的很想解决这个问题并找到解决方案,但不知道该怎么做。

问题来了:

编写一个程序来管理酒店礼宾台的储物柜预订。 客户将行李留给礼宾部,然后礼宾部使用您的程序来确定 在哪个储物柜放置袋子。该程序会告诉礼宾人员 放置袋子的储物柜,并打印一张票给客户。 返回时,客户提供票,礼宾部使用该票 查找相应的储物柜,取回袋子,然后将其归还给客户。

有1000个小储物柜,1000个中型储物柜, 和 1000 个大储物柜(这是拉斯维加斯的一家大酒店)。你可以假设所有 托运行李符合这三种尺寸之一。该程序应 始终分配适合袋子的最小可用储物柜。

有人可以指导我如何解决此类问题吗?我擅长编写 Ruby 脚本,但现在正试图真正理解 OOP 原则。如果您可以在一个类中创建前 2 或 3 个方法,以便我了解您从哪里开始,这将很有帮助。此外,您如何将此问题分解为更易于管理的块,以及如何以不同类可以轻松使用的变量/格式存储数据。

【问题讨论】:

    标签: ruby class oop object data-structures


    【解决方案1】:

    为了模拟这个问题,我们可以使用名为 LockerBag 的类,它们代表领域对象(即应用程序将处理的实际对象)。

    Locker 对象可以有状态标志来确定它是哪种类型的储物柜(小型、中型或大型),Bag 对象也是如此。我们的两个类可以如下所示:

    class Locker
      attr_reader :type, :id
      attr_accessor :bag
    
      def initialize(id, type = nil)
        raise ArgumentError, "Id not present" if id.nil?
        @id = id
        @type = type
        @bag = nil
      end
    
      def free?
        !@bag
      end
    
      def can_place(bag)
        return false unless free?
        case bag.type
          when :small
            true
          when :medium
            @type != :small
          when :large
            @type == :large
          else
            # invalid type
            false
          end
      end
    
    end 
    
    
    class Bag
      attr_reader :type
    
      def initialize(type = nil)
        @type = type
      end
    end
    

    每当您创建一个新对象(在我们的例子中为Bag.newLocker.new)时,都会调用initialize 方法。

    所以,我们有两个域对象,但我们仍然需要一些东西来运行我们的实际程序。这可以称为任何您想要的名称,但为了我们的目的,让我们根据 ruby​​ 命名约定将其称为 locker_app

    require './locker'
    require './bag'
    
    BAG_LIMIT = 1000
    lockers = []
    
    for i in 0..BAG_LIMIT do
      lockers[i] = Locker.new(i, :small)
      lockers[i+BAG_LIMIT] = Locker.new(i+BAG_LIMIT, :medium)
      lockers[i+2*BAG_LIMIT] = Locker.new(i+2*BAG_LIMIT, :large)
    end
    
    while true do
    
      puts "please enter bag size"
      type = gets.strip!.to_sym
      bag = Bag.new(type)
      start = 0
    
      begin
        case type
        when :small
        when :medium
          start = BAG_LIMIT
        when :large
          start = 2*BAG_LIMIT
        else
          raise ArgumentError, "please select a proper size"
        end
    
        for i in start..lockers.size-1
          locker = lockers[i]
          if locker.free? && locker.can_place(bag)
            locker.bag = bag
            puts i
            break
          end
          puts "Sorry, no available lockers" if locker == lockers.last
        end 
      rescue ArgumentError => e
        puts e.message
      end
    
    end
    

    这个简单的程序在无限循环 (while true) 中运行,并通过 Kernel.gets 方法在每次迭代中等待用户输入。然后,用户可以输入袋子类型(小、中或大),程序将输出储物柜的号码。

    储物柜在程序开始时按顺序创建,小储物柜的索引从 0 到 999,中储物柜从 1000 到 1999,大储物柜从 2000 到 2999。然后根据袋子的类型将袋子放入储物柜.

    您可以在自己的控制台中运行它,通过运行ruby locker_app.rb 来验证它是否有效。代码也可以查看here

    这是一个幼稚的实现,应该作为一个起点。你可以从这里有几个不同的方向(例如用1-index而不是像我的例子中那样用0-indexed给储物柜编号,或者维护一个当前存储了多少行李的列表,等等.

    这种设计背后的总体思路是让类描述问题中的对象,然后在这些对象之间建立粘合(在本例中,locker_app 就是粘合)。我坚信首先要创造出行之有效的东西,然后逐步改进它。

    如果您有任何问题,请随时提出。

    【讨论】:

    • main.rb:36:in block in &lt;main&gt;': undefined method bag=' for #<0x25b94b0>
    猜你喜欢
    • 1970-01-01
    • 2015-06-29
    • 1970-01-01
    • 2013-02-20
    • 2022-08-23
    • 1970-01-01
    • 1970-01-01
    • 2016-12-14
    • 1970-01-01
    相关资源
    最近更新 更多