Praktik terbaik: pengurutan publik / dilindungi / privat dalam definisi kelas?

94

Saya memulai proyek baru dari awal dan ingin proyek itu bersih / memiliki standar pengkodean yang baik. Dalam urutan apa para pengembang berpengalaman di sini suka meletakkan berbagai hal di dalam kelas?

J: 1) metode publik 2) metode pribadi 3) vars publik 4) vars pribadi

B: 1) vars publik 2) vars pribadi 3) metode publik 4) metode pribadi

C: 1) vars publik 2) metode publik 3) metode privat 4) vars privat

Saya biasanya ingin meletakkan public static vars di bagian atas, tetapi kemudian akankah metode statis publik dicantumkan di depan konstruktor Anda, atau haruskah konstruktor selalu dicantumkan terlebih dahulu? Hal semacam itu ...

Saya tahu ini rewel tetapi saya hanya bertanya-tanya: apa praktik terbaik untuk ini?

PS: tidak, saya tidak menggunakan Cc #. Aku tahu. Saya seorang luddite.

tempname
sumber
9
Tidak ada salahnya tidak menggunakan C #. Saya tidak pernah menulis setitik pun C # selama bertahun-tahun sebagai pengembang profesional. Gunakan bahasa apa pun yang sesuai untuk tugas tersebut, dan beri tahu siapa pun yang mengatakan sesuatu yang berbeda di mana mereka dapat melakukannya!
Eter
1
Kemungkinan duplikat stackoverflow.com/questions/150479/…
Michael Freidgeim

Jawaban:

146

Dalam Clean Code , Robert C. Martin menyarankan pembuat kode untuk selalu menempatkan variabel anggota di bagian atas kelas (konstanta terlebih dahulu, kemudian anggota pribadi) dan metode harus diurutkan sedemikian rupa sehingga mereka membaca seperti cerita yang tidak menyebabkan pembaca harus terlalu banyak membaca kode. Ini adalah cara yang lebih masuk akal untuk mengatur kode daripada dengan pengubah akses.

Asaf
sumber
10
Saya beruntung juga menambahkan: getter / setter last. Ini membantu kelas terasa tidak terlalu besar, bagi saya.
Dean J
5
Konstruktor di atas, tepat setelah variabel anggota. Dalam OOP, eksekusi dimulai dengan pembuatan instance objek.
Asaf
6
Membuat pembaca terlalu banyak melompat-lompat kode mungkin perlu diimbangi dengan memaksa pembaca untuk membaca semua detail metode pribadi. Metafora surat kabar mungkin disalahpahami karena metode publik Anda harus mewakili secara luas apa yang dilakukan kelas Anda, dan metode pribadi Anda menyediakan detailnya (hampir seperti catatan kaki yang dapat Anda rujuk jika perlu).
Kenny Hung
1
Saya bingung. Anda berkata: (konstanta dulu, lalu anggota pribadi) . BAIK. Kemana perginya anggota publik?
Madu
1
@ Madu Mereka akan mengejar konstanta dan anggota pribadi. Jadi itu akan menjadi urutan berikut: Konstanta, anggota pribadi, anggota publik.
Pierre Gillet
49

Praktik terbaik adalah konsisten .

Secara pribadi, saya lebih suka menempatkan publicmetode terlebih dahulu, diikuti oleh protectedmetode, diikuti oleh privatemetode. Anggota Data harus secara umum selalu pribadi atau dilindungi, kecuali Anda memiliki alasan yang baik untuk itu tidak begitu.

Alasan saya untuk meletakkan publicmetode di atas adalah bahwa ia mendefinisikan antarmuka untuk kelas Anda, jadi siapa pun yang membaca file header Anda harus dapat melihat informasi ini segera.

Secara umum, privatedan protectedanggota kurang penting bagi kebanyakan orang yang melihat file header, kecuali mereka mempertimbangkan untuk mengubah internal kelas. Menjaga mereka "keluar dari jalan" memastikan informasi ini dipertahankan hanya atas dasar kebutuhan untuk mengetahui , salah satu aspek enkapsulasi yang lebih penting.

LeopardSkinPillBoxHat
sumber
LeopardSkikPBH, saya setuju ... itu masuk akal! Saya rasa saya bingung apakah di dalamnya, var atau funcs lebih diutamakan. Terima kasih!
tempname
12
Saya tidak setuju bahwa praktik terbaik adalah konsisten. Ada banyak cara untuk secara konsisten menulis kode yang tidak dapat dibaca dan tidak dapat dirawat.
jason
3
@Jason itu seperti mengatakan bahwa bukan praktik terbaik untuk tetap berada di sisi jalan Anda karena Anda masih bisa mengalami kecelakaan di sana.
Rex M
1
@ Jason - Mungkin saya seharusnya lebih jelas. Khususnya, kasus yang cukup subyektif (urutan metode) menurut saya praktik terbaik adalah konsisten. Setiap orang akan memiliki pendapat tentang cara terbaik untuk memesan sesuatu, tetapi jika Anda pada dasarnya konsisten, itu harus cukup dapat dipertahankan. Saya setuju bahwa "konsisten" tidak selalu merupakan praktik terbaik untuk semua area kode, terutama bila Anda mempertimbangkan kualitas kode yang buruk yang sering harus Anda tangani.
LeopardSkinPillBoxHat
4
@Rex M: Tidak, apa yang saya katakan tidak sama dengan interpretasi Anda sama sekali. Maksud saya adalah bahwa hanya menjadi konsisten bukanlah argumen yang kuat dalam kasus ini. Untuk beberapa kasus konsistensi baik-baik saja (misalnya, penempatan kawat gigi). Tetapi pilihan di sini sebenarnya memengaruhi keterbacaan kode. Oleh karena itu, dibutuhkan argumen yang lebih kuat dari pada konsistensi.
jason
9

Saya pikir saya memiliki filosofi yang berbeda tentang ini dari kebanyakan. Saya lebih suka mengelompokkan item terkait. Saya tidak tahan harus melompat-lompat untuk bekerja dengan kelas. Kode harus mengalir dan menggunakan urutan yang agak artifisial berdasarkan aksesibilitas (publik, pribadi, dilindungi, dll.) Atau contoh versus statis atau anggota versus properti versus fungsi tidak membantu menjaga alur tetap bagus. Jadi jika saya memiliki metode publik Methodyang diimplementasikan oleh metode pembantu pribadi HelperMethodA, HelperMethodBdll. Maka daripada memiliki metode ini berjauhan satu sama lain dalam file, saya akan menyimpannya dekat satu sama lain. Demikian pula, jika saya memiliki metode contoh yang diimplementasikan dengan metode statis, saya akan mengelompokkan ini juga.

Jadi kelas saya sering terlihat seperti ini:

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;
    }       
}
jason
sumber
9

Secara pribadi saya suka publik di atas, dilindungi, dan kemudian pribadi. Alasan untuk ini adalah ketika seseorang membuka header, dia melihat apa yang dapat dia akses terlebih dahulu, kemudian lebih detail saat dia menggulir ke bawah.

Seseorang tidak harus melihat detail implementasi kelas untuk menggunakannya, maka desain kelas tidak dilakukan dengan baik.

AndersK
sumber
3

Saya dulu sangat peduli. Selama beberapa tahun terakhir menggunakan IDE modern hampir semuanya hanya berjarak 1 atau 2 penekanan tombol, saya telah membiarkan standar saya rileks secara substansial. Sekarang, saya mulai dengan statika, variabel anggota, lalu konstruktor setelah itu saya tidak terlalu mengkhawatirkannya.

Dalam C # saya biarkan Resharper mengatur sesuatu secara otomatis.

ScottS
sumber
Saya setuju. Mode normal saya dalam menavigasi anggota dalam sebuah file adalah dengan menggunakan alat yang dibangun ke dalam IDE atau editor mana pun yang saya gunakan. Pengelompokan anggota yang sebenarnya menjadi sekunder. Namun, saya setuju bahwa anggota harus dikelompokkan untuk menghindari pemesanan acak murni, dan saya menggunakan resharper untuk melakukan pengelompokan dan pemesanan secara otomatis.
Phillip Ngan
2

Ini akan menjadi pesanan saya

  1. Variabel Statis
  2. Metode Statis
  3. Variabel Publik
  4. Variabel yang Dilindungi
  5. Variabel Pribadi
  6. Konstruktor
  7. Metode Umum
  8. Metode yang Dilindungi
  9. Metode Pribadi

Saya menggunakan aturan berikut:

  • statis sebelum apa pun
  • variabel sebelum konstruktor sebelum metode (saya menganggap konstruktor berada dalam kategori metode)
  • publik sebelum dilindungi sebelum pribadi

Idenya adalah Anda mendefinisikan objek (data), sebelum perilaku (metode). Statika perlu dipisahkan karena mereka sebenarnya bukan bagian dari objek, juga bukan perilaku.

barkmadley.dll
sumber
terima kasih barkmadley ... itu menarik! bahwa Anda akan meletakkan 4 dan 5 sebelum konstruktor. Saya pasti akan memikirkannya
tempname
Seperti urutan ini meskipun memiliki metode statis di dekat bagian atas itu menarik. Saya bekerja dengan pengembang yang menempatkan variabel pribadi di bagian bawah, saya dapat melihat idenya tetapi rasanya tidak benar
Carlton
2

Saya biasanya setuju dengan ketertiban umum, dilindungi, pribadi serta data statis, data anggota, urutan fungsi anggota.

Meskipun terkadang saya berkelompok seperti anggota (pengambil & penyetel), saya biasanya lebih suka mencantumkan anggota dalam grup SECARA ALFABETIS sehingga mereka dapat ditemukan dengan lebih mudah.

Saya juga suka menyusun data / fungsi secara vertikal. Saya tab / spasi di sebelah kanan sehingga semua nama disejajarkan dalam kolom yang sama.

AlanKley
sumber
1
Hei - 'tab-spacer' setelah hatiku sendiri! :-) Saya tidak obsesif kompulsif. Jujur saya tidak!
tempname
1

Untuk masing-masing miliknya, dan seperti yang dikatakan Elzo, IDE modern telah mempermudah untuk menemukan anggota dan pengubah mereka dengan cara yang mudah dengan ikon berwarna di menu drop-down dan semacamnya.

Pandangan saya adalah bahwa lebih penting bagi programmer untuk mengetahui untuk apa kelas itu dirancang, dan bagaimana kelas itu diharapkan berperilaku.

Jadi, jika itu adalah Singleton, saya menempatkan semantik (kelas getInstance () statis) terlebih dahulu.

Jika ini adalah pabrik beton, saya meletakkan fungsi getNew () dan fungsi register / inisialisasi terlebih dahulu.

... dan seterusnya. Ketika saya mengatakan pertama, maksud saya segera setelah c'tors dan d'tor - karena mereka adalah cara default untuk membuat instance kelas apa pun.

Fungsi-fungsi selanjutnya ada di:

  1. urutan panggilan logis (misalnya inisialisasi (), preProcess (), proses (), postProcess ()), atau
  2. fungsi terkait bersama (seperti pengakses, utilitas, manipulator, dll.),

bergantung pada apakah kelas tersebut dimaksudkan terutama sebagai penyimpanan data dengan beberapa fungsi, atau penyedia fungsi dengan beberapa anggota data.

Rubah
sumber
0

Beberapa editor, seperti Eclipse dan keturunannya, memungkinkan Anda untuk menyusun ulang dalam tampilan garis besar vars dan metode, menurut abjad atau seperti di halaman.

Elzo Valugi
sumber
0

Urutan publik diikuti oleh dilindungi dan pribadi lebih mudah dibaca oleh saya, Lebih baik menjelaskan logika kelas dalam komentar di atas file header secara sederhana dan perintah panggilan fungsi untuk memahami apa dosis kelas dan algoritma yang digunakan di dalamnya.

Saya menggunakan Qt c ++ untuk sementara dan melihat beberapa jenis kata kunci baru seperti signaldan slotsaya lebih suka tetap memesan seperti di atas dan membagikan ide saya dengan Anda di sini.

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