哪个类应该存储查找表? [英] Which class should store the lookup table?

查看:82
本文介绍了哪个类应该存储查找表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

世界包含位于不同位置的特工,而在任何位置只有一个特工.每个代理商都知道他在哪里,但我还需要快速检查在给定位置是否有代理商.因此,我还要维护一张从位置到代理商的地图.我在确定此映射属于哪个位置时遇到问题:class Worldclass Agent(作为类属性)或其他位置.

The world contains agents at different locations, with only a single agent at any location. Each agent knows where he's at, but I also need to quickly check if there's an agent at a given location. Hence, I also maintain a map from locations to agents. I have a problem deciding where this map belongs to: class World, class Agent (as a class attribute) or elsewhere.

在下面,我将查找表agent_locations放在class World中.但是现在,座席必须在每次移动时都呼叫world.update_agent_location.这很烦人.如果我以后决定跟踪有关代理的其他信息(除了它们的位置之外)怎么办?我需要在整个Agent代码中将调用添加回世界对象吗?

In the following I put the lookup table, agent_locations, in class World. But now agents have to call world.update_agent_location every time they move. This is very annoying; what if I decide later to track other things about the agents, apart from their locations - would I need to add calls back to the world object all across the Agent code?

class World:
  def __init__(self, n_agents):
    # ...
    self.agents = []
    self.agent_locations = {}
    for id in range(n_agents):
      x, y = self.find_location()
      agent = Agent(self,x,y)
      self.agents.append(agent)
      self.agent_locations[x,y] = agent
  def update_agent_location(self, agent, x, y):
    del self.agent_locations[agent.x, agent.y]
    self.agent_locations[x, y] = agent
  def update(self): # next step in the simulation
    for agent in self.agents:
      agent.update() # next step for this agent
  # ...

class Agent:
  def __init__(self, world, x, y):
    self.world = world
    self.x, self.y = x, y
  def move(self, x1, y1):
    self.world.update_agent_location(self, x1, y1)
    self.x, self.y = x1, y1
  def update():
    # find a good location that is not occupied and move there
    for x, y in self.valid_locations():
      if not self.location_is_good(x, y):
        continue
      if self.world.agent_locations[x, y]: # location occupied
        continue
      self.move(x, y)

我可以将agent_locations放在class Agent中作为类属性.但这仅在我具有单个World对象时有效.如果以后我决定实例化多个World对象,则查找表将需要特定于世界.

I can instead put agent_locations in class Agent as a class attribute. But that only works when I have a single World object. If I later decide to instantiate multiple World objects, the lookup tables would need to be world-specific.

我相信有更好的解决方案...

I am sure there's a better solution...

我在代码中添加了几行以显示agent_locations的用法.请注意,它仅在Agent对象内部使用,但我不知道这种情况是否会永远存在.

I added a few lines to the code to show how agent_locations is used. Note that it's only used from inside Agent objects, but I don't know if that would remain the case forever.

推荐答案

与OOP一起使用 is has 来谈论对象是有帮助的. World 具有Agents列表和Locations的列表. Location 有一个 Agent. Agent 有一个 Location和一个World.

It helps with OOP to talk about the objects in terms of is a and has a. A World has a list of Agents and a list of Locations. A Location has an Agent. An Agent has a Location and a World.

class Agent:
    def __init__(self, world):
        self.location = None
        self.world = world

    def move(self, new_location):
        if self.location is not None:
            self.location.agent = None
        new_location.agent = self
        self.location = new_location

    def update(self):
        for new_location in self.world.locations:
            if self.location_is_good(new_location):
                self.move(new_location)

    def location_is_good(self, location):
        if location.agent is not None:
            return False

class Location:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.agent = None

进行脑力劳动,向Location添加新属性,例如terrain,很容易看到这种封装的好处.同样,向Agent添加新事物(例如武器),仅需要类似于move()的特定于武器的功能.请注意,World根本不需要参与move().严格在AgentLocation之间进行移动.

Go through the mental exercise of adding a new attribute to a Location, such as terrain, and it's easy to see the benefits of such encapsulation. Likewise, adding new things to Agent, such as a weapon, just requires a weapon-specific function similar to move(). Note that the World doesn't need to get involved in the move() at all. The move is handled strictly between the Agent and the Location.

这篇关于哪个类应该存储查找表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆