我正在为一副纸牌创建一个模块。我希望Deck对象能够接受下面编写的shuffle方法的另一种实现。
我本来以为我的shuffle方法应该接受一个参数,该参数是任何响应shuffle的对象。这是个好方法吗?
我不确定如何在Ruby中实现这一目标。
module PlayingCards
class Deck
RANKS = [*2..10, 'Jack', 'Queen', 'King', 'Ace']
SUITS = %w{ Clubs Diamonds Hearts Spades }
attr_accessor :cards, :discarded
def initialize(options={})
@cards = []
@discarded = []
options[:number_decks] ||= 1
options[:number_decks].times do
(RANKS).product(SUITS).each do |rank, suit|
@cards << Card.new(rank, suit)
end
end
end
def shuffle()
cards.push(*discarded).shuffle!
discarded = []
self
end
end
end
这是手牌类,负责从牌组中抽牌并折叠手牌。
module PlayingCards
class Hand
attr_accessor :deck, :draw_count, :cards, :discarded
def initialize(args = {})
@deck = args[:deck]
@discarded = args[:deck].discarded
@draw_count = args[:draw_count]
@cards = []
end
def draw
draw_count.times do
cards.push(deck.cards[0])
deck.cards.shift
end
cards
end
def fold
discarded.push(cards).flatten!
end
end
end
答案 0 :(得分:2)
我希望Deck对象能够接受下面编写的shuffle方法的另一种实现方式。
有几种方法可以实现此目的。没有一个正确的答案。这里有一些技巧:
只需定义多种方法:
load()
定义一个高阶方法,例如:
def shuffle
cards.push(*discarded).shuffle!
discarded = []
self
end
# For example
def shuffle_before_replacing
cards.shuffle!
cards.push(*discarded)
discarded = []
self
end
注入一个依赖项来执行改组,例如:
SHUFFLE_MODES = {
standard: ->(cards, discarded) { cards.push(*discarded).shuffle },
# ...
}
def shuffle(mode: :standard)
cards = SHUFFLE_MODES.fetch(mode).call(cards, discarded)
discarded = []
self
end
结束
该第三种方法的主要优点是您可以独立于def shuffle(shuffler: Shuffler::Standard)
shuffler = shuffler.new(cards, discarded)
shuffler.shuffle
cards = shuffler.cards
shuffler = shuffler.discarded
self
end
# ...
module Shuffler
class Base
attr_reader :cards, :discarded
def initialize(cards, discarded)
@cards = cards
@discarded = discarded
end
end
end
module Shuffler
class Standard < Base
def shuffle
@cards.push(*discarded).shuffle
@discarded = []
self
end
end
end
module Shuffler
class BeforeReplacing < Base
def shuffle
@cards.shuffle!
@cards.push(*discarded)
@discarded = []
self
end
end
end
类定义Shuffler
-例如,也许最终您将拥有多种类型Deck
中的每一个都可以以不同的方式使用Deck
接口。 (例如,也许您想改组不同的事物,或者改组多次。)
同样,您也可以独立于Shuffler
对Shuffler
进行 test 测试。这是双向的。您现在还可以独立于Deck
测试Deck
(通过将模拟对象传递到Shuffler
方法中)。
这项技术是这三种技术中最先进的一种,我通常只希望有经验的开发人员可以在更加复杂的场景中充分利用。鉴于我所掌握的信息有限,很难说这样的抽象在您的情况下是否仍在努力!
上面的所有代码都未经测试,因此可能找不到,但是希望这能给您一些启发。