메소드 호출 또는 메소드 자체를 보호하는 것이 더 낫습니까?


12

응용 프로그램을 작성 중이며이 시점에 도달했습니다.

private void SomeMethod()
{
    if (Settings.GiveApples)
    {
        GiveApples();
    }

    if (Settings.GiveBananas)
    {
        GiveBananas();
    }
}

private void GiveApples()
{
    ...
}

private void GiveBananas()
{
    ...
}

이것은 매우 직설적으로 보입니다. 몇 가지 조건이 있으며 조건이 맞으면 메소드가 호출됩니다. 그러나 나는 다음과 같이하는 것이 더 낫다고 생각했다.

private void SomeMethod()
{
    GiveApples();
    GiveBananas();
}

private void GiveApples()
{
    if (!Settings.GiveApples)
    {
        return;
    }

    ...
}

private void GiveBananas()
{
    if (!Settings.GiveBananas)
    {
        return;
    }

    ...
}

두 번째 경우에는 각 메소드가 자체를 보호하므로 해당 메소드 중 하나 GiveApples또는 GiveBananas외부 SomeMethod에서 호출 된 경우에도 설정에 올바른 플래그가있는 경우에만 실행됩니다.

이것이 실제로 문제로 고려해야 할 것입니까?

내 현재 상황 에서이 두 가지 메소드 가이 메소드 외부에서 호출 될 가능성은 거의 없지만 아무도 그것을 보장 할 수는 없습니다.


5
먼저 확인하지 않고 GiveApples 또는 GiveBananas를 호출해야하는지 여부에 따라 다릅니다. 가드는 메소드와 연관되어 있기 때문에 아마도 메소드에 속합니다.
Robert Harvey

답변:


13

나는 경비원이 그 방법이 지켜야 할 것으로 생각 합니다 . 예제에서 Settings.GiveApples가 false 인 경우이 메소드는 사과를 제공하지 않아야합니다.

이 경우 경비원은 분명히 메소드 내부에 속합니다. 이렇게하면 경비원을 먼저 확인하지 않고 응용 프로그램의 다른 지점에서 실수로 전화를 걸 수 없습니다.

반면에 설정이 호출 방법에만 적용되고 코드의 다른 곳에서 설정에 관계없이 GiveApples를 제공 할 수있는 경우 가드가 아니며 호출 코드에 있어야합니다.


5

방법 자체 내에 보호대를 두십시오. 의 경비원을 관리 GiveApples()하거나 GiveBananas()책임을지지 않아야합니다 GiveApples().

디자인 관점에서 볼 때 SomeMethod()과일이 필요하다는 사실 만 알고 있어야하며 응용 프로그램을 얻기 위해 응용 프로그램이 무엇을해야하는지 신경 쓰지 않아야합니다. SomeMethod()특정 과일의 검색을 허용하는 전역 설정이 있음을 알고 있다면 과일 검색의 추상화가 유출됩니다 . 이 새로운 가드를 구현하기 위해 별도로 리팩터링해야 GetApples()하거나 GetBananas()필요로 하는 모든 메소드가 있으므로 가드 메커니즘이 변경되면 캐스케이드가 진행됩니다 . 코드를 작성할 때 확인하지 않고 과일을 잊어 버리는 것도 매우 쉽습니다.

이 시나리오에서 고려해야 할 사항은 설정으로 인해 응용 프로그램에서 결과를 얻을 수없는 경우 응용 프로그램이 어떻게 반응해야하는지입니다.


4

일반적으로 외부 제공 설정과 같은 테스트 책임과 "핵심 비즈니스 코드"와 같은 책임을 분리하는 것이 좋습니다 GiveApples. 한편, 함께 속한 것을 그룹화하는 기능을 갖는 것도 좋은 생각입니다. 다음과 같이 코드를 리팩터링하여 두 가지 목표를 모두 달성 할 수 있습니다.

private void SomeMethod()
{
    GiveApplesIfActivated();
    GiveBananasIfActivated();
}

private void GiveApplesIfActivated()
{
    if (Settings.GiveApples)
    {
        GiveApples();
    }
}

private void GiveBananasIfActivated()
{
    if (Settings.GiveBananas)
    {
        GiveBananas();
    }
}

private void GiveApples()
{
    ...
}

private void GiveBananas()
{
    ...
}

이를 통해 클래스의 종속성없이 코드를 리팩터링 GiveApples하거나 GiveBananas별도의 장소로 리팩토링 할 수 있습니다 Settings. 그것은 당신이 아무 상관없이 단위 테스트에서 해당 메소드를 호출하고자 할 때 분명히 유익합니다 Settings.

그러나 프로그램에서, 심지어 어떤 상황에서도, 심지어 테스트 컨텍스트에서, 항상 확인 GiveApples되는 컨텍스트 외부 와 같은 것을 호출하는 것이 항상 잘못된 경우, Settings.GiveApples확인 GiveApples하지 않고 같은 기능을 제공하는 Settings것은 오류가 발생하기 쉽다는 인상을 받고 있습니다 그런 다음 Settings.GiveApples내부 를 테스트하는 변형을 고수하십시오 GiveApples.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.