gpt4 book ai didi

python - 对象 A 包含对象 B1 和 B2,B1 包含 C,包含 D。让 D 更改 B2 中某些内容的最佳方式是什么?

转载 作者:行者123 更新时间:2023-12-01 07:25:59 29 4
gpt4 key购买 nike

我正在使用面向对象编程在 Python 中创建一个有点复杂的棋盘游戏的实现。

我的问题是,许多这些对象应该能够与其他对象交互,即使它们不包含在其中。

例如Game是一个对象,其中包含PointTracker和Board。 Board 包含 AreaOne,AreaOne 包含 SpaceOne。

当 Pawn 被放置在 AreaOne 上时,需要发生的事情之一是放置它的玩家获得积分。因此需要在 PointCounter 中进行更改,具体为:PointCounter.AddPoint('Blue')。

实现这一目标(以及许多类似的交互)的有效且优雅的方式是什么?

我可以想到两种方法,两者都有缺点:

a) 每个方法调用都会传回游戏中其他地方需要发生的调用结果。然后,这将沿着链向上传递,并(可能)再次向下传递到其他包含的对象。因此,当蓝色在 SpaceOne 中放置 Pawn 时,“为蓝色添加一个点”会向上传递到 AreaOne、Board、Game,然后向下传递到 PointTracker。这将需要相当多的开销来准确确定哪个对象需要对传递的内容执行什么操作,这将需要大量编码,容易出错且效率低下(由于需要完成所有检查) .

b) 为每个对象提供一个它需要更改的其他每个对象的实例。因此 SpaceOne 将包含 PointTracker 的实例并可以直接调用 PointTracker.GivePoint('Blue')这实现起来相对容易,而且执行起来似乎很高效,但这意味着将游戏中各地的许多不同对象相互传递,这感觉违背了面向对象编程的目的。

还有更好的方法吗?

如果不是,是否有理由选择 a) 或 b)?

最佳答案

我建议将返回上一级对象的链接存储在下一级对象中,即:

  • Board 对象将具有指向相关 Game 对象的链接作为属性,
  • AreaOne 对象将具有指向相关 Board 对象的链接,
  • SpaceOneAreaOne

因此,您可以通过以下方式从 SpaceOne 访问所需的 Game 对象:

# Get the `SpaceOne` object
space_one = game.board.area_one.space_one

# Climb to the `Game` object from the `SpaceOne` object,
# then go to the `point_tracker`
# and call its `AddPoint(player1)` method.
space_one.area_one.board.game.point_tracker.AddPoint(player1)

UML图:

enter image description here

我的实现:

# Auxiliary class - for a class name printing
class Base(object):
def print_class_name(self):
print(self.__class__.__name__)

class Game(Base):
def __init__(self):
self.point_tracker = None
self.board = None

class PointTracker(Base):
def __init__(self):
self.points = 1

def AddPoint(self, player):
player.counter += self.points
print(f"The {player.name}'s points: = {player.counter}")

class Board(Base):
def __init__(self, game):
self.game = game
self.area_one = None

class AreaOne(Base):
def __init__(self, board):
self.board = board
self.space_one = None

class SpaceOne(Base):
def __init__(self, area_one):
self.area_one = area_one

class Player(object):
def __init__(self, color):
self.name = color
self.counter = 0

def create_game():
game = Game()

game.point_tracker = PointTracker()
game.board = Board(game)

game.board.area_one = AreaOne(game.board)

game.board.area_one.space_one = SpaceOne(game.board.area_one)

return game

### Testing
game = create_game()
player1 = Player('Blue')
player2 = Player('Green')

space_one = game.board.area_one.space_one

needed_point_tracker = space_one.area_one.board.game.point_tracker

needed_point_tracker.AddPoint(player1)
needed_point_tracker.AddPoint(player1)

needed_point_tracker.AddPoint(player2)
needed_point_tracker.AddPoint(player2)

needed_point_tracker.AddPoint(player1)
needed_point_tracker.AddPoint(player1)

needed_point_tracker.AddPoint(player2)

输出

The Blue's points: = 1
The Blue's points: = 2
The Green's points: = 1
The Green's points: = 2
The Blue's points: = 3
The Blue's points: = 4
The Green's points: = 3

关于python - 对象 A 包含对象 B1 和 B2,B1 包含 C,包含 D。让 D 更改 B2 中某些内容的最佳方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57452084/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com