모범 사례 : 클래스 정의 내에서 공용 / 보호 / 개인 순서 지정?


92

나는 처음부터 새로운 프로젝트를 시작하고 있으며 그것이 깨끗하고 좋은 코딩 표준을 갖기를 원합니다. 여기에 노련한 개발자들은 어떤 순서로 수업 내에서 물건을 배치하는 것을 좋아합니까?

A : 1) 공용 메서드 2) 전용 메서드 3) 공용 변수 4) 전용 변수

B : 1) 공용 변수 2) 전용 변수 3) 공용 메서드 4) 전용 메서드

C : 1) 공용 변수 2) 공용 메서드 3) 전용 메서드 4) 전용 변수

일반적으로 공개 정적 변수를 맨 위에 배치하고 싶지만 공개 정적 메서드가 생성자 앞에 나열됩니까, 아니면 생성자가 항상 먼저 나열되어야합니까? 그런거 ...

나는 그것이 까다 롭다는 것을 알고 있지만 궁금해했습니다. 이에 대한 모범 사례는 무엇입니까?

추신 : 아니요 저는 Cc #을 사용하지 않습니다. 알아. 나는 luddite입니다.


9
C #을 사용하지 않아도 문제가 없습니다. 저는 전문 개발자로서 수년간 C #을 작성 해본 적이 없습니다. 작업에 적합한 언어를 사용하고 다른 말을하는 사람에게 어디로 갈 수 있는지 알려주세요!
Ether

답변:


143

에서 클린 코드 로버트 C. 마틴 (다음, 첫 번째 상수 개인 회원) 클래스의 상단에 항상 넣어 멤버 변수에 코더 조언 및 방법은 원인을하지 않는 이야기처럼 읽을 수 있도록 같은 방식으로 주문해야 독자는 코드를 너무 많이 넘겨야합니다. 이것은 액세스 수정 자보다 코드를 구성하는 더 현명한 방법입니다.


10
나는 또한 행운을 빕니다 : 게터 / 세터 마지막. 수업이 덜 부피가 커지지 않도록 도와줍니다.
Dean J

5
멤버 변수 바로 뒤 상단의 생성자. OOP에서 실행은 개체 인스턴스화로 시작됩니다.
Asaph

6
독자가 코드를 너무 많이 뛰어 다니게 만드는 것은 독자가 개인 메서드의 모든 핵심 세부 사항을 읽도록 강요하는 것과 균형을 이루어야 할 것입니다. 신문의 은유는 아마도 당신의 공용 메서드가 당신의 클래스가하는 일을 광범위하게 나타내야하고 당신의 개인 메서드가 세부 사항을 제공해야한다는 점에서 오해 될 것입니다 (필요하다면 참조 할 수있는 각주와 거의 비슷합니다).
Kenny Hung

1
혼란 스럽습니다. 당신은 말했다 : (먼저 상수, 그 다음 개인 멤버) . 확인. 그러면 공개 회원은 어디로 갑니까?
Honey

1
@Honey 그들은 상수와 개인 멤버를 따라 갈 것입니다. 그래서 그것은 상수, 개인 구성원, 공용 구성원의 순서가 될 것입니다.
Pierre Gillet

48

가장 좋은 방법은 일관성을 유지하는 것 입니다.

개인적으로 나는 public방법을 먼저 두는 것을 선호하고 , 그 다음에는 protected방법을 선호 private합니다. 회원 데이터 는 일반적으로 그렇게하지 않을 타당한 이유가없는 한 항상 비공개이거나 보호되어야합니다.

public메서드를 맨 위에 두는 이유는 클래스에 대한 인터페이스 를 정의 하므로 헤더 파일을 읽는 모든 사람이이 정보를 즉시 볼 수 있어야한다는 것입니다.

일반적으로, private그리고 protected회원들은 클래스의 내부를 수정 고려하지 않는, 헤더 파일을보고 대부분의 사람들에게 덜 중요하다. 이러한 정보를 " 간단 하게"유지하면 캡슐화의 더 중요한 측면 중 하나 인 알 필요가 있을 때만이 정보가 유지됩니다 .


LeopardSkikPBH, 전적으로 동의합니다 ... 말이됩니다! 나는 그 안에서 var 또는 funcs가 우선하는지에 대해 혼란스러워했습니다. 감사!
tempname

11
모범 사례가 일관성을 유지하는 데 동의하지 않습니다. 읽을 수없고 유지 관리 할 수없는 코드를 일관되게 작성하는 방법에는 여러 가지가 있습니다.
jason

3
@Jason은 여전히 ​​사고가 발생할 수 있기 때문에 길가에 머무르는 것이 모범 사례가 아니라고 말하는 것과 같습니다.
Rex M

1
@Jason-아마도 내가 더 분명 했어야 했어. 이 특히 상당히 주관적인 경우 (방법의 순서) 일관성을 유지하는 것이 가장 좋은 방법이라고 생각합니다. 모든 사람이 물건을 주문하는 가장 좋은 방법에 대한 의견을 가질 수 있지만, 본질적으로 일관성이 있다면 상당히 유지 관리 할 수 ​​있어야합니다. 저는 "일관성"이 항상 모든 코드 영역에 대한 모범 사례는 아니라는 데 동의합니다. 특히 자주 처리해야하는 낮은 코드 품질을 고려할 때 그렇습니다.
LeopardSkinPillBoxHat

4
@Rex M : 아니요, 제가 말한 것은 당신의 해석과 전혀 다릅니다. 내 요점은이 경우에 단순히 일관성이 있다는 것은 강력한 주장이 아니라는 것입니다. 어떤 경우에는 일관성이 좋습니다 (예 : 중괄호 배치). 그러나 여기서 선택하는 것은 실제로 코드의 가독성에 영향을 미칩니다. 따라서 일관성보다 더 강력한 주장이 필요합니다.
jason

8

나는 이것에 대해 다른 철학을 가지고 있다고 생각합니다. 관련 항목을 함께 그룹화하는 것을 선호합니다. 수업에서 일하기 위해 뛰어 다니는 것을 참을 수 없습니다. 코드는 흐름을 따라야하며 접근성 (공개, 개인, 보호 등)을 기반으로하는 다소 인공적인 순서를 사용하거나 인스턴스 대 정적 또는 멤버 대 속성 대 함수는 좋은 흐름을 유지하는 데 도움이되지 않습니다. 나는 공개 방법 본당 경우에 따라서 Method개인 도우미 메서드에 의해 구현되는 HelperMethodA, HelperMethodB등을 다음보다는 멀리 떨어져 파일의 서로 이러한 방법을 가지고, 나는 서로 가까이를 유지합니다. 마찬가지로 정적 메서드로 구현 된 인스턴스 메서드가있는 경우 이러한 메서드도 함께 그룹화합니다.

그래서 내 수업은 종종 다음과 같이 보입니다.

class MyClass {
    public string Method(int a) {
        return HelperMethodA(a) + HelperMethodB(this.SomeStringMember);
    }

    string HelperMethodA(int a) { // returns some string }

    string HelperMethodB(string s) { // returns some string }

    public bool Equals(MyClass other) { return MyClass.Equals(this, other); }

    public static bool Equals(MyClass left, MyClass right) { // return some bool }

    public double SomeCalculation(double x, double y) {
        if(x < 0) throw new ArgumentOutOfRangeException("x");
        return DoSomeCalculation(x, y); 
    }

    const double aConstant;
    const double anotherConstant;
    double DoSomeCalculation(double x, double y) {
        return Math.Pow(aConstant, x) * Math.Sin(y) 
            + this.SomeDoubleMember * anotherConstant;
    }       
}

8

개인적으로 나는 공개, 보호 및 비공개를 좋아합니다. 그 이유는 누군가가 헤더를 열면 먼저 액세스 할 수있는 항목을 확인한 다음 아래로 스크롤 할 때 자세한 내용을 확인하기 때문입니다.

클래스를 사용하기 위해 클래스의 구현 세부 사항을 볼 필요가 없습니다. 그러면 클래스 디자인이 제대로 수행되지 않습니다.


3

나는 많이 신경 쓰곤했다. 최근 몇 년 동안 최신 IDE를 사용하는 동안 거의 모든 것이 한두 번의 키 입력 만 있으면됩니다. 저는 제 표준을 상당히 완화했습니다. 이제 정적, 멤버 변수, 생성자부터 시작하여 그다지 걱정하지 않습니다.

C #에서는 Resharper가 자동으로 항목을 구성하도록합니다.


나는 동의한다. 파일에서 멤버를 탐색하는 일반적인 모드는 사용중인 IDE 또는 편집기에 내장 된 도구를 사용하는 것입니다. 구성원의 실제 그룹은 2 차가됩니다. 그러나 나는 순수한 무작위 순서를 피하기 위해 구성원을 그룹화해야한다는 데 동의하며 resharper를 사용하여 그룹화 및 순서를 자동으로 수행합니다.
Phillip Ngan

2

이것은 내 주문입니다

  1. 정적 변수
  2. 정적 방법
  3. 공용 변수
  4. 보호 된 변수
  5. 개인 변수
  6. 생성자
  7. 공개 방법
  8. 보호 된 방법
  9. 개인 방법

다음 규칙을 사용합니다.

  • 무엇보다 정적
  • 메서드 전에 생성자 앞의 변수 (생성자가 메서드 범주에 있다고 간주)
  • 비공개 전에 보호하기 전에 공개

아이디어는 동작 (메소드) 전에 객체 (데이터)를 정의하는 것입니다. 정적은 실제로 개체의 일부도 아니고 동작도 아니기 때문에 분리해야합니다.


고마워요 barkmadley ... 재미 있네요! 생성자 앞에 4와 5를 넣습니다. 나는 그것에 대해 확실히 생각할 것입니다
tempname

이 순서처럼 상단 근처에 정적 메서드를 갖는 것이 흥미 롭습니다. 내가 아이디어를 볼 수 있었다 하단에 개인 변수를 넣어 개발자로 일하지만, 느낌이 좋지 않았다
칼튼

2

나는 일반적으로 정적 데이터, 회원 데이터, 회원 기능 명령뿐만 아니라 공개, 보호, 개인 주문에 동의합니다.

나는 때때로 회원 (getters & setter)처럼 그룹화하지만, 일반적으로 그룹 내에서 회원을 더 쉽게 찾을 수 있도록 알파벳순으로 나열하는 것을 선호합니다.

데이터 / 기능을 수직으로 정렬하는 것도 좋아합니다. 모든 이름이 같은 열에 정렬되도록 탭 / 공백을 충분히 오른쪽으로 이동합니다.


1
이봐-내 마음에 '탭-스페이서'! :-) 나는 강박 적이 지 않습니다. 솔직히 아니야!
tempname

1

각자에게 그리고 Elzo가 말했듯이 최신 IDE는 드롭 다운 메뉴 등의 색상 아이콘을 사용하여 멤버와 수정자를 쉽게 찾을 수 있도록했습니다.

내 생각은 프로그래머가 클래스가 무엇을 위해 설계되었는지, 그리고 그것이 어떻게 동작 할 것으로 기대할 수 있는지 아는 것이 더 중요하다는 것입니다.

그래서 싱글 톤이라면 시맨틱 (정적 getInstance () 클래스)을 먼저 넣습니다.

구체적인 팩토리라면 getNew () 함수와 레지스터 / 초기화 함수를 먼저 넣습니다.

... 등등. 내가 처음으로 말할 때, 나는 c'tors와 d' tor 직후를 의미합니다. 왜냐하면 그것들은 모든 클래스를 인스턴스화하는 기본 방법이기 때문입니다.

다음 기능은 다음과 같습니다.

  1. 논리적 호출 순서 (예 : initialize (), preProcess (), process (), postProcess ()) 또는
  2. 관련 기능 (접근 자, 유틸리티, 조작자 등)

클래스가 주로 일부 함수가있는 데이터 저장소인지 아니면 몇 개의 데이터 멤버가있는 함수 공급자인지에 따라 다릅니다.


0

Eclipse 및 그 자손과 같은 일부 편집기를 사용하면 개요보기에서 vars 및 메서드를 알파벳순으로 또는 페이지 에서처럼 재정렬 할 수 있습니다.


0

public의 순서는 protected와 private이 더 읽기 쉽습니다. 헤더 파일 상단의 주석에 클래스 로직을 설명하고 클래스 용량과 내부에서 사용 된 알고리즘을 이해하기 위해 함수 호출 순서를 설명하는 것이 좋습니다.

나는 잠시 동안 Qt는 C ++를 사용하여 같은 키워드의 새로운 종류를 참조하고 signal그리고 slot나는 위와 같이 순서를 유지하고 여기에 당신과 함께 내 생각을 공유하는 것을 선호합니다.

#ifndef TEMPLATE_H
#define TEMPLATE_H


class ClassName
{
    Q_OBJECT
    Q_PROPERTY(qreal startValue READ startValue WRITE setStartValue)
    Q_ENUMS(MyEnum)

public:

    enum MyEnum {
        Hello = 0x0,
        World = 0x1
    };

    // constructors

    explicit ClassName(QObject *parent = Q_NULLPTR);
    ~ClassName();

    // getter and setters of member variables

    // public functions (normal & virtual) -> orderby logic

public slots:

signals:

protected:

    // protected functions it's rule followed like public functions


private slots:

private:

    // methods

    // members

};

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