How can i refactor these functions?

MightyBeast

So basically, in game, I have a "wall validator", which checks if wall meets all of the requirements. Then, based on which requirement have failed, program calls appropriate message function.

Here is the code, where I call wall validator:

    internal void PlaceWall(Vector2 wallStartPosition, Vector2 wallEndPosition)
    {
        _wallStartPosition = wallStartPosition;
        _wallEndPosition = wallEndPosition;

        _wallValidator.InitializeVectors(wallStartPosition, wallEndPosition);
        if (_wallValidator.WallDoesNotMeetTheRequirements())
        {
            _wallValidator.SendAppropriateMessage();
            return;
        }

        PlaceNewWall();
    }

Right now I check all requirements two times in two different functions here they are in wall validator:

    internal bool WallDoesNotMeetTheRequirements()
    {
        if (WallPositionIsBeyondBoard()||
            PlayerUsedAllAvailableWalls()||
            WallIsNotOnTheSameLine() ||
            WallIsTooLong() ||
            WallTilesHavePairCoordinates() ||
            WallDoesNotCoverTwoSolidTiles() ||
            WallInterceptsWithOtherWall())
            return true;

        return false;
    }

    internal void SendAppropriateMessage()
    {
        if (WallPositionIsBeyondBoard())
            _player.output?.DisplayWallHasPositionBeyondBoardMessage();
        if (PlayerUsedAllAvailableWalls())
            _player.output?.DisplayNotEnoughWallsMessage();
        if (WallIsNotOnTheSameLine())
            _player.output?.DisplayWallIsNotOnTheSameLineMessage();
        if (WallIsTooLong())
            _player.output?.DisplayWallIsTooLongMessage();
        if (WallTilesHavePairCoordinates())
            _player.output?.DisplayWallTilesHavePairCoordinatesMessage();
        if (WallDoesNotCoverTwoSolidTiles())
            _player.output?.DisplayWallDoesNotCoverTwoSolidTilesMessage();
        if (WallInterceptsWithOtherWall())
            _player.output?.DisplayWallInterceptsWithOtherWallMessage();
    }

How would you refactor these functions?
I've tried making a "Requirement" class, which accepts "check function" and "message to send" in it's constructor, but have failed. This option does not work in testing environment. The reason is that I am using NUnit testing framework, and when I tried to test wall placement without assigning "ConsoleOutput" (Class, which implements all of the message functions), I would always get a "NullPointer" exception at the point of "Requirement" class initialization.
So, basically, what Im trying to say in code is "Send appropriate message to the output if it is not null, but if it is, then just return true". But with every new requirement in current state, i would need to add check function in two different places.
I don't really like this option of "double checking requirement and sending message" and I feel like I'm missing a simple answer to this problem.
P.S. Sorry for my broken english ;D, hope I explained everything that I could in a way that you can understand.

JonasH

As mentioned in the comments, make a enum that returns the result of the operation, inclusive different error cases.

public enum WallPlacementResult{
    Success,
    NotOnTheSameLine,
    TooLong
    ...
}

WallPlacementResult CheckWallRequirements(){
      if (WallIsNotOnTheSameLine()) return WallPlacementResult.NotOnTheSameLine;
      if (WallIsTooLong()) return WallPlacementResult.TooLong;
      ...
    return WallPlacementResult.Success;
}

void SendAppropriateMessage(WallPlacementResult result)
{
    switch(result){
        case WallPlacementResult.NotOnTheSameLine:
             _player.output?.DisplayWallHasPositionBeyondBoardMessage();
        break;
        case WallPlacementResult.TooLong:
        ...
    }
}

Another option might be to use something like a generic result object. Overall I would recommend delegating any UI task, like showing messages, to the UI layer. The checking logic may benefit of being placed in a lower layer to make it easier to unit test etc.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How can I refactor these simple functions and make them more DRY?

How can I refactor these two functions with repeating code?

How do I refactor these two functions?

How do I refactor to avoid passing functions?

How can I refactor two similar functions to reduce the code duplication in Elixir?

How can I refactor two functions into one function that takes a generic argument?

How can i refactor these lines of code?

how can I refactor methods in Javascript

How can I refactor this if elif statements?

How can I refactor to accept multiple clients?

How can I refactor this code to remove duplication?

How can I refactor this bunch of if statements?

How Can I Refactor To Avoid Duplication?

How can I refactor similar requests in React

how can I refactor or friendly programmer view?

How can I refactor the code with many unions

How can I refactor this code in javascript?

How can I refactor API code in Javascript?

How can I refactor to reduce no of lines

can i refactor the select and get element functions into one with typescript generics?

I use many "OR" operator how can i refactor code in JAVA

How can I refactor terraform module that creates vpc?

How can I refactor duplicate field names in Haskell data types?

How can I refactor complicated method with views in Activity or Fragment?

How can I refactor my kotlin code and make it more clear

How can I refactor Tuple<..> to a typed class with descriptive names?

How can I refactor/abstract ngrx actions to be less prone to typos?

How can I tell PHPStorm to refactor namespaces and class names?

How can I refactor HTML markup out of my property files?