Haruskah setiap kelas yang saya tulis mematuhi antarmuka?

10

Saya sedang menulis sebuah game di Typecript, dan memutuskan bahwa saya akan mencoba untuk mematuhi ide " pemrograman berbasis antarmuka ", di mana Anda menulis kode berdasarkan pada antarmuka, bukan implementasi, dari suatu objek.

Saya menulis sejumlah antarmuka yang baik, dan kelas-kelas yang mengimplementasikannya, kemudian mengambil langkah mundur dan menyadari bahwa kelas-kelas itu cukup sederhana sehingga saya mungkin tidak perlu mengubah implementasi, karena hanya ada satu cara untuk melakukan apa yang kelas tidak (bergerak dengan Phaser.Spritecara terbatas untuk bertindak seperti tank).

Lalu saya ingat pernah membaca beberapa tahun yang lalu tentang ide YAGNI , yang pada dasarnya Anda tidak boleh terlalu merekayasa kode Anda untuk memasukkan hal-hal yang mungkin tidak pernah Anda gunakan.

Mengikuti praktik terbaik, haruskah setiap kelas menerapkan antarmuka, atau haruskah Anda membatasinya pada kelas yang Anda harapkan berpotensi ditukar di masa depan?

Carcigenicate
sumber
Ingat, ketika Anda menggunakan kelas aktual sebagai parameter, Anda juga mengkodekan ke antarmuka, ke antarmuka kelas ini. Tidak ada yang memaksa Anda untuk menggunakan kelas spesifik itu, Anda bisa mewarisinya dan menyediakan fungsionalitas yang sama sekali baru, tetapi itu sepertinya tidak benar. Antarmuka ada untuk membuat orang lebih mudah memahami ide itu. Dengan itu menjadi sedih, tidak, Anda tidak benar-benar membutuhkan antarmuka untuk semuanya.
Andy

Jawaban:

6

Alasan memiliki antarmuka adalah karena menyederhanakan polimorfisme. Berarti Anda dapat mengirim instance dengan kontrak daripada mengetahui penerapannya yang sebenarnya. Misalnya, Anda dapat mengirim "Pembaca" ke suatu metode, sehingga metode yang disebut seperti itu dapat menggunakan metode "baca ()". Dengan mendeklarasikan antarmuka "Pembaca" Anda dapat membuat objek apa pun sesuai dengan kontrak ini, dengan menerapkan metode yang ditentukan. Dengan cara ini, setiap penelepon dapat mengasumsikan metode tertentu akan ada, bahkan jika objek yang mendasari kontrak mungkin sama sekali berbeda.

Ini memisahkan polimorfisme dari kelas dasar, dan memungkinkan juga antara perbatasan rantai kelas, dengan menyiratkan kontrak.

Sekarang ... Ini hanya berguna jika Anda memerlukan beberapa rantai pewarisan untuk bertindak dengan cara yang sama, atau jika Anda akan memiliki banyak kelas dasar dengan perilaku umum yang ingin Anda sampaikan kepada pengguna lain.

Jika Anda hanya memiliki SATU rantai pewarisan (baseclass-> subclass) atau hanya basis, atau Anda tidak perlu benar-benar LULUS objek terkait ke orang lain atau menggunakannya secara umum, maka Anda tidak akan menambahkan implementasi antarmuka, karena gagasan itu kemudian tak berguna.

Richard Tyregrim
sumber
Saya juga menambahkan bahwa antarmuka harus memodelkan abstraksi, jadi jangan membuatnya dengan hanya mengangkat semua anggota publik kelas. Pikirkan tentang apa yang diwakili kelas itu, dan hanya tempatkan benda-benda itu di antarmuka yang harus dimiliki oleh objek jenis apa pun. Anda mungkin juga akhirnya membuat banyak antarmuka (misalnya Movesdan Shootsuntuk tangki contoh Anda) untuk satu kelas.
TMN
7

Jika Anda tidak yakin apakah Anda benar-benar membutuhkan antarmuka, maka Anda mungkin tidak. Ini adalah inti dari prinsip YAGNI. Ketika Anda harus bisa menukar implementasi, maka Anda memperkenalkan antarmuka.

JacquesB
sumber
6

Membuat antarmuka untuk setiap kelas agak berlebihan. Dari perspektif berorientasi objek murni, setiap kelas sudah memiliki antarmuka . Antarmuka tidak lebih dari metode yang dihadapi publik dan anggota data kelas.

Kami biasanya menggunakan "antarmuka" yang berarti "kelas Java yang ditentukan menggunakan interfacekata kunci" atau "kelas C ++ dengan hanya fungsi virtual publik yang murni." Ini adalah abstraksi yang berguna, karena mereka memisahkan antarmuka kelas dari implementasinya.

Dengan pemikiran itu, gunakan antarmuka saat yang tepat.

  • Apakah akan ada beberapa implementasi untuk sebuah antarmuka? Jika demikian, situasi ini dapat menjadi kandidat untuk mengekstraksi metode umum yang dihadapi publik ke dalam sebuah antarmuka.

  • Apakah saya akan menyerahkan implementasi antarmuka potensial ke modul lain yang seharusnya tidak mengetahui cara kerja modul saya? Antarmuka dapat bermanfaat di sini, karena mengurangi ukuran titik sentuh antar modul.

Perhatikan kata-kata musang di atas: "semoga" menjadi kandidat, "bisa" bermanfaat. Tidak ada aturan keras dan cepat yang mengatakan "ya" atau "tidak" untuk situasi tertentu.

Yang sedang berkata, memiliki antarmuka untuk semuanya kemungkinan besar adalah pembunuhan yang berlebihan. Jika Anda melihat pola ini, Anda akan jauh:

interface I {
  int getA()
  int getB()
  ...
  int getY()
  int getZ()
}

class C : I {
  int getA() { ... }
  int getB() { ... }
  ...
  int getY() { ... }
  int getZ() { ... }
}

sumber
Satu lagi alasan untuk antarmuka adalah jika sistem pengujian Anda membuatnya perlu, yang mungkin tergantung pada bahasa Anda dan kerangka kerja pengujian. Semoga Anda tidak perlu melakukan ini, tentu saja.
Darien
@Darien: Alasan bahwa sistem pengujian mungkin memerlukan antarmuka adalah karena pengujian tersebut sebenarnya menggunakan implementasi yang berbeda (diejek), membawa Anda kembali ke poin pertama ketika antarmuka sesuai.
Bart van Ingen Schenau
Beberapa hal hebat di sini. Hanya merenungkan ini: Antarmuka tidak lebih dari metode yang dihadapi publik dan anggota data kelas . Meskipun ini benar untuk implementasi antarmuka , itu tentu tidak berlaku untuk antarmuka yang tidak pernah diimplementasikan, meskipun diberikan - ini akan menjadi semacam bau kode.
Robbie Dee
@RobbieDee memang benar untuk misalnya Java interface, kebetulan bahwa segala sesuatu di Jawa interfacejuga merupakan antarmuka yang menghadap publik (konsep OO).
Semua orang! Tuliskan kalimat ke-2 & ke-3 jawabannya. Laminasi itu. Taruh di dompet kamu. Referensi sering.
radarbob
5

Mungkin sangat menggoda bagi pengembang baru untuk menganggap antarmuka sebagai ketidaknyamanan yang Anda tambahkan hanya karena Anda diberi tahu bahwa itu adalah "praktik terbaik". Jika Anda sedang membabi buta melakukan hal ini, memukul pemrograman kultus kargo .

Ada sejumlah alasan yang sangat baik bahwa Anda harus mempertimbangkan antarmuka untuk pengembangan yang lebih besar daripada mengumpulkan satu set kelas.

Kerangka kerja mengejek

Jika Anda ingin menguji aplikasi multi-layer tanpa harus membuat objek untuk berbagai lapisan, Anda pasti ingin menggunakan kerangka kerja mengejek untuk mengejek layer. Antarmuka digunakan secara luas di sini.

Ketergantungan injeksi

Sementara mereka agak tidak disukai karena mengasapi yang mereka tambahkan, idenya adalah suara - kemampuan untuk hanya bertukar dalam concretions berdasarkan pada antarmuka. Prinsipnya juga dapat ditemukan dalam banyak pola desain seperti pola pabrik.


Pendekatan-pendekatan ini dirangkum dalam D dari prinsip-prinsip SOLID . Intinya adalah - gunakan abstraksi, bukan konkret.

Seperti pola desain sendiri, kapan menggunakannya adalah panggilan penilaian. Poin takeaway adalah untuk memahami bagaimana antarmuka yang berguna tidak hanya menempelkannya di kelas Anda karena Anda merasa harus melakukannya. Ada diskusi yang bagus tentang berbagai manfaat DIP dan YAGNI di sini .

Robbie Dee
sumber
Perhatikan bahwa injeksi ketergantungan dan wadah IoC adalah dua hal yang sangat berbeda (satu adalah prinsip desain dan yang lainnya adalah salah satu cara untuk secara konkrit menerapkan prinsip tersebut dengan menggunakan berbagai kerangka kerja). Anda dapat menggunakan DI tanpa menggunakan wadah IoC.
Sara
@ Kai "Anda dapat menggunakan DI tanpa menggunakan wadah IoC" . Saya pikir toko pengembangan yang lebih dewasa dapat (dan melakukannya). Sama sekali tidak perlu mencemari kode untuk apa yang tampaknya konsep sederhana. Joel memiliki pandangan serupa.
Robbie Dee
YAGNI sangat rumit. Apa pun filosofinya, dalam banyak kasus, pada kenyataannya, YAGNI digunakan sebagai alasan untuk mengambil jalan pintas. Hindari pemasangan harus dianggap lebih serius. Sangat frustasi melihat dalam banyak rapat scrum, seorang pengembang menyebut dirinya diblokir karena orang lain tidak menyelesaikan pekerjaan mereka. Kenapa memblokir pengembang lain menghemat waktu? Saran saya adalah menggunakan antarmuka untuk menghindari sambungan. Tentu saja, seseorang tidak harus menggunakan antarmuka untuk kelas Model.
Ripal Barot