Apakah #regions adalah antipattern atau kode bau?

267

C # memungkinkan penggunaan #region/ #endregionkata kunci untuk membuat area kode dilipat di editor. Setiap kali saya melakukan ini, meskipun saya melakukannya untuk menyembunyikan potongan besar kode yang mungkin bisa di refactored ke kelas atau metode lain. Sebagai contoh saya telah melihat metode yang berisi 500 baris kode dengan 3 atau 4 wilayah hanya untuk membuatnya dapat dikelola.

Jadi, apakah penggunaan wilayah secara bijaksana merupakan tanda masalah? Sepertinya begitu bagi saya.

Craig
sumber
9
FYI: CodeMap cukup banyak menghilangkan kebutuhan untuk daerah. visualstudiogallery.msdn.microsoft.com/... - Klik dan itu akan membawa Anda ke metode / atribut / apa pun. Saya menggunakannya setiap hari dan sungguh menakjubkan betapa banyak yang Anda peroleh dalam produktivitas dan dalam hal kognitif juga. Anda mendapatkan 'pandangan mata' burung yang jauh lebih jelas dari kelas.
7
Adakah yang bisa membuat ini sebagai wiki? Tidak ada jawaban benar atau salah untuk pertanyaan ini (well, masuk akal), itu hampir sepenuhnya subjektif.
Ed S.
6
Untuk apa nilainya, Jeff Atwood membenci mereka . Dia berpendapat bahwa mereka menyembunyikan kode buruk.
Brian
3
Kode bau adalah pengembang yang tidak mandi dan tidak menggunakan deodoran!
marko
5
Daerah yang dibuat dengan hati-hati dalam kode bau adalah apa yang dilakukan oleh beberapa pemerasan Febreeze di sofa berkerak. Itu membuatnya tertahankan sampai Anda menemukan (waktu) uang untuk menggantinya.
Newtopian

Jawaban:

285

Bau kode adalah gejala yang menunjukkan bahwa ada masalah dalam desain yang berpotensi meningkatkan jumlah bug: ini bukan kasus untuk daerah, tetapi daerah dapat berkontribusi menciptakan bau kode, seperti metode panjang.

Sejak:

Anti-pola (atau antipattern) adalah pola yang digunakan dalam operasi sosial atau bisnis atau rekayasa perangkat lunak yang mungkin umum digunakan tetapi tidak efektif dan / atau kontraproduktif dalam praktiknya

daerah adalah anti-pola. Mereka membutuhkan lebih banyak pekerjaan yang tidak meningkatkan kualitas atau keterbacaan kode, yang tidak mengurangi jumlah bug, dan yang hanya dapat membuat kode lebih rumit untuk diperbaiki.

Jangan gunakan daerah di dalam metode; refactor sebagai gantinya

Metode harus pendek . Jika hanya ada sepuluh baris dalam suatu metode, Anda mungkin tidak akan menggunakan daerah untuk menyembunyikan lima di antaranya saat mengerjakan lima lainnya.

Juga, setiap metode harus melakukan satu dan satu-satunya hal . Daerah, di sisi lain, dimaksudkan untuk memisahkan hal-hal yang berbeda . Jika metode Anda menggunakan A, maka B, masuk akal untuk membuat dua wilayah, tetapi ini adalah pendekatan yang salah; alih-alih, Anda harus mengubah metode menjadi dua metode terpisah.

Menggunakan wilayah dalam kasus ini juga dapat membuat refactoring lebih sulit. Bayangkan Anda memiliki:

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
}

Meruntuhkan wilayah pertama untuk berkonsentrasi pada yang kedua tidak hanya berisiko: kita dapat dengan mudah melupakan pengecualian menghentikan aliran (mungkin ada klausa penjaga dengan returnsebaliknya, yang bahkan lebih sulit dikenali), tetapi juga akan memiliki masalah jika kode harus di refactored dengan cara ini:

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
}

Sekarang, wilayah tidak masuk akal, dan Anda tidak mungkin membaca dan memahami kode di wilayah kedua tanpa melihat kode di yang pertama.

Kasus lain yang kadang saya lihat adalah yang ini:

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
}

Sangat menggoda untuk menggunakan kawasan saat validasi argumen mulai menjangkau puluhan LOC, tetapi ada cara yang lebih baik untuk menyelesaikan masalah ini: yang digunakan oleh kode sumber .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)
{
    ...
}

Jangan gunakan wilayah di luar metode untuk mengelompokkan

  • Beberapa orang menggunakannya untuk mengelompokkan bidang, properti, dll. Pendekatan ini salah: jika kode Anda sesuai dengan StyleCop, maka bidang, properti, metode pribadi, konstruktor, dll. Sudah dikelompokkan bersama dan mudah ditemukan. Jika tidak, maka saatnya untuk mulai berpikir tentang menerapkan aturan yang memastikan keseragaman di seluruh basis kode Anda.

  • Orang lain menggunakan daerah untuk menyembunyikan banyak entitas serupa . Misalnya, ketika Anda memiliki kelas dengan ratusan bidang (yang membuat setidaknya 500 baris kode jika Anda menghitung komentar dan spasi putih), Anda mungkin tergoda untuk meletakkan bidang-bidang itu di dalam suatu wilayah, menciutkannya, dan melupakannya. Sekali lagi, Anda salah melakukannya: dengan begitu banyak bidang dalam suatu kelas, Anda harus berpikir lebih baik tentang menggunakan warisan atau mengiris objek menjadi beberapa objek.

  • Akhirnya, beberapa orang tergoda untuk menggunakan daerah untuk mengelompokkan hal-hal terkait : peristiwa dengan delegasinya, atau metode yang berkaitan dengan IO dengan metode lain yang terkait dengan IO, dll. Dalam kasus pertama, itu menjadi berantakan yang sulit untuk dipertahankan , baca dan pahami. Dalam kasus kedua, desain yang lebih baik mungkin untuk membuat beberapa kelas.

Apakah ada gunanya untuk daerah?

Tidak. Ada warisan yang digunakan: kode yang dihasilkan. Namun, alat pembuat kode hanya harus menggunakan kelas parsial saja. Jika C # memiliki dukungan wilayah, itu sebagian besar karena warisan ini digunakan, dan karena sekarang terlalu banyak orang menggunakan wilayah dalam kode mereka, tidak mungkin untuk menghapusnya tanpa merusak basis kode yang ada.

Pikirkan tentang itu goto. Fakta bahwa bahasa atau IDE mendukung fitur tidak berarti bahwa itu harus digunakan setiap hari. Aturan StyleCop SA1124 jelas: Anda tidak boleh menggunakan wilayah. Tidak pernah.

Contohnya

Saat ini saya sedang melakukan review kode dari kode rekan kerja saya. Basis kode berisi banyak daerah, dan sebenarnya adalah contoh sempurna dari kedua cara untuk tidak menggunakan daerah dan mengapa daerah menyebabkan kode buruk. Berikut ini beberapa contohnya:

4 000 monster LOC:

Saya baru-baru ini membaca di suatu tempat di Programmers.SE bahwa ketika sebuah file mengandung terlalu banyak using(setelah menjalankan perintah "Hapus Penggunaan yang Tidak Digunakan"), itu adalah pertanda baik bahwa kelas di dalam file ini melakukan terlalu banyak. Hal yang sama berlaku untuk ukuran file itu sendiri.

Saat meninjau kode, saya menemukan 4 000 file LOC. Tampaknya penulis kode ini hanya menyalin-menyisipkan metode 15-baris yang sama ratusan kali, sedikit mengubah nama variabel dan metode yang disebut. Regex sederhana diizinkan untuk memangkas file dari 4.000 LOC menjadi 500 LOC, hanya dengan menambahkan beberapa obat generik; Saya cukup yakin bahwa dengan refactoring yang lebih pintar, kelas ini dapat dikurangi menjadi beberapa lusin baris.

Dengan menggunakan daerah, penulis mendorong dirinya untuk mengabaikan fakta bahwa kode tersebut tidak mungkin untuk dipertahankan dan ditulis dengan buruk, dan sangat menduplikasi kode alih-alih memperbaikinya.

Wilayah "Do A", Wilayah "Do B":

Contoh lain yang sangat baik adalah metode inisialisasi monster yang hanya melakukan tugas 1, lalu tugas 2, lalu tugas 3, dll. Ada lima atau enam tugas yang benar-benar independen, masing-masing menginisialisasi sesuatu dalam kelas wadah. Semua tugas itu dikelompokkan menjadi satu metode, dan dikelompokkan ke daerah.

Ini memiliki satu keuntungan:

  • Metode ini cukup jelas untuk dipahami dengan melihat nama-nama wilayah. Ini dikatakan, metode yang sama sekali refactored akan sejelas yang asli.

Masalahnya, di sisi lain, beragam:

  • Tidak jelas apakah ada ketergantungan antar daerah. Mudah-mudahan, tidak ada penggunaan kembali variabel; jika tidak, pemeliharaan bisa menjadi mimpi buruk bahkan lebih.

  • Metode itu hampir tidak mungkin untuk diuji. Bagaimana Anda dengan mudah tahu jika metode yang melakukan dua puluh hal sekaligus melakukannya dengan benar?

Wilayah bidang, wilayah properti, wilayah konstruktor:

Kode yang ditinjau juga berisi banyak wilayah yang mengelompokkan semua bidang bersama-sama, semua properti bersama, dll. Ini memiliki masalah yang jelas: pertumbuhan kode sumber.

Saat Anda membuka file dan melihat daftar besar bidang, Anda lebih cenderung untuk refactor kelas terlebih dahulu, kemudian bekerja dengan kode. Dengan daerah, Anda memiliki kebiasaan untuk menghancurkan barang-barang dan melupakannya.

Masalah lain adalah bahwa jika Anda melakukannya di mana-mana, Anda akan menemukan diri Anda membuat satu blok wilayah, yang tidak masuk akal. Ini sebenarnya kasus dalam kode yang saya ulas, di mana ada banyak #region Constructorberisi satu konstruktor.

Akhirnya, bidang, properti, konstruktor, dll. Harus sudah berurutan . Jika ya dan cocok dengan konvensi (konstanta dimulai dengan huruf kapital, dll.), Sudah jelas di mana pada jenis elemen berhenti dan lainnya dimulai, jadi Anda tidak perlu secara eksplisit membuat daerah untuk itu.

Arseni Mourzenko
sumber
13
Saya pikir setidaknya ada beberapa penggunaan #regions yang dapat dipertahankan - mis. Runtuhnya klausa penjaga (memeriksa parameter input) yang, jika dibiarkan tidak runtuh, mengurangi inti atau "daging" dari metode ini. Contoh lain adalah penanganan pengecualian pada batas API; Anda sering tidak ingin memengaruhi jejak stack dengan memanggil metode lain untuk membungkus pengecualian, sehingga Anda memiliki beberapa baris kode untuk dibungkus dan diretoh kembali. Ini juga sering merupakan kode yang tidak relevan, dan dapat dengan aman diciutkan.
Daniel B
9
Pengecekan kenyataan. Saya telah melihat banyak wilayah antar-metode yang sangat membantu. Ketika Anda punya beberapa ratus metode garis dengan logika kontrol bersarang dengan puluhan hingga ratusan baris dengan beberapa dari mereka - syukurlah si idiot setidaknya meletakkan di daerah.
radarbob
37
@radarbob: singkatnya, daerah sangat membantu dalam kode jelek yang seharusnya tidak ada.
Arseni Mourzenko
41
-1 (jika saya memiliki reputasi). Bahkan jika anggota tipe Anda terorganisasi dengan baik dan terpisah, mungkin ada banyak dari mereka. Wilayah menghemat Anda harus menggulir melewati 10 atau 12 properti dan getter dan setters terkait hanya untuk mendapatkan metode yang ingin Anda kerjakan. Satu-satunya alternatif adalah meruntuhkan semua properti Anda secara individu, yang bukan sesuatu yang saya sukai. Wilayah fungsionalitas tunjukkan / sembunyikan skala besar sangat berguna. Saya setuju tentang daerah intra-metode.
Asad Saeeduddin
14
I Sangat tidak setuju dengan jawaban ini: Kode bau dan wilayah tidak ada hubungannya dengan satu sama lain. Jika kode Anda bau, itu akan busuk dengan atau tanpa daerah. Cara saya menggunakan region adalah dengan memecah kelas saya menjadi region. Secara umum saya tetap berpegang pada pola yang sama: Properti Publik, Metode Publik, Bidang Pribadi, Metode Pribadi. Itulah satu-satunya penggunaan yang saya inginkan untuk daerah. Ada lagi, Anda mungkin melanggar prinsip SRP dalam kode Anda.
Alexus
113

Sungguh luar biasa bagi saya betapa banyak orang membenci daerah dengan penuh semangat!

Saya setuju sepenuhnya dengan begitu banyak keberatan mereka: Mendorong kode ke dalam #regionuntuk menyembunyikannya dari pandangan adalah hal yang buruk. Membagi satu kelas menjadi kelas #regionsmana yang harus di refactored menjadi kelas yang terpisah jelas merupakan kesalahan. Menggunakan #regionuntuk menanamkan informasi semantik yang berlebihan, yah, berlebihan.

Tetapi tidak satu pun dari hal-hal itu berarti bahwa ada sesuatu yang salah dengan menggunakan wilayah dalam kode Anda! Saya hanya dapat berasumsi bahwa sebagian besar keberatan orang berasal dari bekerja di tim di mana orang lain cenderung menggunakan fitur IDE seperti ini secara tidak benar. Saya memiliki kemewahan bekerja primer sendiri, dan saya menghargai cara daerah telah membantu mengatur alur kerja saya. Mungkin ini gangguan obsesif kompulsif saya, tetapi saya tidak suka melihat banyak kode di layar saya sekaligus, tidak peduli seberapa rapi dan elegan tulisan itu. Memisahkan hal-hal menjadi wilayah logis memungkinkan saya untuk menutup kode yang saya tidak peduli untuk mengerjakan kode yang saya lakukanpeduli tentang. Saya tidak mengabaikan kode yang ditulis dengan buruk, tidak masuk akal untuk memperbaikinya lebih dari itu, dan organisasi "meta" tambahan bersifat deskriptif, bukannya sia-sia.

Sekarang saya telah menghabiskan lebih banyak waktu bekerja di C ++, memprogram lebih langsung ke Windows API, saya mendapati diri saya berharap bahwa dukungan untuk wilayah sama baiknya dengan C #. Anda bisa berargumen bahwa menggunakan pustaka GUI alternatif akan membuat kode saya lebih sederhana atau lebih jelas, sehingga menghilangkan kebutuhan untuk mengeluarkan suara kode yang tidak relevan dari layar, tapi saya punya alasan lain untuk tidak ingin melakukan itu. Saya cukup mahir dengan keyboard dan IDE saya yang memperluas / menciutkan kode yang dibagi menjadi beberapa daerah membutuhkan waktu kurang dari sepersekian detik. Waktu yang saya hemat dalam kekuatan otak, mencoba membatasi fokus sadar saya hanya pada kode yang sedang saya kerjakan, lebih dari sepadan. Itu semua milik dalam satu kelas / file, tetapi tidak semua milik di layar saya pada saat yang sama.

Intinya adalah bahwa menggunakan #regionsuntuk memisahkan dan secara logis membagi kode Anda bukanlah hal yang buruk untuk dihindari. Seperti yang ditunjukkan Ed, ini bukan "bau kode". Jika kode Anda berbau, Anda dapat yakin bahwa itu bukan berasal dari daerah, melainkan dari kode apa pun yang Anda coba kubur di wilayah itu. Jika sebuah fitur membantu Anda menjadi lebih teratur, atau menulis kode yang lebih baik, maka saya katakan menggunakannya . Jika itu menjadi penghalang, atau Anda mendapati diri Anda menggunakannya secara salah, maka berhentilah menggunakannya. Jika yang terburuk menjadi yang terburuk, dan Anda dipaksa untuk bekerja di tim dengan orang-orang yang menggunakannya, maka hafal pintasan keyboard untuk mematikan kode yang menjabarkan: Ctrl+ M, Ctrl+P. Dan berhenti mengeluh. Kadang-kadang saya merasa ini adalah cara lain yang ingin dilihat oleh programmer yang "benar", "keras" untuk mencoba dan membuktikan diri. Anda tidak lebih baik menghindari daerah daripada menghindari pewarnaan sintaksis. Itu tidak membuat Anda menjadi pengembang yang lebih macho.

Semua itu dikatakan, daerah dalam suatu metode hanyalah omong kosong belaka. Setiap kali Anda mendapati diri Anda ingin melakukan itu, Anda harus melakukan refactoring ke dalam metode terpisah. Tidak ada alasan.

Cody Grey
sumber
9
Kata baik. Penggunaan kawasan untuk organisasi tidak lebih berbahaya daripada mengaktifkan opsi "view whitespace" IDE. Ini adalah pilihan pribadi.
Josh
24
Bekerja pada WPF dengan ViewModels yang memiliki 10 atau 20 properti yang hanya membungkus properti pada model saya, saya suka daerah - Saya hanya bisa menyelipkan properti-properti itu di suatu daerah (mereka tidak perlu disentuh) dan tetap memperhatikan kode yang relevan .
Kirk Broadhurst
4
Setuju. Dalam. NET 2.0, properti sekitar 8-10 baris. Ketika Anda memiliki lebih dari 20 properti di kelas, mereka membutuhkan banyak ruang. Daerah sempurna untuk menciutkannya.
Kristof Claes
6
@ Kristof: Seperti properti di .NET 4.0 yang melakukan validasi input sederhana. Properti otomatis memang belum begitu ajaib untuk tujuan saya.
Cody Gray
8
Saya bersedia bertaruh pada bola kiri saya bahwa orang-orang yang membenci daerah tidak pernah mengembangkan aplikasi WPF, atau tidak pernah benar-benar menggunakan fungsionalitas pendefinisian WPF seperti pengikatan data dan pengikatan perintah. Hanya mengatur kode Anda untuk membuat pekerjaan itu memakan banyak ruang dan Anda biasanya tidak perlu melihatnya lagi.
l46kok
70

Pertama, saya tidak tahan dengan istilah "bau kode" lagi. Ini digunakan terlalu sering dan sering kali dilemparkan oleh orang-orang yang tidak bisa mengenali kode yang baik jika itu menggigit mereka. Bagaimanapun ...

Saya pribadi tidak suka menggunakan banyak daerah. Itu membuatnya lebih sulit untuk mendapatkan kode, dan kode itulah yang saya tertarik. Saya suka daerah ketika saya memiliki sejumlah besar kode yang tidak perlu disentuh terlalu sering. Selain itu, mereka sepertinya menghalangi saya, dan daerah seperti "Metode Pribadi", "Metode Publik", dll. Hanya membuat saya gila. Mereka mirip dengan komentar varietas i++ //increment i.

Saya juga akan menambahkan bahwa penggunaan wilayah tidak bisa benar-benar menjadi "anti-pola" karena istilah itu biasanya digunakan untuk menggambarkan logika program / pola desain, bukan tata letak editor teks. Ini subjektif; gunakan apa yang cocok untuk Anda. Anda tidak akan pernah berakhir dengan program yang tidak dapat dipelihara karena terlalu sering menggunakan daerah, yang merupakan inti dari anti-pola. :)

Ed S.
sumber
2
Biasanya saya akan downvote Anda untuk komentar kode bau tetapi dalam hal ini persis akurat. Non-kode tidak bisa berupa bau kode. +2!
7
Haha, yah, saya tidak bermaksud mengatakan bahwa istilah "bau kode" tidak dapat digunakan secara akurat. Itu bisa, tetapi saya melihatnya terlempar begitu banyak hari ini sehingga reaksi langsung saya hanya jengkel, terutama ketika itu datang dari orang-orang yang benar-benar hanya mengulangi apa yang mereka dengar tanpa memahaminya atau berpikir kritis. Pernyataan seperti "lebih dari 5 variabel lokal dalam suatu fungsi adalah bau kode" hanya menunjukkan betapa sedikitnya pengalaman yang dimiliki orang tersebut.
Ed S.
13
Tidak yakin saya mengerti komentar Anda tentang bau kode. Kode bau tidak menunjukkan ada masalah, hanya saja mungkin ada masalah.
Craig
7
+1 untuk berdiri hingga bau kode istilah. Saya muak ketika melihat sebuah pos mengklaim metode pribadi adalah bau kode. Tapi secara keseluruhan saya tidak setuju dengan ketidaksukaan Anda terhadap daerah. Saya mudah terganggu. Sebenarnya saya akan senang jika VS memiliki mode VB4 di mana Anda dapat menampilkan hanya satu metode sekaligus.
Josh
7
Hanya ingin berpadu dan mengatakan bahwa penyalahgunaan metafora yang sangat baik tidak boleh merendahkan metafora. "Code bau" adalah metafora yang hebat, yang langsung dipahami, mudah diingat, dan mudah digunakan. Masih ada banyak tempat di mana menerapkan metafora "kode bau" masih merupakan cara terbaik untuk mendapatkan titik.
Eric King
23

Ya wilayah adalah bau kode!

Saya akan senang melihat daerah dihapus dari kompiler sama sekali. Setiap pengembang datang dengan skema perawatan tidak berguna sendiri yang tidak akan pernah bernilai bagi programmer lain. Saya ada hubungannya dengan programmer yang ingin mendekorasi dan mempercantik bayi mereka, tidak ada hubungannya dengan nilai nyata.

Bisakah Anda memikirkan satu contoh di mana Anda berpikir, "Ya ampun, saya berharap kolega saya menggunakan beberapa daerah di sini!"

Meskipun saya dapat mengkonfigurasi IDE saya untuk secara otomatis memperluas semua wilayah mereka masih eye-sore dan mengurangi membaca kode yang sebenarnya.

Saya benar-benar tidak peduli jika semua metode publik saya dikelompokkan bersama atau tidak. Selamat Anda tahu perbedaan antara deklarasi variabel dan inisialisasi, tidak perlu menampilkannya dalam kode!

Perawatan berharga!

Selain itu jika file Anda perlu dan 'arsitektur informasi' melalui penggunaan wilayah Anda mungkin ingin memerangi masalah inti: Kelas Anda terlalu besar! Memecahnya menjadi bagian-bagian yang lebih kecil jauh lebih bermanfaat dan, jika dilakukan dengan benar, menambah semantik / keterbacaan yang sebenarnya.

Joppe
sumber
Apakah #regions bagian dari kompiler? Saya pikir mereka hanya arahan ke IDE yang bisa diabaikan.
Steve Rukuts
2
Kompiler harus mengabaikannya saat menguraikan kode C # Anda. Jika tidak mengabaikan mereka itu akan muntah pada mereka. Maksud saya seperti itu.
Joppe
1
"Bisakah Anda memikirkan satu contoh di mana Anda berpikir" Ya ampun, saya berharap kolega saya telah menggunakan beberapa daerah di sini! "?" Ya, sangat banyak. Ketika saya memiliki kelas dengan metode pribadi dan metode publik, saya memecahnya di daerah karena ketika refactoring metode publik, Anda tidak perlu menyentuh kode pribadi dan sebaliknya.
Anshul
Anda jelas tidak pernah melihat kode outsourcing. Sooo berkali-kali daerah akan sangat bagus untuk melihat dalam kode outsourcing. Walaupun kodenya payah, setidaknya akan jauh lebih mudah untuk dipahami jika dikelompokkan bersama dalam beberapa pengertian logis. Meskipun, jika kode mereka tidak logis kemungkinan wilayah tidak akan baik, jadi mungkin akan memperburuknya. Daerah bagus jika digunakan dengan benar.
Nickmccomb
15

Saya pribadi menggunakan kawasan sebagai cara untuk mengelompokkan berbagai jenis metode atau bagian kode bersama-sama.

Jadi file kode mungkin terlihat seperti ini saat membukanya:

  • Properti Publik
  • Konstruktor
  • Simpan Metode
  • Edit Metode
  • Metode Pembantu Pribadi

Saya tidak menempatkan daerah dalam metode. IMHO itu adalah tanda bau kode. Saya pernah menemukan metode yang panjangnya lebih dari 1200 baris dan memiliki 5 wilayah berbeda di dalamnya. Itu adalah pemandangan yang menakutkan!

Jika Anda menggunakannya sebagai cara untuk mengatur kode Anda dengan cara yang akan membuat menemukan hal-hal lebih cepat untuk pengembang lain, saya tidak berpikir itu pertanda masalah. Jika Anda menggunakannya untuk menyembunyikan baris kode di dalam metode, saya akan mengatakan sudah waktunya untuk memikirkan kembali metode itu.

Tyanna
sumber
14
Ugh. Saya tahu ini adalah topik yang subjektif, tetapi saya benar-benar tidak tahan dengan skema ini. Dalam pengalaman saya, 'organisasi' yang ditambahkan tidak membantu sama sekali dan itu hanya membuat browsing kode terasa sakit di leher. Saya juga lebih suka metode pengelompokan tidak hanya oleh pengubah akses tetapi oleh tanggung jawab logis. Untuk antarmuka publik, saya biasanya mengelompokkan setiap metode / properti bersama-sama, tetapi sering kali metode yang dilindungi dapat memanggil fungsi pembantu pribadi, dan dalam hal ini saya lebih suka fungsi pembantu (yang hanya dapat digunakan di sana) berada di atas atau di bawah metode yang menyebutnya.
Ed S.
3
@ Id S. - itu sebabnya saya berkata "mungkin terlihat seperti". Ini sangat subyektif. Saya tidak mengatakan bahwa setiap file akan terlihat seperti itu. Saya akan terkejut jika mereka melakukannya. Hanya sebuah contoh tentang topik yang kompleks. :)
Tyanna
Oh saya tahu, seperti yang saya katakan; itu subyektif. Apa pun yang bekerja untuk Anda / tim Anda. Saya hanya mengeluarkannya untuk skema ini karena tidak berhasil (untuk saya), tetapi saya harus mempertahankan proyek yang melakukan hal ini. Itu membuatku gila.
Ed S.
3
@EdS. Jadi buka opsi Anda di vs. dan matikan daerah. Masalah terpecahkan.
Andy
Mengapa objek Anda memiliki metode penyimpanan? :(
TheCatWhisperer
10

Menggunakan #regionblok untuk membuat kelas yang sangat besar dapat dibaca biasanya merupakan tanda melanggar Prinsip Tanggung Jawab Tunggal. Jika mereka terbiasa dengan perilaku kelompok, maka kemungkinan kelasnya melakukan terlalu banyak (sekali lagi melanggar SRP).

Berpegang pada garis pemikiran "bau kode", #regionbalok bukanlah bau kode dalam dan dari diri mereka sendiri, tetapi sebaliknya mereka lebih "Febreze for code" karena mereka berusaha menyembunyikan bau. Sementara saya telah menggunakan mereka satu ton di masa lalu, ketika Anda mulai refactoring Anda mulai melihat lebih sedikit karena mereka akhirnya tidak banyak bersembunyi.

Austin Salonen
sumber
5

Kata kuncinya di sini adalah "bijaksana". Sulit membayangkan kasus di mana menempatkan suatu wilayah di dalam suatu metode adalah bijaksana; itu terlalu mungkin menyembunyikan kode dan kemalasan. Namun, mungkin ada alasan bagus untuk memiliki beberapa wilayah di sana-sini dalam kode seseorang.

Jika ada banyak dan banyak daerah, saya pikir itu adalah bau kode. Daerah sering merupakan petunjuk di tempat yang memungkinkan untuk refactoring di masa depan. Banyak daerah berarti seseorang tidak benar-benar pernah mengambil petunjuk itu.

Digunakan secara bijaksana, mereka memberikan jalan tengah yang baik antara struktur kelas tunggal dengan banyak metode dan struktur banyak kelas dengan hanya beberapa metode di masing-masing. Mereka paling berguna ketika kelas mulai mendekati ke titik di mana ia harus dire-refour menjadi beberapa kelas, tetapi belum ada di sana. Dengan mengelompokkan metode terkait bersama, saya membuatnya mudah nanti untuk mengekstrak seperangkat metode terkait ke dalam kelas mereka sendiri jika mereka terus bertambah jumlahnya. Misalnya, jika saya memiliki kelas yang mendekati 500 baris kode, kumpulan metode yang menggunakan 200 baris total kode yang dikumpulkan bersama di suatu wilayah mungkin merupakan bagian yang bagus untuk direformasi entah bagaimana - dan wilayah lain dengan 100 baris kode di dalamnya metode mungkin juga menjadi target yang baik.

Cara lain yang saya suka gunakan daerah adalah untuk mengurangi salah satu efek negatif dari refactoring metode besar: Banyak metode kecil, singkat, mudah digunakan kembali bahwa pembaca harus menggulir melalui untuk sampai ke metode lain yang sebagian besar tidak terkait. Suatu wilayah dapat menjadi cara yang bagus untuk meta-encapsulate suatu metode dan bantuannya bagi pembaca, sehingga seseorang yang bekerja dengan aspek kelas yang berbeda dapat dengan mudah meruntuhkannya dan dengan cepat mengabaikan bagian kode tersebut. Tentu saja, ini hanya berfungsi jika wilayah Anda benar-benar terorganisasi dengan baik dan pada dasarnya digunakan sebagai cara lain untuk mendokumentasikan kode Anda.

Secara umum, saya menemukan daerah membantu saya mengatur diri saya, membantu "mendokumentasikan" kode saya, dan membantu saya menangkap tempat untuk memperbaiki lebih cepat daripada jika saya tidak menggunakan daerah.

Ethel Evans
sumber
4

Saya terutama menggunakan daerah untuk kelas server CRUD untuk mengatur berbagai jenis operasi. Bahkan saat itu, saya dengan senang hati bisa pergi tanpa mereka.

Jika digunakan secara luas, itu akan menaikkan bendera merah. Saya akan mencari kelas yang memiliki tanggung jawab terlalu banyak.

Dalam pengalaman saya, metode dengan ratusan baris kode jelas merupakan bau.

TaylorOtwell
sumber
4

Aturan praktis saya adalah: Jika Anda memiliki lebih dari 5 wilayah dalam sebuah file, itu adalah bau kode

Yaitu, mungkin baik untuk menggambarkan bidang, metode, properti dan konstruktor, tetapi jika Anda mulai membungkus setiap metode lain di wilayah itu sendiri ada sesuatu yang sangat salah

..dan ya, saya sudah banyak proyek di mana itu terjadi, sering karena standar pengkodean yang buruk, pembuatan kode atau keduanya. Sudah lama cepat harus beralih semua garis besar di studio visual untuk mendapatkan gambaran yang baik dari kode.

Homde
sumber
4

DAERAH MEMILIKI PENGGUNAANNYA

Saya telah menggunakannya secara pribadi untuk acara antarmuka "coding tangan" sebelum untuk windows membentuk aplikasi.

Namun pada pekerjaan saya, kami menggunakan generator kode untuk menangani SQL dan secara otomatis menggunakan wilayah untuk memilah jenis metode pilih, perbarui, hapus, dll.

Jadi sementara saya tidak sering menggunakannya, mereka baik-baik saja untuk menghapus potongan kode besar.

Ken
sumber
1
Saya telah menggunakan generator kode yang serupa dan lebih suka menggunakan kelas parsial untuk menghapus kode yang dihasilkan.
Craig
Kami melakukannya, daerah di dalam kode yang dihasilkan untuk membuatnya lebih mudah untuk membaca atau men-debug (jika perlu).
Ken
4

Jika Anda memiliki kode IN wilayah Anda tentu memiliki masalah (kecuali kasus kode yang dihasilkan.) Menempatkan region dalam kode pada dasarnya mengatakan "refactor this."

Namun, ada beberapa kasus lain. Salah satu yang terlintas dalam benak saya adalah beberapa waktu yang lalu: Meja dengan beberapa ribu item yang sudah dihitung sebelumnya. Ini adalah deskripsi geometri, singkat dari kesalahan dalam tabel tidak akan pernah ada kesempatan untuk melihatnya. Tentu, saya bisa mendapatkan data dari sumber daya atau sejenisnya tetapi itu akan menghalangi menggunakan kompiler untuk membantu membuatnya mudah dibaca.

Loren Pechtel
sumber
1
Itu kasus penggunaan yang lebih baik untuk kelas parsial dengan yang disimpan dalam file terpisah, atau mungkin IMyDataSource disuntikkan dengan implementasi HardcodedDataSource.
Bryan Boettcher
3

Pada proyek baru-baru ini, ada metode garis 1700 dengan beberapa daerah tertanam di dalamnya. Yang menarik adalah bahwa daerah-daerah membatasi tindakan yang berbeda yang dilakukan dalam metode tersebut. Saya dapat melakukan refactor -> ekstrak metode pada masing-masing daerah tanpa memengaruhi fungsionalitas kode.

Secara umum, daerah yang digunakan untuk menyembunyikan kode pelat ketel berguna. Saya akan menyarankan agar tidak menggunakan daerah untuk menyembunyikan properti, bidang, dan sejenisnya karena jika mereka terlalu sulit untuk dilihat saat bekerja di dalam kelas, itu mungkin merupakan tanda bahwa kelas harus lebih lanjut dipecah. Tetapi sebagai aturan keras, jika Anda menempatkan suatu wilayah dalam suatu metode, Anda mungkin lebih baik mengekstraksi metode lain yang menjelaskan apa yang terjadi daripada membungkus blok itu di suatu wilayah.

Michael Brown
sumber
3

Bisakah daerah digunakan dalam kode yang berkualitas baik? Mungkin. Saya yakin mereka, dalam banyak kasus. Namun, pengalaman pribadi saya membuat saya sangat curiga - saya telah melihat daerah hampir secara eksklusif disalahgunakan. Saya akan mengatakan bahwa saya letih, tetapi masih optimis.

Secara kasar saya dapat membagi kode menggunakan wilayah yang saya lihat sampai saat ini menjadi tiga kategori:

  • Kode dengan faktor buruk: Sebagian besar kode yang saya lihat menggunakan daerah sebagai alat anjak orang miskin. Misalnya, kelas yang telah berkembang ke titik di mana masuk akal untuk mengkhususkannya untuk tujuan yang berbeda mungkin malah dibagi menjadi daerah yang terpisah, satu untuk setiap tujuan.

  • Kode ditulis menggunakan pustaka yang salah, dan terkadang bahasa yang salah, untuk domain masalah Seringkali, ketika seorang programmer tidak menggunakan set pustaka yang tepat untuk domain masalah, Anda akan melihat kode menjadi sangat bertele-tele - dengan banyak fungsi pembantu kecil yang benar-benar bukan milik (mereka mungkin termasuk di perpustakaan mereka sendiri).

  • Kode ditulis oleh siswa atau lulusan baru. Beberapa program dan kursus tampaknya mencoba dan menanamkan siswa dengan penggunaan daerah untuk segala macam tujuan aneh. Anda akan melihat wilayah mengotori kode sumber ke titik di mana rasio tag wilayah terhadap baris kode berada dalam kisaran 1: 5 atau lebih buruk.

blueberryfields
sumber
3

Saya akan mengatakan itu adalah "bau kode."

Anti-pola umumnya merupakan masalah struktural mendasar dalam sebuah perangkat lunak, sedangkan wilayah, dengan sendirinya hanya menyebabkan perilaku yang menjengkelkan dalam editor. Menggunakan wilayah sebenarnya tidak secara inheren buruk, tetapi menggunakannya banyak, terutama untuk menyembunyikan potongan kode dapat menunjukkan ada masalah lain, independen dan lebih besar terjadi di tempat lain.

Apa namanya
sumber
@Andrew Grimm: yeah
whatsisname
3

Saya menggunakan wilayah hanya untuk satu hal (setidaknya saya tidak bisa memikirkan tempat lain yang saya gunakan): untuk mengelompokkan tes unit untuk suatu metode.

Saya biasanya memiliki satu kelas uji per kelas dan kemudian mengelompokkan tes unit untuk setiap metode dengan menggunakan daerah yang memiliki nama metode. Tidak yakin apakah itu bau kode atau apa, tetapi karena ide dasarnya adalah bahwa unit test tidak perlu diubah kecuali mereka rusak karena ada sesuatu dalam kode yang berubah, membuat saya lebih mudah menemukan semua tes untuk metode tertentu cukup cepat.

Saya mungkin pernah menggunakan daerah untuk mengatur kode di masa lalu, tapi saya tidak ingat kapan terakhir kali saya melakukannya. Saya tetap berpegang pada wilayah saya di kelas-kelas unit test.

Anne Schuessler
sumber
1
Apakah Anda pernah memiliki tes yang menguji lebih dari satu metode?
Marcie
Saya benar-benar tidak mengerti pertanyaannya atau apa tujuan Anda. Jawabannya adalah: Tidak, tes unit selalu ditargetkan hanya pada satu metode atau lebih tepatnya aspek tertentu dari satu metode.
Anne Schuessler
2

Saya percaya ini adalah pola anti dan terus terang berpikir mereka harus dihilangkan. Tetapi jika Anda berada dalam situasi yang tidak menguntungkan untuk bekerja di tempat di mana mereka adalah standar, Visual Studio menawarkan alat yang luar biasa untuk meminimalkan jumlah yang ingin Anda muntah setiap kali Anda melihat wilayah yang saya benci #Regions

Plugin ini akan max ukuran font daerah sangat kecil. Mereka juga akan diperluas sehingga Anda tidak perlu menekan ctr + m + l untuk membuka semua wilayah. Itu tidak memperbaiki bentuk kanker kode ini tetapi itu membuatnya tertahankan.

Anggota DeadlyChambers
sumber
0

Saya menggunakan kawasan untuk memuat setiap kombinasi visibilitas dan tipe anggota. Jadi semua fungsi pribadi masuk ke suatu daerah, dll.

Alasan saya melakukan ini bukan karena saya bisa melipat kode. Itu karena saya memiliki editor saya sehingga saya dapat memasukkan, katakanlah, referensi ke proxy:

#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

ke dalam kode dan masing-masing bagian terselip dengan rapi ke wilayah yang tepat.

Dalam hal ini makro akan menganalisis proyek saya, beri saya kotak daftar proksi dan menyuntikkan kode yang saya inginkan. Kursor saya bahkan tidak bergerak.

Pada awal pembelajaran C # saya telah mempertimbangkan penggunaan daerah untuk menjaga kesamaan, tetapi itu adalah proposisi hit and miss karena itu bukan hubungan satu-ke-satu setiap saat. Siapa yang ingin meresahkan anggota yang digunakan oleh dua wilayah, atau bahkan mulai memecah hal-hal pada istilah itu.

Satu-satunya jenis pemisahan lainnya adalah metode - saya akan membagi metode menjadi Perintah, Fungsi, dan Penangan, jadi saya akan memiliki wilayah untuk Perintah publik, pribadi, dll.

Ini memberi saya granularitas, tetapi konsisten, granularitas tegas yang dapat saya andalkan.

Menandai
sumber
-1 segera setelah saya mendapatkan 125 poin untuk dibatalkan. Anda menambahkan baris kode yang tidak dibutuhkan. MENGAPA MENGAPA MENGAPA Anda akan menempatkan suatu wilayah di sekitar properti ... jika (God.Iam.AbusingRegions () == true) myName = "Mark"
DeadlyChambers
1
@DeadlyChambers Alasannya dinyatakan dalam paragraf kedua - Saya menggunakan editor makro untuk menyuntikkan pola kode umum ke dalam file, daerah membantu menjaga file terstruktur sehingga item serupa dikelompokkan. Saya tidak menempatkan wilayah di sekitar properti tunggal, tetapi semua properti jatuh ke wilayah yang ditentukan tergantung pada atributnya "protected_const_properties". Apakah Anda membaca posting?
Markus
1
Anda mungkin dapat mengubah itu menjadi: protected LauncherProxy LauncherProxy => God.Iam.GetOrAddProxy <LauncherProxy> (ref _launcherProxy); dan dengan demikian Anda sekarang tidak membutuhkan wilayah. Juga _launcherProxy dapat diubah namanya menjadi _launcherProxyCache sehingga Anda tidak perlu wilayah atau komentar di sana.
aeroson
0

Wilayah adalah ekspresi preprosesor - dengan kata lain mereka diperlakukan seperti komentar dan pada dasarnya diabaikan oleh kompiler. Mereka murni alat visual yang digunakan dalam Visual Studio. Karena itu #region sebenarnya bukan bau kode, karena itu bukan kode. Bau kode bukan metode 800 garis yang memiliki banyak tanggung jawab yang tertanam di dalam dll. Jadi jika Anda melihat 10 wilayah dalam satu metode - itu mungkin digunakan untuk menyembunyikan bau kode. Setelah mengatakan bahwa saya telah melihat mereka menggunakan sangat efektif untuk membuat kelas lebih menyenangkan mata dan lebih dinavigasi - dalam kelas yang ditulis dengan sangat baik dan terstruktur juga!

BKSpurgeon
sumber
0

Daerah adalah ide organisasi yang bagus, tetapi gagal memperhitungkan beberapa kecenderungan pengembang yang ingin mengkategorikan semuanya, dan umumnya tidak perlu menurut sebagian besar praktik OOP modern ... mereka adalah "bau", dalam arti bahwa menggunakannya sering menunjukkan bahwa kelas / metode Anda terlalu besar dan harus di refactored, karena Anda kemungkinan melanggar "S" prinsip SOLID ... tetapi seperti bau apa pun, itu tidak selalu berarti ada yang buruk.

Wilayah melayani lebih banyak tujuan dalam kode fungsional daripada kode berorientasi objek, IMO, di mana Anda memiliki fungsi panjang dari data sekuensial yang masuk akal untuk dipecah, tetapi ada kalanya saya secara pribadi menggunakannya dalam c #, dan mereka hampir selalu fokus pada kode yang tidak perlu / ingin Anda lihat. Bagi saya, ini biasanya konstanta string SQL mentah dalam basis kode yang digunakan untuk NPoco atau variannya. Kecuali jika Anda benar-benar peduli bagaimana data datang untuk mengisi objek POCO melalui ORM Anda, ini sama sekali tidak berguna untuk dilihat ... dan jika Anda benar-benar peduli, hei, cukup perluas wilayah dan BAM! 150+ baris dari beberapa query SQL yang rumit untuk kesenangan Anda menonton.

Jeremy Holovacs
sumber