Kopel. Praktik terbaik

11

Mengikuti dari utas ini saya mulai

Pola Singleton

Itu membuat saya berpikir tentang bagaimana menggabungkan kelas saya dan bagaimana cara terbaik untuk mencapai kopling longgar. Harap diingat bahwa saya seorang programmer baru (4 bulan ke pekerjaan pertama saya) dan ini benar-benar pertimbangan pertama yang saya berikan untuk ini, dan saya sangat tertarik untuk memahami konsepnya.

Jadi, apa tepatnya kopling longgar dan kopling berat? Dalam proyek saya saat ini (dan proyek pertama), saya sedang mengerjakan proyek ac # winforms, di mana bagian GUI membuat objek dan berlangganan ke acara mereka, ketika dipicu, GUI membuat objek lain (dalam contoh ini, datagridview (kelas) yang telah saya buat yang membungkus sekitar datagridview standar dan menambahkan fungsionalitas tambahan) dan melampirkannya ke GUI. Apakah ini kopling yang buruk atau bagus?

Saya benar-benar tidak ingin masuk ke kebiasaan buruk dan mulai mengkode dengan buruk, karenanya saya akan menghargai tanggapan Anda.

Darren Young
sumber

Jawaban:

11

Untuk membuat kode Anda secara longgar digabungkan di sini adalah beberapa hal sederhana untuk diingat:

Bagian 1:

Secara teknis dikenal sebagai "Pemisahan Kepedulian". Setiap kelas memiliki peran tertentu, harus menangani logika bisnis atau logika aplikasi. Coba dan hindari kelas yang menggabungkan kedua tanggung jawab. yaitu kelas yang mengelola data (istilah luas) adalah logika aplikasi sedangkan kelas yang menggunakan data adalah logika bisnis.

Secara pribadi saya menyebut ini (di dunia kecil saya sendiri) sebagai create it or use it. Kelas harus membuat objek atau menggunakan objek yang seharusnya tidak pernah melakukan keduanya.

Bagian 2:

Bagaimana menerapkan pemisahan perhatian.
Sebagai titik awal ada dua teknik sederhana:

Catatan: Pola desain tidak mutlak.
Mereka seharusnya disesuaikan dengan situasi tetapi memiliki tema mendasar yang mirip dengan semua aplikasi. Jadi jangan lihat contoh di bawah ini dan katakan bahwa saya harus mengikuti ini dengan kaku; ini hanya contoh (dan sedikit dibuat-buat pada saat itu).

Injeksi Ketergantungan :

Di sinilah Anda melewatkan objek yang digunakan kelas. Objek yang Anda lewati didasarkan pada antarmuka sehingga kelas Anda tahu apa yang harus dilakukan dengannya tetapi tidak perlu tahu implementasi yang sebenarnya.

class Tokenizer
{
    public:
        Tokenizer(std::istream& s)
            : stream(s)
        {}
        std::string nextToken() { std::string token; stream >> token;return token;}
    private:
        std::istream& stream;
};

Di sini kami menyuntikkan aliran ke Tokenizer. Tokenizer tidak tahu jenis aliran apa asalkan menerapkan antarmuka std :: istream.

Pola Pencari Layanan :

Pola locator layanan adalah sedikit variasi pada injeksi ketergantungan. Daripada memberikan objek yang bisa digunakan, Anda memberikannya objek yang tahu cara menemukan (membuat) objek yang ingin Anda gunakan.

class Application
{
     public:
         Application(Persister& p)
             : persistor(p)
         {}

         void save()
         {
             std::auto_ptr<SaveDialog> saveDialog = persistor.getSaveDialog();
             saveDialog.DoSaveAction();
         }

         void load()
         {
             std::auto_ptr<LoadDialog> loadDialog = persistor.getLoadDialog();
             loadDialog.DoLoadAction();
         }
    private:
        Persister& persistor;
};

Di sini kita melewati objek aplikasi objek persistor. Ketika Anda melakukan tindakan simpan / muat menggunakan persistor untuk membuat objek yang benar-benar tahu bagaimana melakukan tindakan. Catatan: Sekali lagi persistor adalah sebuah antarmuka dan Anda dapat memberikan implementasi yang berbeda tergantung pada situasinya.

Ini berguna ketika potentiallyobjek unik diperlukan setiap kali Anda membuat tindakan.

Secara pribadi saya menemukan ini sangat berguna dalam penulisan unit test.

Catatan Pola:

Pola desain adalah subjek besar bagi dirinya sendiri. Ini sama sekali bukan daftar pola eksklusif yang dapat Anda gunakan untuk membantu dengan kopling longgar; ini hanyalah titik awal yang umum.

Dengan pengalaman Anda akan menyadari bahwa Anda sudah menggunakan pola-pola ini hanya saja Anda tidak menggunakan nama formal mereka. Dengan menstandarkan nama mereka (dan membuat semua orang mempelajarinya), kami menemukan bahwa mudah dan cepat untuk mengomunikasikan ide.

Martin York
sumber
3
@ Darren Young: Terima kasih telah menerimanya. Tetapi pertanyaan Anda baru berumur tiga jam. Saya akan kembali dalam satu hari atau lebih untuk memverifikasi bahwa orang lain belum memberikan jawaban yang lebih baik.
Martin York
Terima kasih atas tanggapan yang luar biasa. Mengenai pemisahan masalah .... Saya memiliki kelas yang memerlukan beberapa data untuk penggunaannya dan kemudian melakukan sesuatu dengan data itu. Beginilah dulu saya merancang kelas. Apakah karena itu akan lebih baik untuk membuat kelas yang memperoleh data dan menyesuaikannya dengan bentuk yang benar dan kemudian kelas lain untuk benar-benar menggunakan data?
Darren Young
@ Darren Young: Seperti semua pemrograman, garisnya abu-abu dan buram tidak didefinisikan dengan baik. Sulit untuk memberikan respons yang tepat tanpa membaca kode Anda. Tetapi ketika saya berbicara tentang managing the datasaya merujuk ke variabel (bukan data aktual). Jadi hal-hal seperti pointer perlu dikelola agar tidak bocor. Tetapi data dapat disuntikkan atau bagaimana data diambil dapat diabstraksi (sehingga kelas Anda dapat digunakan kembali dengan metode pengambilan data yang berbeda). Maaf saya tidak bisa lebih tepatnya.
Martin York
1
@ Darren Young: Seperti dicatat oleh @StuperUser dalam jawabannya. Jangan berlebihan (AKA minutae of loose coupling(suka kata minutae)). Rahasia pemrograman adalah belajar kapan harus menggunakan teknik. Terlalu sering menggunakan dapat menyebabkan kusutnya kode.
Martin York
@ Martin - terima kasih atas sarannya. Saya pikir di situlah saya berjuang saat ini ..... Saya cenderung terus-menerus khawatir tentang arsitektur kode saya dan juga mencoba untuk belajar bahasa spesifik saya menggunakan C #. Saya kira itu akan datang dengan pengalaman dan keinginan saya untuk mempelajari hal ini. Saya menghargai komentar Anda.
Darren Young
6

Saya seorang pengembang ASP.NET jadi tidak tahu banyak tentang kopling WinForms, tetapi tahu sedikit dari aplikasi web N-Tier, dengan asumsi arsitektur aplikasi 3 tingkat UI, Domain, Data Access Layer (DAL).

Kopling longgar adalah tentang abstraksi.

Seperti yang dinyatakan @MKO jika Anda dapat mengganti rakitan dengan yang lain (mis. Proyek UI baru yang menggunakan proyek Domain Anda, DAL baru yang menyimpan ke spreadsheet daripada database) maka ada kopling longgar. Jika Domain dan DAL Anda bergantung pada proyek lebih jauh ke bawah rantai, maka kopling bisa lebih longgar.

Salah satu aspek dari sesuatu yang secara longgar digabungkan adalah apakah Anda dapat mengganti objek dengan yang lain yang mengimplementasikan antarmuka yang sama. Itu tidak tergantung pada objek yang sebenarnya, tetapi deskripsi abstrak dari apa yang dilakukannya (interface-nya).
Kopling longgar, antarmuka dan Dependency Injectors (DI) dan Inversion of Control (IoC) berguna untuk aspek isolasi dalam mendesain agar dapat diuji.

Misalnya objek dalam proyek UI memanggil objek repositori dalam proyek Domain.
Anda dapat membuat objek palsu yang mengimplementasikan antarmuka yang sama dengan repositori yang digunakan oleh kode yang diuji, kemudian menulis perilaku khusus untuk pengujian ( bertopik untuk mencegah kode produksi yang menyimpan / menghapus / dipanggil dan mengolok - olok yang bertindak sebagai bertopik dan melacak keadaan objek palsu untuk tujuan pengujian).
Berarti satu-satunya kode produksi yang dipanggil sekarang hanya di objek UI Anda, pengujian Anda akan bertentangan dengan metode itu saja dan setiap kegagalan pengujian akan mengisolasi cacat pada metode itu.

Juga, di menu Analisis dalam VS (tergantung pada versi yang Anda miliki) ada alat untuk Menghitung Metrik Kode untuk proyek Anda, salah satunya adalah Kopling Kelas, akan ada informasi lebih lanjut tentang ini dalam dokumentasi MSDN.

Namun, jangan TERLALU terhenti dalam minutae dari kopling longgar, jika TIDAK ada kemungkinan hal-hal digunakan kembali (mis. Proyek domain dengan lebih dari satu UI) dan umur produk kecil, maka kopling longgar menjadi kurang prioritas (masih akan diperhitungkan), tetapi akan tetap menjadi tanggung jawab arsitek / pemimpin teknologi yang akan meninjau kode Anda.

StuperUser
sumber
3

Coupling mengacu pada tingkat pengetahuan langsung yang dimiliki satu kelas dari kelas lainnya . Ini tidak dimaksudkan untuk ditafsirkan sebagai enkapsulasi vs non-enkapsulasi. Ini bukan referensi ke pengetahuan satu kelas tentang atribut atau implementasi kelas yang lain, melainkan pengetahuan tentang kelas yang lain itu sendiri. Kopling kuat terjadi ketika kelas dependen berisi pointer langsung ke kelas konkret yang menyediakan perilaku yang diperlukan. Ketergantungan tidak dapat diganti, atau "tanda tangannya" berubah, tanpa memerlukan perubahan ke kelas dependen. Kopling longgar terjadi ketika kelas dependen berisi hanya pointer ke antarmuka, yang kemudian dapat diimplementasikan oleh satu atau banyak kelas beton.Ketergantungan kelas dependen adalah untuk "kontrak" yang ditentukan oleh antarmuka; daftar metode dan / atau properti yang didefinisikan yang harus disediakan oleh kelas pelaksana. Setiap kelas yang mengimplementasikan antarmuka dengan demikian dapat memenuhi ketergantungan kelas dependen tanpa harus mengubah kelas. Hal ini memungkinkan pengembangan perangkat lunak; kelas baru yang mengimplementasikan antarmuka dapat ditulis untuk menggantikan dependensi saat ini dalam beberapa atau semua situasi, tanpa memerlukan perubahan ke kelas dependen; kelas baru dan lama dapat dipertukarkan secara bebas. Kopling yang kuat tidak memungkinkan hal ini. Tautan Ref.

Amir Rezaei
sumber
3

Lihatlah 5 prinsip SOLID . Mengikuti SRP, ISP dan DIP akan secara signifikan menurunkan kopling, DIP sejauh ini yang paling kuat. Ini adalah prinsip dasar di bawah DI yang telah disebutkan .

Juga, GRASP layak untuk dilihat. Ini adalah campuran aneh antara konsep-konsep abstrak (Anda akan menemukan sulit untuk menerapkan pada awalnya) dan pola-pola konkret (yang mungkin sebenarnya bisa membantu), tetapi kecantikan mungkin adalah yang paling tidak menjadi perhatian Anda saat ini.

Dan terakhir, Anda mungkin menemukan bagian ini pada IoC cukup berguna, sebagai titik masuk ke teknik umum.

Bahkan, saya menemukan pertanyaan tentang stackoverflow , di mana saya menunjukkan aplikasi SOLID pada masalah nyata. Mungkin bacaan yang menarik.

back2dos
sumber
1

Menurut Wikipedia:

Dalam komputasi dan desain sistem, sistem yang digabungkan secara longgar adalah sistem di mana masing-masing komponennya memiliki, atau memanfaatkan, sedikit atau tidak sama sekali pengetahuan tentang definisi komponen-komponen terpisah lainnya.

Masalah dengan kopling ketat membuat sulit untuk melakukan perubahan. (Banyak penulis tampaknya menyarankan bahwa ini terutama menyebabkan masalah selama pemeliharaan, tetapi dalam pengalaman saya itu juga relevan selama pengembangan awal, juga.) Apa yang cenderung terjadi dalam sistem yang digabungkan secara ketat adalah bahwa perubahan pada satu modul dalam sistem memerlukan perubahan tambahan dalam modul yang digabungkan. Lebih sering daripada tidak, ini membutuhkan lebih banyak perubahan pada modul lain dan seterusnya.

Sebaliknya, dalam sistem yang digabungkan secara longgar, perubahan relatif terisolasi. Karenanya mereka lebih murah dan dapat dibuat dengan keyakinan yang lebih besar.

Dalam contoh khusus Anda, hal-hal yang menangani peristiwa memang memberikan beberapa pemisahan antara GUI dan data yang mendasarinya. Namun, itu terdengar seolah-olah ada area pemisahan lain yang bisa Anda jelajahi. Tanpa rincian lebih lanjut dari situasi khusus Anda, sulit untuk menjadi spesifik. Namun, Anda mungkin mulai dengan arsitektur 3-tier yang memisahkan:

  • Penyimpanan data dan pengambilan logika
  • Logika bisnis
  • Logika diperlukan untuk menjalankan UI

Yang perlu dipertimbangkan adalah bahwa untuk aplikasi kecil, satu kali dengan pengembang tunggal, manfaat dari penerapan kopling longgar di setiap tingkat mungkin tidak sepadan dengan usaha. Di sisi lain, aplikasi yang lebih besar dan lebih kompleks dengan banyak pengembang merupakan keharusan. Awalnya, ada biaya yang dikeluarkan untuk memperkenalkan abstraksi dan mendidik pengembang yang tidak terbiasa dengan kode mengenai arsitekturnya. Dalam jangka panjang, bagaimanapun, longgar kopling menawarkan keuntungan yang jauh lebih besar daripada biayanya.

Jika Anda serius mendesain sistem yang digabungkan secara longgar, bacalah tentang prinsip-prinsip SOLID dan pola desain.

Namun, hal penting yang harus disadari adalah bahwa pola dan prinsip ini hanya itu - pola dan prinsip. Itu bukan aturan. Ini berarti bahwa mereka perlu diterapkan secara pragmatis dan cerdas

Dalam kaitannya dengan pola, penting untuk dipahami bahwa tidak ada satu pun implementasi "yang benar" dari salah satu pola tersebut. Mereka juga bukan templat pemotong kue untuk mendesain implementasi Anda sendiri. Mereka ada di sana untuk memberi tahu Anda bentuk solusi apa yang mungkin dimiliki, dan untuk memberi Anda bahasa umum untuk mengkomunikasikan keputusan desain dengan pengembang lain.

Semua yang terbaik.

Kramii
sumber
1

Gunakan injeksi ketergantungan, pola strategi, dan acara. Secara umum: membaca tentang pola desain, mereka semua tentang kopling longgar dan mengurangi ketergantungan. Saya akan mengatakan bahwa acara-acara tersebut sama longgarnya dengan yang Anda dapatkan saat injeksi dependensi dan pola strategi memerlukan beberapa antarmuka.

Trik yang baik adalah menempatkan kelas di perpustakaan / majelis yang berbeda, dan membuat mereka bergantung pada sesedikit mungkin perpustakaan lain, yang akan memaksa Anda untuk refactor untuk menggunakan lebih sedikit ketergantungan.

Homde
sumber
4
Apakah kondom adalah istilah IT abstrak atau saya tidak mendapatkan permainan kata-kata?
Darren Young
3
Itu nama lain untuk wadah injeksi ketergantungan.
Mchl
2
Juga cara yang bagus untuk mencegah penyebaran virus. Apakah kita membicarakan hal yang sama?
sova
1
Kopling berat sering dilakukan pada backend
Homde
1
Mengatur judul adalah format yang
sulit disalahgunakan
0

Biarkan saya memberikan tampilan alternatif. Saya hanya memikirkan ini dalam hal setiap kelas menjadi API yang baik. Urutan metode dipanggil jelas. Apa yang mereka lakukan jelas. Anda telah mengurangi jumlah metode menjadi seminimal yang dibutuhkan. Sebagai contoh,

init, buka, tutup

melawan

setTheFoo, setBar, initX, getConnection, tutup

Yang pertama jelas dan terlihat seperti API yang bagus. Yang kedua dapat menyebabkan kesalahan jika dipanggil dalam urutan yang salah.

Saya tidak terlalu khawatir harus memodifikasi dan mengkompilasi ulang penelepon. Saya memelihara BANYAK kode beberapa di antaranya baru dan sekitar 15 tahun. Saya biasanya ingin kesalahan kompiler ketika saya membuat perubahan. Terkadang saya sengaja akan merusak API karena alasan itu. Ini memberi saya kesempatan untuk mempertimbangkan konsekuensi pada masing-masing penelepon. Saya bukan penggemar injeksi ketergantungan karena saya ingin dapat melacak secara visual kode saya tanpa kotak hitam dan saya ingin kompiler menangkap sebanyak mungkin kesalahan.

Sean McEligot
sumber