很抱歉,如果读者在阅读以下内容后有一个更好的标题,请进行更改。
我正在用python实现一个流行的棋盘游戏。一个游戏功能包括玩家可以从中获得的五堆令牌。我在思考用代码表示这种情况的好方法时遇到了麻烦。我当前的实现看起来像这样(为该帖子简化):
class Game:
def __init__(self):
...
self.tokens = num_tokens
class Player:
def take_token(self, game):
game.tokens[token] -= 1
self.tokens[token] += 1
return game # the updated game instance
在我看来,这显然是一个糟糕的主意,因为我是将游戏状态传递给Player
只是为了操纵它,然后将其发送回去……应该有一种更简洁的方式来表示这一点。问题是我喜欢将每个对象的数据存储在self
下,因为这似乎是将数据绑定到对象的好方法。有人可以在这里帮助我确定正确的设计模式吗?
答案 0 :(得分:1)
怎么样
library(dplyr)
dummy_data %>%
group_by(ID) %>%
mutate(initiator = sample(0:1))
# ID Sex initiator
# <dbl> <chr> <dbl>
#1 1 M 0
#2 1 F 1
#3 2 F 1
#4 2 M 0
#5 3 F 1
#6 3 M 0
答案 1 :(得分:1)
由于这是一个基于设计的问题,所以我想说,您对单个类(您的情况下为播放器)的责任要超出要求。 要编写更独立的代码,您必须遵循“单一责任原则” 您必须按照先前的答案中的建议编写一个松散耦合的代码。
答案 2 :(得分:1)
经过一番讨论,我们认为在保持相关属性的对象所有权的同时保持封装的最佳方法是通过具有错误传播的getter和setter:
class Game:
def __init__(self):
...
self.tokens = num_tokens
def take_token(self):
if self.tokens ≤ 0:
raise RuntimeError("Trying to take from empty pile")
self.tokens -= 1
return True
class Player:
def take_token(self, game):
if game.take_token():
self.tokens[token] += 1
这使每个对象都可以进行自己的核算,同时为内部数据保留适当的边界。