#regions는 반 패턴 또는 코드 냄새입니까?


264

C #에서는 #region/ #endregion키워드를 사용하여 편집기에서 코드 영역을 축소 할 수 있습니다. 내가 할 때마다 다른 클래스 나 메소드로 리팩토링 될 수있는 큰 코드 덩어리를 숨기려고합니다. 예를 들어, 관리하기 쉽도록 3 개 또는 4 개의 영역이있는 500 줄의 코드가 포함 된 메서드를 보았습니다.

지역을 신중하게 사용하는 것이 문제의 징후입니까? 나에게 그런 것 같습니다.


9
참고 : CodeMap은 지역에 대한 요구를 거의 제거합니다. visualstudiogallery.msdn.microsoft.com/…- 클릭하면 메소드 / 속성 / 무엇으로 이동합니다. 나는 매일 그것을 사용하며 생산성과인지 적 측면에서 얼마나 많은 이익을 얻는 지 놀랍습니다. 수업에서 훨씬 더 '조감도'를 얻습니다.

7
누구나 이것을 위키로 만들 수 있습니까? 이 질문에 대한 옳고 그름의 대답은 없습니다 (이성 내에서), 그것은 거의 완전히 주관적입니다.
Ed S.

6
가치가있는 것에 대해 Jeff Atwood는 그들을 미워합니다 . 그는 그들이 잘못된 코드를 숨기고 있다고 주장한다.
Brian

3
코드 냄새는 샤워하지 않고 탈취제를 사용하지 않는 개발자입니다!
marko

5
잘 짜여진 코드로 정교하게 제작 된 지역은 Febreeze를 약간 짜서 거친 소파에서하는 것입니다. 교체 할 (시간) 돈을 찾을 때까지 견딜 수 있습니다.
Newtopian

답변:


284

코드 냄새는 잠재적으로 버그의 수를 증가시키는 디자인에 문제가 있음을 나타내는 증상입니다. 이는 지역의 경우에는 해당되지 않지만 지역은 긴 방법처럼 코드 냄새를 유발할 수 있습니다.

이후:

반 패턴 (또는 반 패턴)은 일반적으로 사용될 수 있지만 실제로는 비 효과적이고 반 생산적인 사회 또는 비즈니스 운영 또는 소프트웨어 엔지니어링에 사용되는 패턴입니다.

영역 안티 패턴입니다. 코드의 품질이나 가독성을 높이 지 않는 더 많은 작업이 필요하므로 버그 수를 줄이지 않으며 코드를 리팩토링하기가 더 복잡해질 수 있습니다.

메소드 안에 영역을 사용하지 마십시오. 대신 리팩터링

방법은 짧아야 합니다. 메소드에 10 개의 행만있는 경우 다른 5 개에서 작업 할 때 영역을 사용하여 5 개를 숨기지 않을 수 있습니다.

또한 각 메소드는 하나만 수행해야합니다 . 반면에 지역은 다른 것을 분리 하기위한 입니다. 방법이 A, B를 수행하는 경우 두 영역을 만드는 것이 논리적이지만 잘못된 접근 방식입니다. 대신 메소드를 두 개의 개별 메소드로 리팩토링해야합니다.

이 경우 영역을 사용하면 리팩토링이 더 어려워 질 수 있습니다. 당신이 가지고 있다고 상상해보십시오 :

private void DoSomething()
{
    var data = LoadData();
    #region Work with database
    var verification = VerifySomething();
    if (!verification)
    {
        throw new DataCorruptedException();
    }

    Do(data);
    DoSomethingElse(data);
    #endregion

    #region Audit
    var auditEngine = InitializeAuditEngine();
    auditEngine.Submit(data);
    #endregion
}

첫 번째 영역을 축소하여 두 번째 영역에 집중하는 것은 위험 할뿐만 아니라 흐름을 중지하는 예외를 잊어 버릴 수 있습니다 ( return대신 가드 조항이있을 수 있으므로 더 찾기가 어렵습니다) 코드를 이런 식으로 리팩토링해야하는 경우 :

private void DoSomething()
{
    var data = LoadData();
    #region Work with database
    var verification = VerifySomething();
    var info = DoSomethingElse(data);

    if (verification)
    {
        Do(data);
    }

    #endregion

    #region Audit
    var auditEngine = InitializeAuditEngine(info);
    auditEngine.Submit(
        verification ? new AcceptedDataAudit(data) : new CorruptedDataAudit(data));
    #endregion
}

이제 영역은 의미가 없으며 첫 번째 영역의 코드를 보지 않고 두 번째 영역의 코드를 읽고 이해할 수 없습니다.

때때로 내가 본 또 다른 경우는 다음과 같습니다.

public void DoSomething(string a, int b)
{
    #region Validation of arguments
    if (a == null)
    {
        throw new ArgumentNullException("a");
    }

    if (b <= 0)
    {
        throw new ArgumentOutOfScopeException("b", ...);
    }
    #endregion

    #region Do real work
    ...
    #endregion
}

인수 유효성 검사가 수십 개의 LOC에 걸쳐 시작될 때 영역을 사용하고 싶어하지만 .NET Framework 소스 코드에서 사용되는이 문제를 해결하는 더 좋은 방법이 있습니다.

public void DoSomething(string a, int b)
{
    if (a == null)
    {
        throw new ArgumentNullException("a");
    }

    if (b <= 0)
    {
        throw new ArgumentOutOfScopeException("b", ...);
    }

    InternalDoSomething(a, b);
}

private void InternalDoSomething(string a, int b)
{
    ...
}

메소드 외부의 영역을 사용하여 그룹화하지 마십시오

  • 어떤 사람들은 그것들을 사용하여 필드, 속성 등을 함께 그룹화합니다. 이 접근법은 잘못되었습니다. 코드가 StyleCop 호환 인 경우 필드, 속성, 개인 메서드, 생성자 등이 이미 그룹화되어 찾기 쉽습니다. 그렇지 않다면 코드베이스 전체에 균일 성을 보장하는 규칙 적용에 대해 생각할 시간입니다.

  • 다른 사람들은 영역을 사용 하여 유사한 엔티티를 많이 숨 깁니다 . 예를 들어, 수백 개의 필드가있는 클래스 (주석과 공백을 세면 최소 500 줄의 코드 작성)가있는 경우 해당 필드를 영역 안에 넣고 축소하여 잊어 버리려는 유혹을받을 수 있습니다. 다시 말하지만, 당신은 잘못하고 있습니다 : 클래스에 너무 많은 필드가 있으므로 상속을 사용하거나 객체를 여러 객체로 슬라이스하는 것에 대해 더 잘 생각해야합니다.

  • 마지막으로 일부 사람들은 영역을 사용 하여 관련 항목그룹화 하려는 유혹을받습니다 . 델리게이트와의 이벤트 또는 IO와 관련된 다른 방법과의 IO 관련 방법 등. 첫 번째 경우, 유지하기 어려운 혼란이됩니다. 읽고 이해하십시오. 두 번째 경우, 더 나은 디자인은 아마도 여러 클래스를 만드는 것입니다.

지역에 잘 사용됩니까?

아니요 . 레거시 사용이있었습니다 : 생성 된 코드. 그럼에도 불구하고 코드 생성 도구는 부분 클래스를 대신 사용해야합니다. C #에 지역 지원이있는 경우 대부분 레거시 사용으로 인해 발생하고 너무 많은 사람들이 코드에 지역을 사용했기 때문에 기존 코드베이스를 손상시키지 않으면 서 지역을 제거 할 수 없습니다.

에 대해 생각하십시오 goto. 언어 나 IDE가 기능을 지원한다고해서 매일 사용해야한다는 의미는 아닙니다. StyleCop SA1124 규칙은 명확합니다. 영역을 사용해서는 안됩니다. 못.

현재 동료의 코드를 코드 검토하고 있습니다. 코드베이스에는 많은 지역이 포함되어 있으며 실제로 지역을 사용하지 않는 방법과 지역이 나쁜 코드로 이어지는 이유의 완벽한 예입니다. 여기 몇 가지 예가 있어요.

4 000 LOC 몬스터 :

최근 Programmers.SE 어딘가에서 파일을 너무 많이 포함 할 때 using( "사용하지 않은 사용 제거"명령을 실행 한 후)이 파일 내부의 클래스가 너무 많이 수행되고 있음을 나타내는 좋은 신호입니다. 파일 자체의 크기에도 동일하게 적용됩니다.

코드를 검토하는 동안 4 000 LOC 파일을 발견했습니다. 이 코드의 작성자는 단순히 15 줄의 동일한 메소드를 수백 번 복사하여 붙여 넣은 것으로 나타 났으며 변수의 이름과 호출 된 메소드를 약간 변경했습니다. 간단한 정규 표현식을 사용하면 몇 가지 제네릭을 추가하여 파일을 4 000 LOC에서 500 LOC로 트리밍 할 수있었습니다. 좀 더 영리한 리팩토링을 사용하면이 클래스가 수십 줄로 줄어들 수 있습니다.

지역을 사용함으로써 저자는 코드를 유지 관리하는 것이 불가능하고 잘못 작성되었다는 사실을 무시하고 코드를 리팩토링하는 대신 코드를 크게 복제하도록 권장했습니다.

지역“Do A”, 지역“Do B”:

또 다른 훌륭한 예로는 단순히 작업 1, 작업 2, 작업 3 등을 수행 한 괴물 초기화 방법이 있습니다. 각각 독립적으로 5 ~ 6 개의 작업이있었습니다. 각 작업은 컨테이너 클래스에서 무언가를 초기화합니다. 이러한 모든 작업은 하나의 방법으로 그룹화되고 지역으로 그룹화되었습니다.

이것은 한 가지 장점이있었습니다.

  • 이 방법은 지역 이름을보고 이해하기가 매우 분명했습니다. 다시 말해 리팩토링 된 동일한 방법은 원래 방법과 동일합니다.

반면에 문제는 여러 가지였습니다.

  • 지역간에 종속성이 있는지는 확실하지 않았습니다. 바라건대, 변수 재사용은 없었습니다. 그렇지 않으면 유지 관리가 훨씬 악몽이 될 수 있습니다.

  • 이 방법은 테스트하기가 거의 불가능했습니다. 한 번에 20 가지를 수행하는 방법이 올바르게 수행되는지 어떻게 쉽게 알 수 있습니까?

필드 영역, 속성 영역, 생성자 영역 :

검토 된 코드에는 모든 필드, 모든 속성 등을 그룹화하는 많은 영역이 포함되어 있습니다. 이는 명백한 문제인 소스 코드 증가입니다.

파일을 열고 방대한 필드 목록을 보면 클래스를 먼저 리팩터링 한 다음 코드를 사용하는 경향이 있습니다. 지역에서는 물건을 무너 뜨리고 잊어 버리는 습관이 있습니다.

또 다른 문제는 모든 곳에서 수행하면 하나의 블록 영역을 만드는 것입니다. 이것은 실제로 내가 검토 한 코드에서 #region Constructor하나의 생성자 를 포함하는 많은 경우였습니다 .

마지막으로 필드, 속성, 생성자 등 은 이미 순서대로되어 있어야 합니다. 그것들이 관례 (대문자로 시작하는 상수 등)와 일치하면 요소의 유형이 멈추고 다른 시작 부분이 이미 분명하므로 명확하게 영역을 만들 필요가 없습니다.


13
나는 적어도 #regions의 방어 적 사용이 몇 가지 있다고 생각합니다. 예를 들어, 가려지지 않은 가드 절의 붕괴 (입력 매개 변수 확인). 또 다른 예는 API 경계에서 예외 처리입니다. 예외를 래핑하기 위해 다른 메소드를 호출하여 스택 추적에 영향을 미치지 않는 경우가 많으므로 랩하고 다시 던질 코드가 몇 줄 있습니다. 이 코드는 종종 관련이없는 코드이므로 안전하게 축소 할 수 있습니다.
Daniel B

9
현실 점검. 유용한 메소드 간 #regions가 많이 있습니다. 그중 일부에서 수십에서 수백 개의 줄을 가진 중첩 된 제어 논리를 가진 수백 줄의 방법을 가지고 있다면 적어도 지역에 바보가 있다는 것을 감사하십시오.
radarbob

37
@radarbob : 간단히 말해서, 지역은 처음에는 존재하지 않아야하는 엉터리 코드에 도움이됩니다.
Arseni Mourzenko

41
-1 (평판이 있다면). 유형 멤버가 잘 정리되고 분리되어 있어도 많은 멤버가있을 수 있습니다. 영역을 사용하면 작업하려는 메소드에 도달하기 위해 10 또는 12 개의 특성과 연관된 게터 및 세터를 스크롤해야합니다. 유일한 대안은 모든 속성을 개별적으로 축소하는 것입니다. 이것은 제가 좋아하는 것이 아닙니다. 제공되는 대규모 표시 / 숨기기 기능 영역은 매우 유용합니다. 나는 방법 내 영역에 동의합니다.
Asad Saeeduddin

14
나는이 답변에 엄격하게 동의하지 않습니다 : 코드 악취와 지역은 서로 관련이 없습니다. 코드에 악취가 발생하면 지역이 있거나없는 악취가 발생합니다. 지역을 사용하는 방법은 수업을 지역으로 분리하는 것입니다. 일반적으로 공용 속성, 공용 메서드, 개인 필드, 개인 메서드와 같은 패턴을 고수합니다. 그것이 내가 지역을 가진 유일한 용도입니다. 다른 어떤 것도 코드에서 SRP 보안 주체를 위반했을 수 있습니다.
Alexus

113

얼마나 많은 사람들 이 열정적으로 지역을 싫어하는지는 정말 놀랍습니다 !

나는 많은 반대 의견에 전적으로 동의합니다. 코드를 #region보이지 않게 숨기면 좋지 않습니다. 클래스를 #regions별도의 클래스로 리팩토링해야 할 때로 클래스를 나누는 것은 분명히 실수입니다. a #region를 사용하여 중복 된 의미 정보를 임베드 하는 것이 좋습니다.

그러나 그중 어느 것도 코드에서 영역을 사용하는 데 본질적으로 잘못된 것이 없다는 것을 의미하지 않습니다 ! 나는 대부분의 사람들의 반대 의견이 다른 사람들이 이와 같은 IDE 기능을 잘못 사용하려는 경향이있는 팀에서 일했다고 가정 할 수 있습니다. 본인은 일차적으로 일하는 것이 고급 스러우며 지역이 워크 플로를 구성하는 데 도움이 된 방식에 감사합니다. 어쩌면 그것은 강박 관념 장애 일지 모르지만 화면에서 얼마나 깔끔하고 우아하게 작성 되었든 한 번에 많은 코드를보고 싶지 않습니다. 논리적 지역으로 물건을 분리하면 제가 코드를 붕괴 할 수 없는 내가 코드에 작업에 대한 관심을 수행하십시오신경써 필자가 잘못 작성한 코드를 무시하지 않고있는 것보다 코드를 리팩터링하는 것이 이치에 맞지 않으며 추가 "메타"조직은 무의미한 것이 아니라 설명 적입니다.

이제 C ++에서 Windows API에 직접 프로그래밍하는 데 더 많은 시간을 보냈으므로 지역에 대한 지원이 C #만큼 좋기를 바랍니다. 대체 GUI 라이브러리를 사용하면 코드가 더 간단하거나 명확 해 지므로 화면에서 관련없는 코드 노이즈를 제거 할 필요가 없지만 다른 이유는 있습니다. 키보드와 IDE에 능숙하여 지역으로 세분화 된 코드를 확장 / 축소하는 데 1 초도 걸리지 않습니다. 내가 생각하고있는 코드만으로 의식의 초점을 제한하려고 노력하는 것은 두뇌의 힘을 아끼는 시간보다 가치가 있습니다. 그것은 모두 하나의 클래스 / 파일에 속하지만 동시에 내 화면에 속하지는 않습니다.

요점은 #regions코드를 분리하고 논리적으로 나누는 데 사용 하는 것이 모든 비용을 피하는 것이 나쁜 것은 아니라는 것입니다. Ed가 지적했듯이 "코드 냄새"가 아닙니다. 코드 냄새가 나면 해당 코드가 해당 지역에서 나오는 것이 아니라 해당 지역에 묻으려는 코드에서 온 것인지 확인할 수 있습니다. 기능이보다 체계적으로 구성되거나 더 나은 코드를 작성하는 데 도움이된다면 사용이라고합니다 . 방해가되거나 잘못 사용하는 경우 사용 을 중지 하십시오. 최악의 상황이 최악의 상황에서이를 사용하는 사람들과 팀을 이루어야하는 경우 키보드 단축키를 외우면 코드 외곽선이 꺼집니다. Ctrl+ M, Ctrl+P. 그리고 불평을 그만두십시오. 때때로 나는 이것이 "진정한", "하드 코어"프로그래머로 보이기를 원하는 사람들이 스스로 시도하고 증명하는 것을 좋아하는 또 다른 방법이라는 느낌을받습니다. 구문 색상 표시를 피하는 것보다 영역을 피하는 것이 좋습니다. 그것은 당신을 더 사나운 개발자로 만들지 않습니다.

모든 방법 에서 , 메소드 내의 영역 은 단지 넌센스입니다. 당신이 그것을 원할 때마다, 당신은 별도의 방법으로 리팩토링해야합니다. 변명하지.


9
잘했다. 조직의 영역 사용은 IDE의 "공백보기"옵션을 토글하는 것보다 더 해롭지 않습니다. 개인적인 취향입니다.
Josh

24
내 모델의 속성을 단순히 래핑하는 10 또는 20 개의 속성을 가진 ViewModels로 WPF를 작업하면서 지역을 좋아합니다. 지역에 해당 속성을 집어 넣을 수 있습니다 (만지지 않아도됩니다) . 관련 코드를 주시하십시오 .
Kirk Broadhurst

4
전적으로 동의합니다. .NET 2.0에서 속성의 길이는 약 8-10 줄입니다. 클래스에 20 개가 넘는 속성이 있으면 많은 공간 을 차지합니다 . 지역은 붕괴에 완벽합니다.
Kristof Claes

6
@Kristof : 간단한 입력 유효성 검사를 수행하는 .NET 4.0의 속성과 동일합니다. 자동 속성은 내 목적을 위해 그다지 마 법적이지 않았습니다.
Cody Grey

8
지역을 싫어하는 사람들이 WPF 응용 프로그램을 개발하지 않았거나 데이터 바인딩 및 명령 바인딩과 같은 WPF 정의 기능을 사용한 적이 없다는 왼쪽 공을 내고 싶습니다. 이러한 작업을 수행하기 위해 코드를 설정하기 만하면 많은 공간을 차지하므로 일반적으로 다시 볼 필요가 없습니다.
l46kok

70

우선, 더 이상 "코드 냄새"라는 용어를 참을 수 없습니다. 너무 자주 사용되며 좋은 코드를 물지 않으면 인식하지 못하는 사람들이 많이 사용합니다. 어쨌든 ...

나는 개인적으로 많은 지역을 사용하는 것을 좋아하지 않습니다. 코드를 얻는 것이 더 어려워지고 코드가 관심이 있습니다. 매우 자주 만질 필요가없는 코드가 많을 때 지역을 좋아합니다. 그 외에도 그들은 내 방식대로 들어가는 것처럼 보이며 "비공개 방법", "공용 방법"등과 같은 지역은 나를 미치게합니다. 그들은 다양한 의견에 유사합니다 i++ //increment i.

또한이 용어는 텍스트 편집기의 레이아웃이 아니라 프로그램 논리 / 디자인 패턴을 설명하는 데 일반적으로 사용되므로 영역 사용은 실제로 "반 패턴"이 될 수 없다고 덧붙입니다. 이것은 주관적입니다. 당신을 위해 일하는 것을 사용하십시오. 안티 패턴이 중요한 지역을 과도하게 사용하여 유지 보수 할 수없는 프로그램을 끝내지 않을 것입니다. :)


2
일반적으로 코드 냄새 주석에 대해 의견을 제시하지만이 경우에는 정확합니다. 비 코드는 코드 냄새가 될 수 없습니다. +2!

7
하하, "코드 냄새"라는 용어를 정확하게 사용할 수 없다고 말하는 것은 아닙니다. 그것은 가능하지만, 요즘 너무 많이 던져서 내 즉각적인 반응은 성가신 것입니다. 특히 그것을 이해하거나 비판적으로 생각하지 않고 듣는 것을 실제로 반복하는 사람들에게서 오는 경우 특히 그렇습니다. "함수에서 5 개 이상의 지역 변수는 코드 냄새입니다"와 같은 문장은 그 사람이 실제로 경험 한 경험이 얼마나 적은지를 보여줍니다.
Ed S.

13
코드 냄새에 대한 귀하의 의견을 이해하지 못합니다. 코드 냄새는 문제가 있음을 나타내지 않으며 문제가있을 수 있습니다.
Craig

7
용어 코드 냄새를 견디기 위해 +1. 개인 방법이 코드 냄새라고 주장하는 게시물을 보았을 때 나는 지쳤다. 그러나 전반적으로 나는 지역에 대한 당신의 불쾌감에 동의하지 않습니다. 나는 쉽게 산만하다. 사실 VS에 VB4 모드가 있으면 한 번에 하나의 메소드 만 표시 할 수 있다면 좋을 것입니다.
Josh

7
그냥 완벽하게 은유를 잘못 사용한다고해서 은유를 평가 절하해서는 안된다고 말하고 싶었습니다. "코드 냄새"는 큰 은유로, 즉시 이해하고 쉽게 기억하며 쉽게 사용할 수 있습니다. "코드 냄새"비유를 적용하는 것이 여전히 요점을 얻는 가장 좋은 방법 인 곳은 여전히 ​​많습니다.
에릭 킹

23

그렇습니다 지역은 코드 냄새입니다!

컴파일러에서 영역이 모두 제거되어 기쁩니다. 모든 개발자는 다른 프로그래머에게 결코 가치가없는 자신의 무의미한 정리 체계를 고안합니다. 나는 아기를 꾸미고 아름답게 만들고자하는 프로그래머와 관련이 있으며 실제 가치와는 아무런 관련이 없습니다.

"게 이즈, 내 동료가 여기에서 일부 지역을 사용했으면 좋겠다"고 생각하는 한 가지 예가 있습니까?

모든 영역을 자동으로 확장하도록 IDE를 구성 할 수는 있지만 여전히 눈이 멀고 실제 코드를 읽는 데 어려움이 있습니다.

모든 공개 방법이 함께 묶여 있는지 여부는 정말로 덜 중요합니다. 축하합니다. 변수 선언과 초기화의 차이점을 알고 코드에 표시 할 필요가 없습니다.

무가치 손질!

또한 파일을 사용하고 영역을 사용하여 '정보 아키텍처'가 필요한 경우 핵심 문제와 싸우고 싶을 수 있습니다. 수업이 너무 큽니다! 작은 부분으로 나누는 것이 훨씬 유리하며 제대로 수행되면 진정한 의미 / 가독성이 추가됩니다.


#regions는 컴파일러의 일부입니까? 나는 그들이 무시할 수있는 IDE에 대한 지시 사항이라고 생각했습니다.
Steve Rukuts

2
C # 코드를 구문 분석 할 때 컴파일러는이를 무시해야합니다. 그것을 무시하지 않으면 던져 버릴 것입니다. 나는 그런 식으로 의미합니다.
Joppe December

1
"예,"제 동료가 여기에서 일부 지역을 사용했으면 좋겠습니다! " 그렇습니다. 개인 메서드와 공용 메서드가있는 클래스가있는 경우 공용 메서드를 리팩터링 할 때 반드시 개인 코드를 만질 필요가 없으며 그 반대도 마찬가지이므로 지역에서 분리합니다.
Anshul

아웃소싱 된 코드는 본 적이 없습니다. Sooo 여러 번 지역은 아웃소싱 코드에서 볼 수 있었을 것입니다. 코드가 짜증나더라도 적어도 논리적으로 그룹화되어 있다면 이해하기가 훨씬 쉬웠을 것입니다. 비록 그들의 코드가 논리적 인 기회가 아니라면 그 지역도 그렇지 않을 것이므로 아마도 더 나빴을 것입니다. 그래도 제대로 사용하면 지역이 좋습니다.
Nickmccomb

15

개인적으로 다양한 유형의 메소드 또는 코드 부분을 그룹화하는 방법으로 영역을 사용합니다.

따라서 코드 파일을 열 때 다음과 같이 보일 수 있습니다.

  • 공공 재산
  • 생성자
  • 저장 방법
  • 방법 편집
  • 개인 헬퍼 메소드

메소드 안에 영역을 넣지 않습니다. 코드 냄새의 징조 인 IMHO. 나는 한때 1200 줄이 넘는 방법을 발견했고 그 안에 5 개의 다른 지역이있었습니다. 무서운 광경이었다!

다른 개발자를 위해 더 빨리 찾을 수있는 방식으로 코드를 구성하는 방법으로 코드를 사용하는 경우 문제의 징후라고 생각하지 않습니다. 메소드 내부에서 코드 행을 숨기려면이 메소드를 다시 생각할 시간이라고 말하고 싶습니다.


14
어. 나는 이것이 주관적인 주제라는 것을 알고 있지만, 사람, 나는이 계획을 참을 수 없습니다. 내 경험에 따르면 추가 된 '조직'은 전혀 도움이되지 않으며 코드 탐색에 어려움을 겪습니다. 또한 액세스 수정 자뿐만 아니라 논리적 책임에 의한 그룹화 방법을 선호합니다. 공용 인터페이스의 경우 일반적으로 각 메소드 / 프로퍼티를 그룹화하지만 보호 된 메소드가 개인 헬퍼 함수를 ​​호출하는 경우가 종종 있으며,이 경우 헬퍼 함수 (만 사용 가능)가 위 또는 아래에있는 것을 선호합니다. 그것을 호출하는 메소드.
Ed S.

3
@ Ed S.- "내가 좋아 보인다"고 말한 이유입니다. 매우 주관적입니다. 나는 모든 파일이 그렇게 보일 것이라고 말하는 것이 아닙니다. 그들이 한 경우에 놀랐습니다. 복잡한 주제에 대한 예일뿐입니다. :)
Tyanna

아시다시피 말했듯이 주관적입니다. 당신 / 당신의 팀을 위해 작동하는 무엇이든. 나는 그것이 작동하지 않기 때문에이 계획을 위해 그것을 가지고 있지만, 나는 이것을 한 프로젝트를 유지해야했습니다. 그것은 나를 미치게했다.
Ed S.

3
@EdS. 따라서 vs에서 옵션으로 이동하여 지역을 끄십시오. 문제 해결됨.
Andy

왜 객체에 저장 메소드가 있습니까? :(
TheCatWhisperer

10

사용하여 #region매우 큰 클래스를 읽을 수 있도록 블록은 일반적으로 단일 책임의 원칙을 위반하는 기호입니다. 그들이 행동을 그룹화하는 데 사용된다면 , 수업이 너무 많은 일을하고 있을 가능성 이 있습니다 (다시 SRP를 위반).

"코드 냄새"줄을 고수하면서 #region블록 자체는 코드 냄새가 아니라 냄새를 숨기려고하는 "코드에 대한 열풍"입니다. 과거에는 톤을 많이 사용했지만 리팩토링을 시작하면 많이 숨기지 않기 때문에 더 적게 보이기 시작합니다.


5

여기서 핵심 단어는 "유의 한"입니다. 메소드 안에 영역을 넣는 것이 합리적이라고 생각하기는 어렵습니다. 코드 숨김과 게으름이 너무 많습니다. 그러나 몇 가지 영역을 여기저기서 코드로 작성해야하는 이유가있을 수 있습니다.

많은 지역이 있다면 코드 냄새라고 생각합니다. 지역은 종종 향후 리팩토링을위한 가능한 장소의 힌트입니다. 많은 지역은 누군가가 실제로 힌트를 얻지 못한다는 것을 의미합니다.

신중하게 사용하면 많은 메소드를 가진 단일 클래스의 구조와 각각에 몇 개의 메소드를 가진 많은 클래스의 구조 사이에 좋은 중간 근거를 제공합니다. 클래스가 여러 클래스로 리팩토링되어야하는 시점에 가까워지기 시작했을 때 가장 유용하지만 아직은 그렇지 않습니다. 관련 메소드를 그룹화하여 나중에 계속 증가하는 관련 메소드 세트를 자체 클래스로 쉽게 추출 할 수 있습니다. 예를 들어, 500 줄의 코드에 접근하는 클래스가있는 경우 한 지역에서 함께 수집 된 총 200 줄의 코드를 사용하는 메소드 집합은 어떻게 든 리팩터링하기에 좋은 조각 일 것입니다. 방법도 좋은 대상이 될 수 있습니다.

영역을 사용하는 또 다른 방법은 큰 방법을 리팩토링하는 부정적인 영향 중 하나를 줄이는 것입니다. 독자가 주로 관련이없는 다른 방법을 찾기 위해 스크롤해야하는 작고 간결하며 쉽게 재사용되는 많은 방법. 지역은 독자를 위해 메소드와 헬퍼를 메타 캡슐화하는 좋은 방법이 될 수 있으므로 클래스의 다른 측면에서 작업하는 사람은 메소드를 축소하고 코드의 해당 부분을 빠르게 닫을 수 있습니다. 물론 이것은 지역이 실제로 체계적으로 구성되어 본질적으로 코드를 문서화하는 다른 방법으로 사용되는 경우에만 작동합니다.

일반적으로 지역은 내가 조직을 유지하고 코드를 "문서화"하는 데 도움이되며 지역을 사용하지 않는 경우보다 훨씬 빨리 리팩토링 할 수있는 장소를 찾도록 도와줍니다.


4

저는 주로 CRUD 서버 클래스에 지역을 사용하여 다양한 유형의 작업을 구성합니다. 그럼에도 불구하고 나는 그들없이 기꺼이 갈 수있었습니다.

광범위하게 사용하면 적기가 발생합니다. 나는 너무 많은 책임이있는 수업을 찾고있을 것입니다.

내 경험상 수백 줄의 코드가있는 방법은 분명히 냄새입니다.


4

내 경험 법칙 : 파일에 5 개 이상의 영역이 있으면 코드 냄새가납니다

즉, 필드, 메서드, 속성 및 생성자를 묘사하는 것이 좋을 수도 있지만 자체 영역의 다른 모든 메서드를 래핑하기 시작하면 뭔가 잘못되었습니다.

.. 그렇습니다. 저는 코딩 표준이 낮거나 코드 생성 또는 두 가지 모두로 인해 많은 프로젝트를 수행했습니다. 코드에 대한 좋은 개요를 얻으려면 Visual Studio에서 모든 개요를 빠르게 전환 해야하는 것은 오래되었습니다.


4

지역에서 사용

나는 윈도우 폼 앱 이전에 "핸드 코딩"인터페이스 이벤트를 위해 개인적으로 사용했습니다.

그러나 우리는 SQL 처리를 위해 코드 생성기를 사용하며 영역을 사용하여 선택, 업데이트, 삭제 등의 유형의 메소드를 자동으로 정렬합니다.

따라서 자주 사용하지는 않지만 큰 코드 덩어리를 제거하는 데 완벽합니다.


1
비슷한 코드 생성기를 사용했으며 생성 된 코드를 제거하기 위해 부분 클래스를 사용하는 것을 선호합니다.
Craig

우리는 영역이 생성 된 코드 안에 있기 때문에 (필요한 경우) 더 쉽게 읽거나 디버깅 할 수 있습니다.
Ken

4

영역 IN 코드가 있으면 확실히 문제가 있습니다 (생성 된 코드의 경우는 제외). 코드에 영역을 넣는 것은 기본적으로 "리 팩터 리팩터링"이라고 말합니다.

그러나 다른 경우가 있습니다. 내가 얼마 전에 다시 한 번 생각 나게하는 것 : 사전에 계산 된 수천 개의 항목이있는 테이블. 그것은 기하학에 대한 설명이며, 테이블에 오류가 없기 때문에 그것을 볼 기회가 결코 없습니다. 물론 리소스 등에서 데이터를 얻을 수 있었지만 쉽게 읽을 수 있도록 컴파일러를 사용할 수는 없었습니다.


1
별도의 파일에 저장된 부분 클래스 또는 HardcodedDataSource 구현으로 주입 된 IMyDataSource가 더 나은 사용 사례입니다.
Bryan Boettcher 2016 년

3

최근 프로젝트에는 여러 지역이 포함 된 1700 라인 방법이있었습니다. 흥미로운 점은 해당 영역이 방법 내에서 수행되고있는 별개의 동작을 구분했다는 것입니다. 코드의 기능에 영향을 미치지 않고 각 지역에서 리 팩터-> 추출 방법을 수행 할 수있었습니다.

일반적으로 보일러 플레이트 코드를 숨기는 데 사용되는 영역이 유용합니다. 속성, 필드 등을 숨기기 위해 영역을 사용하지 않는 것이 좋습니다. 왜냐하면 클래스 내에서 작업 할 때보 기가 너무 다루기 힘들면 클래스를 더 세분화해야한다는 신호 일 것입니다. 그러나 어려운 방법으로, 메소드 내에 영역을 넣는 경우 영역에서 해당 블록을 줄 바꿈하는 것보다 발생하는 상황을 설명하는 다른 방법을 추출하는 것이 좋습니다.


3

좋은 품질의 코드에서 영역을 사용할 수 있습니까? 아마. 나는 그들이 많은 경우에 내기했다. 그러나 나의 개인적인 경험은 나를 매우 의심하게 만든다. 나는 거의 독점적으로 오용 된 지역을 보았다. 나는 지겹지 만 여전히 낙관적이라고 말하고 싶습니다.

지금까지 본 지역 사용 코드를 크게 세 가지 범주로 나눌 수 있습니다.

  • 잘못 고려한 코드 : 내가 본 대부분의 코드는 지역을 가난한 사람의 인수 분해 도구로 사용합니다. 예를 들어, 다른 목적으로 특수화하는 것이 합리적 수준으로 성장한 클래스는 각 목적마다 하나씩 별도의 영역으로 분할 될 수 있습니다.

  • 문제 영역에 대해 잘못된 라이브러리, 때로는 잘못된 언어를 사용하여 작성된 코드 종종 프로그래머가 문제 영역에 대해 올바른 라이브러리 세트를 사용하지 않으면 코드가 매우 장황하게 보일 것입니다. 실제로는 속하지 않습니다.

  • 학생 또는 최근 졸업생이 작성한 코드. 일부 프로그램과 과정은 학생들에게 모든 종류의 이상한 목적을 위해 지역을 사용하도록 노력하는 것으로 보입니다. 영역 태그 대 코드 행의 비율이 1 : 5 이하인 지점까지 소스 코드를 비산하는 영역이 표시됩니다.


3

나는 그것이 "코드 냄새"라고 말할 것입니다.

안티 패턴은 일반적으로 소프트웨어에서 근본적인 구조적 문제이지만, 영역 자체는 편집기에서 눈에 거슬리는 행동을 유발합니다. 영역을 사용하는 것은 본질적으로 나쁘지는 않지만 특히 코드 덩어리를 숨기기 위해 영역을 많이 사용하면 다른 곳에서 진행되는 다른 독립적이고 큰 문제가 있음을 나타낼 수 있습니다.



3

하나의 영역에만 영역을 사용합니다 (적어도 내가 사용하는 다른 위치는 생각할 수 없습니다). 메서드에 대한 단위 테스트를 그룹화합니다.

나는 보통 클래스 당 하나의 테스트 클래스를 가지고 있고 메소드 이름을 가진 영역을 사용하여 각 메소드에 대한 단위 테스트를 그룹화합니다. 그것이 코드 냄새인지 아닌지 확실하지 않지만 기본 아이디어는 코드의 무언가가 변경되어 깨지기 전에는 단위 테스트를 변경할 필요가 없다는 것이므로 특정 방법에 대한 모든 테스트를 쉽게 찾을 수 있습니다 꽤 빨리.

과거에 지역을 사용하여 코드를 구성했을 수도 있지만 마지막으로 수행 한 시간을 기억할 수 없습니다. 그래도 단위 테스트 수업에서 내 지역을 고수합니다.


1
둘 이상의 방법을 테스트하는 테스트가 있습니까?
Marcie

나는 질문이나 당신이 목표로하는 것을 실제로 이해하지 못합니다. 답은 : 아니요, 단위 테스트는 항상 한 가지 방법 또는 한 가지 방법의 특정 측면을 대상으로합니다.
Anne Schuessler

2

나는 이것이 안티 패턴이라고 생각하고 솔직히 제거해야한다고 생각합니다. 그러나 당신은 그들이 표준 비주얼 스튜디오는 당신이 지역 볼 때마다 구토하고 싶은 양을 최소화 할 수있는 멋진 도구를 제공하고 있습니다 장소에서 작업의 불행한 상황에있는 경우 내가 #Regions 증오를

이 플러그인은 정말 작은 지역의 글꼴 크기를 최대화합니다. 또한 모든 지역을 열기 위해 ctr + m + l을 누르지 않아도됩니다. 이러한 형태의 코드 암을 수정하지는 않지만 견딜 수있게 만듭니다.


0

각 가시성 및 멤버 유형의 각 조합을 포함하기 위해 영역을 사용합니다. 따라서 모든 개인 기능은 지역 등으로 이동합니다.

내가하는 이유는 코드를 접을 수 없기 때문입니다. 프록시에 대한 참조를 삽입 할 수 있도록 편집기를 스크립트로 작성했기 때문입니다.

#region "private_static_members"
 /// <summary>
 /// cache for LauncherProxy
 /// </summary>
private static LauncherProxy _launcherProxy;
#endregion

#region "protected_const_properties"
protected LauncherProxy LauncherProxy{
  get{
    if(_launcherProxy==null) {
      if (!God.Iam.HasProxy(LauncherProxy.NAME)) {
        God.Iam.RegisterProxy(new LauncherProxy());
      }
      _launcherProxy=God.Iam.Proxy(LauncherProxy.NAME) as LauncherProxy;
    }
    return _launcherProxy;
  }
}
#endregion

코드에 삽입하고 각 부분을 적절한 지역에 깔끔하게 넣습니다.

이 경우 매크로는 프로젝트를 분석하고 프록시 목록 상자를 제공하며 원하는 코드를 삽입합니다. 커서가 움직이지 않습니다.

C #을 배우기 시작했을 때 나는 공통성을 유지하기 위해 영역을 사용하는 것을 고려했지만 항상 일대일 관계가 아니기 때문에 그것은 명중입니다. 누가 두 지역에서 사용하는 회원에 대해 걱정하고 싶거나 심지어 그 용어로 일을 시작하기를 원합니다.

다른 유형의 분리는 메소드입니다. 메서드, 함수 및 핸들러로 메소드를 나눌 것이므로 공개, 개인 등의 명령 등을위한 영역이 있습니다.

이것은 나에게 세분성을 제공하지만, 내가 믿을 수있는 일관되고 명백한 세분성입니다.


125 점을 줄이자 마자 -1입니다. 불필요한 코드 줄을 추가하고 있습니다. 왜 왜 속성 주위에 영역을 두겠습니까? if (God.Iam.AbusingRegions () == true) myName = "Mark"
DeadlyChambers

1
@DeadlyChambers 이유는 두 번째 단락에 나와 있습니다. 편집기 매크로를 사용하여 공통 코드 패턴을 파일에 삽입하고 영역은 파일을 구조화하여 유사한 항목이 그룹화되도록합니다. 단일 속성 주위에 영역을 배치하지는 않지만 "protected_const_properties"속성에 따라 모든 속성이 지정된 영역에 속합니다. 게시물을 읽었습니까?
Mark

1
protected LauncherProxy LauncherProxy => God.Iam.GetOrAddProxy <LauncherProxy> (ref _launcherProxy); 따라서 이제 지역이 필요하지 않습니다. 또한 _launcherProxy는 _launcherProxyCache로 이름을 바꿀 수 있으므로 지역이나 주석이 필요하지 않습니다.
aeroson

0

영역은 전 처리기 표현식입니다. 즉, 주석처럼 처리되며 기본적으로 컴파일러에서 무시됩니다. 그들은 순수한 Visual Studio에서 사용되는 시각적 도구입니다. 따라서 #region은 코드가 아니기 때문에 실제로 코드 냄새가 아닙니다. 코드 냄새는 800 라인 방식으로 여러 가지 다른 책임이 포함되어 있습니다. 따라서 한 가지 방법으로 10 개의 영역이 표시되면 코드 냄새를 숨기는 데 사용됩니다. 아주 잘 작성되고 구조화 된 수업에서 수업을보다 즐겁게하고 더 탐색하기 쉽도록 수업을 매우 효과적으로 사용하는 것을 보았습니다!


0

지역은 멋진 조직 아이디어 였지만 모든 개발자를 과도하게 분류하려는 일부 개발자 경향을 고려하지 않았으며 대부분의 최신 OOP 관행에 따르면 일반적으로 불필요합니다. SOLID 원칙의 "S"를 위반할 가능성이 있으므로 클래스 / 방법이 너무 커서 리팩터링되어야합니다. 그러나 어떤 냄새와 마찬가지로 반드시 무언가가 잘못되었다는 의미 는 아닙니다 .

지역은 객체 지향 코드 IMO가 아닌 기능적 코드에서 더 많은 목적을 제공합니다. 여기서 순차적 인 데이터의 긴 기능이 깨지기는 쉽지만 C #에서 개인적으로 사용한 시간이 있었고 거의 항상 볼 필요가없는 코드에 집중하십시오. 나에게 이것은 일반적으로 NPoco 또는 그 변형에 사용되는 코드베이스의 원시 SQL 문자열 상수였습니다. 데이터가 ORM을 통해 POCO 객체를 채우는 방법에 실제로 신경 쓰지 않는 한, 이것들은 완전히 무의미합니다 ... 만약 당신이 돌보면 지역과 BAM을 확장하십시오 ! 시청의 즐거움을위한 150 줄 이상의 복잡한 SQL 쿼리

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