Prinsip Segregasi Antarmuka di Java

1. Perkenalan

Dalam tutorial ini, kita akan membahas Prinsip Segregasi Antarmuka, salah satu prinsip SOLID. Mewakili "I" dalam "SOLID", segregasi antarmuka berarti kita harus memecah antarmuka yang lebih besar menjadi antarmuka yang lebih kecil.

Sehingga memastikan bahwa mengimplementasikan kelas tidak perlu mengimplementasikan metode yang tidak diinginkan.

2. Prinsip Segregasi Antarmuka

Prinsip ini pertama kali didefinisikan oleh Robert C. Martin sebagai: " Klien tidak boleh dipaksa untuk bergantung pada antarmuka yang tidak mereka gunakan ".

Tujuan dari prinsip ini adalah untuk mengurangi efek samping dari penggunaan antarmuka yang lebih besar dengan memecah antarmuka aplikasi menjadi yang lebih kecil . Ini mirip dengan Prinsip Tanggung Jawab Tunggal, di mana setiap kelas atau antarmuka melayani satu tujuan.

Desain aplikasi yang tepat dan abstraksi yang benar adalah kunci di balik Prinsip Segregasi Antarmuka. Meskipun akan membutuhkan lebih banyak waktu dan tenaga dalam fase desain aplikasi dan mungkin meningkatkan kompleksitas kode, pada akhirnya, kita mendapatkan kode yang fleksibel.

Kami akan melihat beberapa contoh di bagian selanjutnya di mana kami memiliki pelanggaran prinsip, dan kemudian kami akan memperbaiki masalah dengan menerapkan prinsip dengan benar.

3. Contoh Antarmuka dan Implementasinya

Mari kita lihat situasi di mana kita memiliki antarmuka Pembayaran yang digunakan oleh implementasi BankPayment :

public interface Payment { void initiatePayments(); Object status(); List getPayments(); }

Dan implementasinya:

public class BankPayment implements Payment { @Override public void initiatePayments() { // ... } @Override public Object status() { // ... } @Override public List getPayments() { // ... } }

Untuk kesederhanaan, mari kita abaikan implementasi bisnis sebenarnya dari metode ini.

Ini sangat jelas - sejauh ini, kelas pelaksana BankPayment membutuhkan semua metode di antarmuka Pembayaran . Sehingga tidak melanggar prinsip.

4. Mencemari Antarmuka

Sekarang, saat kita bergerak maju dalam waktu, dan lebih banyak fitur masuk, ada kebutuhan untuk menambahkan layanan Pembayaran Pinjaman . Layanan ini juga merupakan jenis Pembayaran tetapi memiliki beberapa operasi lagi.

Untuk mengembangkan fitur baru ini, kami akan menambahkan metode baru ke antarmuka Pembayaran :

public interface Payment { // original methods ... void intiateLoanSettlement(); void initiateRePayment(); }

Selanjutnya, kita akan melakukan implementasi Pembayaran Pinjaman :

public class LoanPayment implements Payment { @Override public void initiatePayments() { throw new UnsupportedOperationException("This is not a bank payment"); } @Override public Object status() { // ... } @Override public List getPayments() { // ... } @Override public void intiateLoanSettlement() { // ... } @Override public void initiateRePayment() { // ... } }

Sekarang, karena antarmuka Pembayaran telah berubah dan lebih banyak metode ditambahkan, semua kelas pelaksana sekarang harus mengimplementasikan metode baru. Masalahnya, penerapannya tidak diinginkan dan bisa menimbulkan banyak efek samping. Di sini, kelas implementasi LoanPayment harus mengimplementasikan inisiatePayments () tanpa kebutuhan sebenarnya untuk ini. Dan karenanya, prinsip itu dilanggar.

Jadi, apa yang terjadi pada kelas Pembayaran Bank kami :

public class BankPayment implements Payment { @Override public void initiatePayments() { // ... } @Override public Object status() { // ... } @Override public List getPayments() { // ... } @Override public void intiateLoanSettlement() { throw new UnsupportedOperationException("This is not a loan payment"); } @Override public void initiateRePayment() { throw new UnsupportedOperationException("This is not a loan payment"); } }

Perhatikan bahwa implementasi BankPayment sekarang telah menerapkan metode baru. Dan karena itu tidak membutuhkannya dan tidak memiliki logika untuk mereka, itu hanya melontarkan UnsupportedOperationException . Di sinilah kita mulai melanggar prinsip.

Di bagian selanjutnya, kita akan melihat bagaimana kita bisa menyelesaikan masalah ini.

5. Menerapkan Prinsip

Di bagian terakhir, kami sengaja mencemari antarmuka dan melanggar prinsip. Pada bagian ini, kita akan melihat bagaimana cara menambahkan fitur baru untuk pembayaran pinjaman tanpa melanggar prinsip.

Mari kita uraikan antarmuka untuk setiap jenis pembayaran. Situasi saat ini:

Perhatikan di diagram kelas, dan mengacu pada antarmuka di bagian sebelumnya, bahwa metode status () dan getPayments () diperlukan di kedua implementasi. Di sisi lain, inisiatePayments () hanya diperlukan di BankPayment , dan metode inisiateLoanSettlement () serta inisiateRePayment () hanya untuk LoanPayment .

Setelah diurutkan, mari kita hancurkan antarmuka dan terapkan Prinsip Segregasi Antarmuka. Jadi, kami sekarang memiliki antarmuka yang sama:

public interface Payment { Object status(); List getPayments(); }

Dan dua antarmuka lagi untuk dua jenis pembayaran:

public interface Bank extends Payment { void initiatePayments(); }
public interface Loan extends Payment { void intiateLoanSettlement(); void initiateRePayment(); }

Dan implementasi masing-masing, dimulai dengan Pembayaran Bank :

public class BankPayment implements Bank { @Override public void initiatePayments() { // ... } @Override public Object status() { // ... } @Override public List getPayments() { // ... } }

Dan terakhir, implementasi Pembayaran Pinjaman kami yang telah direvisi :

public class LoanPayment implements Loan { @Override public void intiateLoanSettlement() { // ... } @Override public void initiateRePayment() { // ... } @Override public Object status() { // ... } @Override public List getPayments() { // ... } }

Sekarang, mari kita tinjau diagram kelas baru:

Seperti yang bisa kita lihat, antarmuka tidak melanggar prinsip. Implementasi tidak harus menyediakan metode kosong. Ini menjaga kode tetap bersih dan mengurangi kemungkinan bug.

6. Kesimpulan

Dalam tutorial ini, kami melihat skenario sederhana, di mana kami pertama kali menyimpang dari mengikuti Prinsip Segregasi Antarmuka dan melihat masalah yang disebabkan oleh penyimpangan ini. Kemudian kami menunjukkan bagaimana menerapkan prinsip dengan benar untuk menghindari masalah tersebut.

Jika kita berurusan dengan antarmuka lama yang tercemar yang tidak dapat kita modifikasi, pola adaptor bisa berguna.

Prinsip Segregasi Antarmuka adalah konsep penting saat merancang dan mengembangkan aplikasi. Mematuhi prinsip ini membantu menghindari antarmuka yang membengkak dengan banyak tanggung jawab. Hal ini pada akhirnya membantu kita untuk mengikuti Prinsip Tanggung Jawab Tunggal juga.

Seperti biasa, kode tersedia di GitHub.