在调用其他函数之前确保已调用测试函数

时间:2017-12-12 10:09:21

标签: c# oop

早上好/下午/晚上,

我将直接深入了解一个例子来说明我的问题。

让我们选择两个简单的(C#)类:BagItem

public class Bag
{
    public bool CanAddItem( Item item, float value, out Vector positionInBag )
    {
        // Do heavy calculation
        // Returns true if the item can be added into the bag
        // False otherwise
    }

    public void AddItem( Item item, Vector position )
    {
        // Add the item into the bag at the specified position
    }
}

public class Item
{
    Vector positionInBag ;

    public void PresentToBag( Bag bag, float value )
    {
        if( bag.CanAddItem( this, value, out positionInBag ) )
        {
            Console.WriteLine("I can be added " + positionInBag ) ;
        }
        else
        {
            Console.WriteLine("I can't be added!" ) ;
        }
    }

    public void DropIntoBag( Bag bag )
    {
        bag.AddItem( this, positionInBag  ) ;
    }
}

我的问题如下:如何确保调用Item.DropIntoBag函数并确定它可以添加到包中

第一种可能的解决方案

我可以在致电if( bag.CanAddItem(this) )之前致电bag.AddItem但是:

  • bag.CanAddItem执行繁重的计算,并且在调用Item.PresentToBag之前应该调用DropIntoBag函数,因此,bag.CanAddItem应该已经被调用。
  • bag.CanAddItem返回{使用out关键字)Item的重要数据,以便添加到正确的位置

第二种可能的解决方案

我可以在Item类中添加一个布尔值,指示是否可以将项目添加到包中。但是价值可以由物品本身操纵,这可能导致错误的输出。

第3种可能的解决方案

我可以在Bag类中添加一个地图,指示该项是否可以添加到包中(因此,避免繁重的计算)。但是,因为Bag.CanAddItem依赖于一个不属于Item类的值,所以我认为我不能这样做。

调用Item.DropIntoBag后,该项目应该正确放入包中(并且positionInBag应该是包中的有效位置),但我不知道如何保证它。也许有例外?但这意味着要进行繁重的计算以测试是否可以添加该项目。

提前感谢您的建议。我希望这个问题不是基于意见的。

1 个答案:

答案 0 :(得分:0)

其中一个解决方案(不是最好的,但现有代码的变化很小):

public class Bag
{
    public bool CanAddItem( Item item, float value, out Vector positionInBag )
    {
        // Do heavy calculation
        // Returns true if the item can be added into the bag
        // False otherwise
    }

    public void AddItem( Item item, Vector position )
    {
        // Add the item into the bag at the specified position
    }
}

public interface ICanBeDropped{
    public void Drop();
}

public class DropIntoBagHolder: ICanBeDropped{
    Item item;
    float amount;
    Bag bag;
    Vector positionInBag ;

    DropIntoBagHolder(...){ ... }

    public void Drop(){
        bag.AddItem( item, value maybe here?, positionInBag  ) ;
    }
}

public class Item
{
    public ICanBeDropped PresentToBag( Bag bag, float value )
    {
        Vector positionInBag ;
        if( bag.CanAddItem( this, value, out positionInBag ) )
        {
            Console.WriteLine("I can be added " + positionInBag ) ;
            return new DropIntoBagHolder(....);
        }
        Console.WriteLine("I can't be added!" ) ;
        return null; // will cause exception
    }
}

我认为所有的设计都有点奇怪。为什么物品知道包?也许您可以创建一些更高级别的对象来表示Bag和(当前)Item之间的互动?