web-dev-qa-db-ja.com

ベストプラクティス:クラス定義内でpublic / protected / privateを順序付けしますか?

私はゼロから新しいプロジェクトを始めており、それがきれいである/良いコーディング標準を持っていることを望んでいます。ここのベテラン開発者は、どの順序でクラス内で物事をレイアウトするのが好きですか?

A:1)パブリックメソッド2)プライベートメソッド3)パブリック変数4)プライベート変数

B:1)パブリック変数2)プライベート変数3)パブリックメソッド4)プライベートメソッド

C:1)パブリック変数2)パブリックメソッド3)プライベートメソッド4)プライベート変数

私は一般的にパブリックの静的変数を一番上に置きたいのですが、コンストラクタの前にパブリックの静的メソッドをリストするか、コンストラクタを常に最初にリストする必要がありますか?そのようなこと...

私はそれがひどいものであることを知っていますが、私はちょうど疑問に思いました:これのベストプラクティスは何ですか?

PS:いいえ、私はCc#を使用しません。私は知っています。私はludditeです。

74
tempname

Clean Code では、ロバートC.マーティンは、常にクラスの先頭に定数(最初に定数、次にプライベートメンバー)を置くようにコーダーに助言し、メソッドは次のように順序付けられるべきである読者がコードを飛び回る必要があまりないストーリー。これは、アクセス修飾子ではなく、コードを整理するためのより賢明な方法です。

116
Asaph

ベストプラクティスは、一貫性を保つです。

個人的には、publicメソッドを最初に配置し、次にprotectedメソッドを配置し、その後にprivateメソッドを配置することを好みます。メンバーdataは、そうでない理由がない限り、一般に常にプライベートまたは保護されている必要があります。

publicメソッドを一番上に置く理由は、クラスのinterfaceを定義しているため、ヘッダーファイルを熟読している人はすぐにこの情報を見ることができるはずです。

一般に、privateおよびprotectedメンバーは、クラスの内部を変更することを検討している場合を除き、ヘッダーファイルを見るほとんどの人にとってそれほど重要ではありません。それらを「邪魔にならないように」保つことで、この情報は、カプセル化のより重要な側面の1つである知る必要があるでのみ維持されます。

45

個人的には、トップに公開し、保護してからプライベートにするのが好きです。この理由は、誰かがヘッダーをクラックすると、最初にアクセスできるものが表示され、次にスクロールダウンすると詳細が表示されるためです。

7
Anders

私はこれに関してほとんどの哲学とは異なる哲学を持っていると思います。関連するアイテムをグループ化することを好みます。クラスで作業するために飛び回る必要はありません。コードはフローする必要があり、アクセシビリティ(パブリック、プライベート、保護など)またはインスタンス対静的またはメンバー対プロパティ対機能に基づいたかなり人為的な順序を使用する必要がありますが、ナイスフローを維持するのに役立ちません。したがって、プライベートヘルパーメソッドMethodHelperMethodAなどによって実装されるパブリックメソッド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;
    }       
}
7
jason

これは私の注文でしょう

  1. 静的変数
  2. 静的メソッド
  3. パブリック変数
  4. 保護された変数
  5. プライベート変数
  6. コンストラクター
  7. パブリックメソッド
  8. 保護されたメソッド
  9. プライベートメソッド

次のルールを使用します。

  • 何よりも先に静的
  • メソッドの前のコンストラクターの前の変数(私はコンストラクターがメソッドのカテゴリーにあると考えます)
  • プライベートの前に保護される前にパブリック

考え方は、動作(メソッド)の前にオブジェクト(データ)を定義することです。静的変数はオブジェクトの一部ではなく、動作でもないため、分離する必要があります。

4
barkmadley

私はよく気にしました。過去数年間、最新のIDEを使用すると、ほとんどすべてが1〜2回のキーストロークで済むため、標準を大幅に緩和できました。今、私は静的変数、メンバー変数、コンストラクターから始め、その後はあまり気にしません。

C#では、Resharperが自動的に物事を整理できるようにします。

3
ScottS

私は一般に、公開データ、保護データ、非公開データ、静的データ、メンバーデータ、メンバー関数の順序に同意します。

メンバー(ゲッターとセッター)のようなメンバーをグループ化することもありますが、通常はグループ内のメンバーをアルファベット順にリストして、より簡単に見つけられるようにします。

また、データ/関数を縦に並べるのも好きです。すべての名前が同じ列に配置されるように、十分に右にタブ/スペースで移動します。

2
AlanKley

それぞれに、そしてElzoが言うように、最新のIDEは、ドロップダウンメニューなどの色付きアイコンを使用して、簡単な方法でメンバーとその修飾子を見つけやすくしました。

私の考えは、プログラマーにとって、クラスが何のために設計され、どのように動作することが期待できるかを知ることがより重要だということです。

したがって、シングルトンの場合は、セマンティクス(静的getInstance()クラス)を最初に配置します。

具体的なファクトリーの場合、getNew()関数とregister/initialize関数を最初に配置します。

... 等々。私が最初に言うとき、私はc'torsとd'torの直後を意味します-それらはクラスをインスタンス化するデフォルトの方法だからです。

その後の機能は次のとおりです。

  1. 論理的な呼び出し順序(例:initialize()、preProcess()、process()、postProcess())、または
  2. 関連機能(アクセサ、ユーティリティ、マニピュレータなど)

クラスが主にいくつかの関数を含むデータストアであるか、いくつかのデータメンバーを含む関数プロバイダーであるかによって異なります。

1
Fox

Eclipseやその子孫などの一部のエディターでは、アウトラインビューで変数とメソッドをアルファベット順またはページ内で並べ替えることができます。

0
Elzo Valugi

パブリックの後に保護されたプライベートのシーケンスが読みやすくなっています。ヘッダーファイルの上部にあるコメントでクラスロジックを簡単に説明し、クラスの用量とアルゴリズムが内部で使用されているものを理解するために関数呼び出しの順序を指定する方が良いでしょう。

私はしばらくQt c ++を使用していますが、signalslotのような新しい種類のキーワードがあります。上記のように注文を続け、ここで私のアイデアを共有してください。

#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
0
saeed