簡體   English   中英

有辦法避免方法調用重復嗎?

[英]Is there a way to avoid method calling repetition?

我正在構建一個游戲,其中幾種方法相互關聯,需要在后台調用。 例如,當士兵需要離開城堡時,需要在他離開后立即打開然后關閉門:

public void MoveTheGate(bool openTheGate)
{
    if (openTheGate)
    {
        //  code for: open the gate
    }
    else
    {
        //  code for: close the gate
    }
}

public void GetOutOfTheCastle()
{
    MoveTheGate(true);

    //  code for: get out of the castle

    MoveTheGate(false);
}

當來自另一個王國的信使到達城堡時,也是如此,必須在信使進入城堡的開始和結束時都調用MoveTheGate()方法。

有沒有更精致的方法來實現這一目標?

你可以做

OpenGate(()=>
  { stuff to do with gate open }
);

OpenGate在哪里

public void OpenGate(Action action)
{
    try
    {
      MoveTheGate(true);
      action();
   }
   finally 
   {
    MoveTheGate(false);
   }
}

這可能完全是矯kill過正,但是您始終可以實現IDisposable然后使用using塊。 這是“確保”它發生的好方法。

如果您建立了一個在處置時調用了某些給定操作的類,

public class DelegateDisposable : IDisposable
{
    private readonly Action action;

    public DelegateDisposable(Action action)
    {
        this.action = action;
    }

    public void Dispose()
    {
        if(this.action != null)
        {
            this.action();
        }
    }
}

然后,您可以像這樣使用它:

private IDisposable OpenGate()
{
    MoveTheGate(true);
    return new DelegateDisposable(() => MoveTheGate(false));
}

並像這樣使用它:

public void GetOutOfTheCastle()
{
    using (OpenGate())
    {
        //  code for: get out of the castle
    }
}

這種方法的一個很好的優點是它不會與您的調用棧混淆,盡管它確實有一些開銷。 但是,如果您將DelegateDisposable帶入某個實用程序類,則它對於其他功能也可能很有用。

我將對強制您在基本繼承的抽象類的上下文中執行操作的繼承模式保持公正。 我認為這是更可取的原因是因為它使您可以輕松地封裝Gate的打開和關閉,並且不會暴露繼承條件的發生條件或功能。

public void Main()
{
    var x = new InheritedAction();
}

public abstract class BaseGateAction
{
    public void PerformBaseAction(Action actionToPerformWhileGateIsOpen)
    {
        Open();
        actionToPerformWhileGateIsOpen();
        Close();
    }

    private void Open()
    {
        Console.WriteLine("Gate has been opened");
    }

    private void Close()
    {
        Console.WriteLine("Gate has been closed");
    }
}

public class InheritedAction : BaseGateAction
{
    public InheritedAction()
    {
        PerformBaseAction(() => 
            Console.WriteLine("Attack the dragon while the gate is open"));

        PerformBaseAction(() => 
        {
            Console.WriteLine("Attack the dragon while the gate is open");
            Console.WriteLine("The dragon is victorious and you have been devoured");
        });
    }
}

此代碼示例分別為兩個PerformBaseAction方法調用輸出以下內容:

Gate has been opened
Attack the dragon while the gate is open
Gate has been closed

Gate has been opened
Attack the dragon while the gate is open
The dragon is victorious and you have been devoured
Gate has been closed

這將不僅允許更好的代碼重用,而且允許更多的封裝邏輯。 您總是可以添加其他暴露的方法,這些方法采用先決條件或后決條件,這些條件會影響您是否可以打開門。

public abstract class BaseGateAction
{
    ....    
    public void PerformBaseActionWithPrecondition(Func<bool> precondition, Action actionToPerformWhileGateIsOpen)
    {
        if (precondition())
        {
            PerformBaseAction(actionToPerformWhileGateIsOpen);
        }
        else
        {
            Console.WriteLine("The gate could not be opened!");
        }
    }
    ...
}

可以這樣稱呼:

PerformBaseActionWithPrecondition<bool>(
        () => true == false,
        () => Console.WriteLine("Attack!")
    );

並輸出:

The gate could not be opened!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM