代码之家  ›  专栏  ›  技术社区  ›  will-hart

面向对象方法-子类修改父类

  •  2
  • will-hart  · 技术社区  · 15 年前

    我有一个关于面向对象设计的问题-我有两个类,一个 地图 (实际上是X、Y网格)和 项目 放在地图上。地图包含所有项目及其位置,并控制程序流。这些项目具有一定的智能性,可以确定是否希望在地图上移动。

    例如,地图代码可能如下所示:

    class Map
    {
        ...
        Items[,] map;
    
        public void DoItemUpdate()
        {
            ...
            for (x = 0 to MaxX)
            {
                for (y = 0 to MaxY)
                {
                        map[x,y].UpdateItem();
                }
            }
        }
    }
    

    项目代码可能看起来像:

    class Items
    {
        ...
        Vector2 location;
    
        public void UpdateItem()
        {
            // determine if we want to move the unit
            ....
    
            // if yes, move the unit
            this.Move(fromXY, toXY);
        }
    
        public void Move(Vector2 from, Vector2 to)
        {
            // what goes in here - raise event, use reference to Map class?
        }
    }
    

    基本上,我想知道的是移动代码应该如何构造,以便它询问地图移动是否合法,然后在地图中注册移动。

    我想了几个方法

    1. 将对父映射类的引用传递给该项并从中调用函数
    2. 使用委托/事件结构“回调”映射

    关于这些方法的任何评论——什么是最适合OO代码的最佳/最干净/最合适的? 谢谢!

    1 回复  |  直到 15 年前
        1
  •  3
  •   anthony    15 年前

    两者都不。我会给你的物品添加一个方法(应该是物品吗?)班级:

    Vector2 GetMoveRequest();
    

    定义项可以返回的常量值,以指示它不希望被移动。(0,0)如果返回值指示一个增量,或(-1,-1)如果返回值指示一个绝对位置。或者如果您不想定义一个魔法值:

    bool TryGetMoveRequest(out Vector2 request);
    

    优势:

    现在您已经在两个类中适当地分离了移动逻辑。该项目知道它是否要移动,如果要移动到哪里。映射可以评估移动的合法性,然后根据逻辑执行或忽略项目的移动请求。没有引用处理,没有笨拙的回调机制。

    此外,您的map类中的逻辑将能够增加复杂性。考虑一个场景,其中一个项目的移动可能阻止另一个项目的移动,或者被另一个项目的移动阻止。使用您列出的任何一种方法都很难实现这一点。