Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. PHP

SOLID: Bagian 4 - Dependency Inversion Principle

by
Read Time:10 minsLanguages:
This post is part of a series called The SOLID Principles.
SOLID: Part 3 - Liskov Substitution & Interface Segregation Principles

Indonesian (Bahasa Indonesia) translation by Andy Nur (you can also view the original English article)

Single Responsibility (SRP), Open/Closed (OCP), Liskov Substitution, Interface Segregation, dan Dependency Inversion. Lima prinsip agile yang harus membimbing mu setiap kali menulis kode.

Tidak adil jika kamu mengatakan bahwa salah satu prinsip SOLID lebih penting daripada yang lain. Namun, mungkin tidak ada yang lain, yang memiliki efek langsung dan mendalam pada kode-mu daripada Dependency Inversion Principle, atau DIP singkatnya. Jika kamu menemukan prinsip lain yang sulit dipahami atau diterapkan, mulailah dengan yang satu ini dan terapkan sisanya pada kode yang telah mematuhi DIP.

Definisi

A. Modul tingkat tinggi tidak boleh bergantung pada modul tingkat rendah. Keduanya harus bergantung pada abstraksi.
B. Abstraksi seharusnya tidak bergantung pada rincian. Rincian seharusnya bergantung pada abstraksi.

Prinsip ini didefinisikan oleh Robert C. Martin dalam bukunya Agile Software Development, Principles, Patterns, and Practices dan kemudian diterbitkan ulang dalam versi C# dari buku Agile Principles, Patterns, and Practices in C, dan ini merupakan yang terakhir dari lima prinsip agile SOLID.

DIP di Dunia Nyata

Sebelum kita memulai coding, saya ingin menceritakan sebuah cerita. Di Syneto, kami tidak selalu teliti dengan kode kami. Beberapa tahun yang lalu kami tahu lebih sedikit dan meskipun kami berusaha melakukan yang terbaik, tidak semua proyek kami begitu bagus. Kami melewati neraka dan kembali lagi dan kami belajar banyak hal dengan trial dan error.

Prinsip SOLID dan prinsip-prinsip arsitektur rapi dari Uncle Bob (Robert C. Martin) menjadi game changer bagi kami dan mengubah cara coding kami dengan cara yang sulit untuk dideskripsikan. Saya akan mencoba untuk mencontohkan, singkatnya, beberapa keputusan arsitektur utama yang dipaksakan oleh DIP yang memiliki dampak besar pada proyek kami.

Sebagian besar proyek web berisi tiga teknologi utama: HTML, PHP, dan SQL. Versi khusus dari aplikasi ini yang sedang kita bicarakan atau jenis implementasi SQL yang kamu gunakan tidak relevan. Masalahnya, informasi dari form HTML harus berakhir, dalam satu atau lain cara, di dalam database. Perekat di antara keduanya bisa disediakan dengan PHP.

Apa yang penting untuk diambil dari ini, adalah seberapa bagus ketiga teknologi tersebut mewakili tiga lapisan arsitektur yang berbeda: antarmuka pengguna, logika bisnis, dan persistence. Kita akan membicarakan implikasi dari lapisan ini dalam satu menit. Untuk saat ini, mari fokus pada beberapa solusi aneh namun sering dijumpai untuk membuat teknologi bekerja sama.

Sering kali saya melihat proyek yang menggunakan kode SQL dalam tag PHP di dalam file HTML, atau kode PHP yang meng-echo halaman dan halaman HTML dan menafsirkan secara langsung variabel global $_GET atau $_POST. Tetapi kenapa ini buruk?

html-php-sql-cross-dependencieshtml-php-sql-cross-dependencieshtml-php-sql-cross-dependencies

Gambar di atas mewakili versi mentah dari apa yang kita jelaskan di paragraf sebelumnya. Tanda panah mewakili berbagai dependensi, dan seperti yang dapat kita simpulkan, pada dasarnya semuanya tergantung pada segala hal. Jika kita perlu mengubah tabel database, kita mungkin akhirnya mengedit file HTML. Atau jika kita mengubah field dalam HTML, kita mungkin akan mengubah nama kolom dalam sebuah pernyataan SQL. Atau jika kita melihat skema kedua, mungkin kita perlu memodifikasi PHP kita jika HTML berubah, atau dalam kasus yang sangat buruk, ketika kita menghasilkan semua konten HTML dari dalam file PHP kita pasti perlu mengubah file PHP untuk memodifikasi konten HTML Jadi, tidak diragukan lagi, dependensinya adalah zigzag antara class dan modul. Tetapi itu tidak berakhir disini. Anda bisa menyimpan prosedur; kode PHP di tabel SQL

html-php-sql-stored-procedureshtml-php-sql-stored-procedureshtml-php-sql-stored-procedures

Pada skema di atas, query ke database SQL mengembalikan kode PHP yang dihasilkan dengan data dari tabel. Fungsi atau class PHP ini melakukan query SQL lainnya yang mengembalikan kode PHP yang berbeda, dan siklus berlanjut sampai akhirnya semua informasi diperoleh dan dikembalikan ... mungkin ke UI.

Saya tahu ini mungkin terdengar keterlaluan bagi banyak dari kamu, tapi jika kamu belum mengerjakan proyek yang diciptakan dan diimplementasikan dengan cara ini, kamu pasti akan menjalannya padai karir masa depanmu. Sebagian besar proyek yang ada, terlepas dari bahasa pemrograman yang digunakan, ditulis dengan prinsip lama, oleh programmer yang tidak peduli atau cukup tahu untuk berbuat lebih baik. Jika kamu membaca tutorial ini, kemungkinan besar kamu lebih tinggi dari itu. Kamu siap, atau bersiap untuk menghargao profesimu, merangkul kerajinan tanganmu, dan berbuat lebih baik.

Pilihan lainnya adalah mengulangi kesalahan yang dibuat pendahulumu dan hidup dengan konsekuensinya. Di Syneto, setelah salah satu proyek kami mencapai keadaan yang hampir tidak dapat dipelihara karena arsitekturnya yang kuno dan artisekteur yang bergantung silang dan pada dasarnya kami harus meninggalkannya selamanya, kami memutuskan untuk tidak pernah kembali ke jalan itu lagi. Sejak itu, kita telah berusaha untuk memiliki arsitektur rapi yang benar mematuhi prinsip SOLID, dan yang terpenting adalah Dependency Inversion Principle.

HighLevelDesignHighLevelDesignHighLevelDesign

Apa yang menakjubkan dari arsitektur ini adalah bagaimana dependensinya menunjuk:

  • Antarmuka pengguna (dalam kebanyakan kasus framework web MVC) atau mekanisme pengiriman lainnya yang ada untuk proyekmu akan bergantung pada logika bisnis. Logika bisnis cukup abstrak. Antarmuka pengguna sangat konkret. UI hanyalah detail untuk proyek ini, dan ini juga sangat tidak stabil. Tidak ada yang harus bergantung pada UI, tidak ada yang harus bergantung pada framework MVC mu.
  • Pengamatan menarik lainnya yang bisa kita buat adalah bahwa persistence, database, MySQL atau PostgreSQL mu, bergantung pada logika bisnis. Logika bisnismu adalah agnostik database. Hal ini memungkinkan pertukaran persistence sesuai keinginan. Jika besok kamu ingin mengubah MySQL dengan PostgreSQL atau hanya file teks biasa, kamu bisa melakukannya. Kamu tentu saja perlu menerapkan lapisan persistence yang spesifik untuk metode persistence yang baru, namun kamu tidak perlu memodifikasi satu baris kode dalam logika bisnismu. Ada penjelasan lebih rinci tentang topik persistence dalam tutorial Evolving Toward a Persistence Layer.
  • Akhirnya, di sebelah kanan logika bisnis, di luar itu, kita memiliki semua class yang menciptakan class logika bisnis. Ini adalah factory dan class yang dibuat oleh titik masuk ke aplikasi kita. Banyak orang cenderung menganggap ini milik logika bisnis, tetapi saat mereka menciptakan objek bisnis, satu-satunya alasan mereka adalah dengan melakukan ini. Mereka adalah class yang hanya membantu kita menciptakan class lainnya. Objek bisnis dan logika yang mereka berikan tidak bergantung pada factory ini. Kita bisa menggunakan pola yang berbeda, seperti Simple Factory, Abstract Factory, Builder atau pembuatan objek biasa untuk memberikan logika bisnis. Tidak masalah. Begitu objek bisnis diciptakan mereka bisa melakukan pekerjaan mereka.

Tunjukkan padaku Code

Menerapkan Dependency Inversion Principle (DIP) pada tingkat arsitektural cukup mudah jika kamu mematuhi agile design patterns klasik. Menggunakan dan mencontohnya di dalam logika bisnis cukup mudah juga dan bahkan bisa menyenangkan. Kita akan membayangkan sebuah aplikasi pembaca e-book.

kita mulai mengembangkan e-reader kita sebagai pembaca PDF. Sejauh ini bagus. Kita memiliki class PDFReader menggunakan PDFBook. Fungsi read() pada delegasi pembaca untuk metode read() buku. Kita hanya memverifikasi ini dengan melakukan cek regex setelah bagian kunci dari string yang dikembalikan oleh metode PDFBook reader().

Harap diingat bahwa ini hanyalah sebuah contoh. Kami tidak akan mengimplementasikan logika membaca file PDF atau format file lainnya. Itu sebabnya tes kita hanya akan memeriksa beberapa string dasar. Jika kita menulis aplikasi sebenarnya, satu-satunya perbedaan adalah bagaimana kita mengetes berbagai format file. Struktur dependensi akan sangat mirip dengan contoh kita.

pdfreader-pdfbookpdfreader-pdfbookpdfreader-pdfbook

Memiliki pembaca PDF menggunakan buku PDF mungkin merupakan solusi yang bagus untuk aplikasi terbatas. Jika ruang lingkup kita adalah menulis pembaca PDF dan tidak lebih, itu sebenarnya akan menjadi solusi yang dapat diterima. Tetapi kita ingin menulis pembaca e-book umum, mendukung beberapa format, di antaranya versi pertama kita yang mengimplementasikan PDF. Mari mengubah nama class pembaca kita.

Mengganti nama tidak memiliki efek melawan fungsional. Tesnya masih melintas.

Testing started at 1:04 PM ...
PHPUnit 3.7.28 by Sebastian Bergmann.
Time: 13 ms, Memory: 2.50Mb
OK (1 test, 1 assertion)
Process finished with exit code 0

Tetapi itu memiliki efek desain yang serius.

ebookreader-pdfbookebookreader-pdfbookebookreader-pdfbook

Pembaca kita menjadi lebih abstrak. Jauh lebih umum. Kita memiliki EBookReader umum yang menggunakan jenis buku yang sangat spesifik, PDFBook. Abstraksi tergantung pada detail. Fakta bahwa buku kita adalah bertipe PDF hanya boleh menjadi detail, dan tidak ada yang harus bergantung padanya.

Solusi yang paling umum, dan paling sering digunakan untuk membalikkan dependesinya adalah mengenalkan modul yang lebih abstrak dalam desain kita. "Unsur yang paling abstrak di OOP adalah Interface. Dengan demikian, class lainnya bisa bergantung pada Interface dan tetap mematuhi DIP".

Kita membuat sebuah interface untuk pembaca kita. Interface ini disebut EBook dan merupakan kebutuhan dari EBookReader. Ini adalah akibat langsung dari mematuhi Interface Segregation Principle (ISP) yang mempromosikan gagasan bahwa interfacea seharusnya mencerminkan kebutuhan klien. Interface dimiliki oleh klien, dan karenanya dinamai untuk mencerminkan tipe dan objek yang dibutuhkan klien dan metode tersebut akan berisi metode yang ingin digunakan klien. Adalah wajar bagi sebuah EBookReader untuk menggunakan Ebooks dan memiliki metode read().

ebookreader-ebookinterface-pdfbookebookreader-ebookinterface-pdfbookebookreader-ebookinterface-pdfbook

Daripada dependesi tunggal, kita memiliki dua dependensi sekarang.

  • Titik dependesi pertama dari EBookReader menuju interface EBook dan penggunaan tipe. EBookReader menggunakan EBooks.
  • Dependensi kedua berbeda. Ini mengarahkan dari PDFBook menuju interface EBook yang sama namun memiliki tipe implementasi. PDFBook hanyalah bentuk tertentu dari Ebook, dan dengan demikian impelementasi interface itu untuk memenuhi kebutuhan klien.

Tidak mengherankan, solusi ini juga memungkinkan kita menyambungkan berbagai jenis ebook ke pembaca kita. Kondisi tunggal untuk semua buku ini adalah untuk memenuhi interface EBook dan mengimplementasikannya.

Yang pada gilirannya membawa kita pada The Open/Closed Principle, dan lingkarannya ditutup.

Dependency Inversion Principle adalah salah satu yang memimpin atau membantu kita mematuhi semua prinsip lainnya. Mematuhi DIP akan:

  • Hampir memaksamu untuk mematuhi OCP.
  • Memungkinkanmu untuk memisahkan responsibiliti.
  • Membuatmu tepat menggunakan subtyping.
  • Menawarkan kesempatan untuk memisahkan interface-mu.

Pemikiran Akhir

Itu dia. Kita sudah selesai Semua tutorial tentang prinsip SOLID telah selesai. Bagi saya, secara pribadi, menemukan prinsip-prinsip ini dan melaksanakan proyek dengan mereka dalam pikiran adalah sebuah perubahan besar. Saya benar-benar mengubah cara saya memikirkan desain dan arsitektur dan dapat saya katakan sejak itu semua proyek yang saya kerjakan secara eksponensial lebih mudah diatur dan dipahami.

Saya menganggap prinsip SOLID salah satu konsep paling penting dari desain berorientasi objek. Konsep-konsep ini yang seharusnya membimbing kita dalam membuat kode kita lebih baik dan hidup kita sebagai programmer jauh lebih mudah. Kode yang dirancang dengan baik lebih mudah dipahami oleh programmer. Komputer itu cerdas, mereka bisa mengerti kode, terlepas dari kompleksitasnya. Manusia di sisi lain memiliki sejumlah hal yang mereka dapat tetap dalam pikirannya yang aktif dan terfokus. Lebih khusus lagi, jumlah hal tersebut adalah Nomor Ajaib Tujuh, Plus atau Minus Dua.

Kita harus berusaha agar kode kita terstruktur di sekitar angka-angka ini dan ada beberapa teknik yang membantu kita melakukannya. Fungsi dengan maksimal empat baris panjangnya (lima dengan garis definisi disertakan) sehingga semuanya bisa muat sekaligus dalam pikiran kita. Indentasi tidak melewati lima tingkat dalamnya. Class dengan tidak lebih dari sembilan metode. Desain pattern biasanya menggunakan lima sampai sembilan class. Desain tingkat tinggi kita dalam skema di atas menggunakan empat sampai lima konsep. Ada lima prinsip SOLID, masing-masing membutuhkan lima sampai sembilan sub-konsep/modul/class untuk dicontohkan. Ukuran ideal tim pemrograman adalah antara lima dan sembilan. Jumlah ideal tim di sebuah perusahaan adalah antara lima dan sembilan.

Seperti yang bisa Anda lihat, nomor ajaib tujuh, plus atau minus dua ada di sekitar kita, jadi mengapa kodemu harus berbeda?

Advertisement
Did you find this post useful?
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.