Haruskah saya membuat antarmuka untuk objek transfer data?


19

Apakah itu ide yang baik atau ide buruk untuk membuat antarmuka untuk objek transfer data? Menganggap bahwa objek biasanya dapat berubah.

Meskipun contoh saya di Jawa, itu harus berlaku untuk bahasa lain yang memiliki konsep serupa.

interface DataTransferObject  {
    String getName();
    void setName(String name);
}

class RealDataTransferObject  implements DataTransferObject {

    String name;
    String getName() {
        return name;
    } 
    void setName(String name) {
        this.name = name;
    }
}

Tentu saja, ini adalah contoh yang disederhanakan, dalam kehidupan nyata mungkin ada lebih banyak bidang.

Jawaban:


24

Jawaban umumnya adalah tidak , karena Anda tidak boleh menambahkan kode tanpa alasan spesifik dan konkret untuknya, dan tidak ada alasan umum untuk antarmuka seperti itu.

Yang sedang berkata, kadang-kadang ada alasan yang bagus. Tetapi dalam semua kasus yang saya lihat, antarmuka ini parsial, yang hanya mencakup satu atau beberapa properti yang dibagi oleh beberapa kelas yang ingin saya gunakan secara polimorfik tanpa memberi mereka superclass umum. Kandidat yang umum adalah Idproperti untuk digunakan dalam semacam registri atau Nameproperti untuk ditampilkan kepada pengguna. Tapi ini bisa berguna dalam kasus apa pun di mana Anda ingin beberapa kode menangani semua yang memiliki X - cukup buat XSourceantarmuka yang berisi metode getX(dan, hanya jika diperlukan setX).

Tetapi antarmuka yang terpisah untuk setiap kelas model, yang berisi semua properti? Saya tidak bisa membayangkan alasan bagus untuk melakukan itu. Alasan yang buruk akan menjadi kerangka kerja yang dirancang buruk yang membutuhkannya; EJB Entitas melakukan hal itu, jika saya ingat dengan benar. Untungnya mereka sangat buruk sehingga mereka tidak pernah mendapatkan banyak daya tarik dan sudah ditinggalkan sejak EJB 3.0

Sidenote: harap hindari menggunakan istilah "objek nilai" untuk menggambarkan kacang Jawa dengan hanya pengambil dan setter sepele - ini bertentangan dengan definisi objek nilai yang lebih umum sebagai sesuatu tanpa identitas yang biasanya tidak dapat diubah. Istilah yang lebih baik adalah DTO atau kelas model - meskipun dalam kasus terakhir perhatikan bahwa model domain anemia dianggap sebagai antipattern.


3
"model domain anemik dianggap sebagai antipattern" - oleh Martin Fowler yang, dalam PEAA, mengakui bahwa dia mengenal orang-orang yang telah bekerja seperti itu selama beberapa dekade "sangat sukses". Jadi, saya sarankan, lebih sedikit anti-pola dan lebih banyak tidak-bagaimana-Fowler suka suka bekerja. Meskipun demikian, jawaban yang bagus, +1.
pdr

4
@ pdr: Fowler mungkin telah menciptakan istilah tersebut, tetapi ia bukan satu-satunya yang menganggap mereka antipengganti. Saya tidak berpikir siapa pun yang benar-benar mengerti OO berpikir itu ide yang baik untuk menjaga logika khusus domain dari model domain.
Michael Borgwardt

Terima kasih untuk koreksi jangka, DTO adalah kata yang saya cari tadi malam tapi tidak bisa mengingat kehidupan saya. Dengan mengubah nama di sekitar, hal-hal menjadi lebih masuk akal desain bijaksana.
Archimedes Trajano

@ pdr Saya pikir cara terbaik untuk mengatakannya adalah itu adalah antipattern dalam konteks pemrograman OO. Ada banyak paradigma lain di mana itu sangat baik, dan Anda bahkan bisa berhasil bekerja seperti itu dalam bahasa OO (itu tidak akan terlalu berorientasi objek).
Daniel B

3
@MichaelBorgwardt: Saya setuju, dia tidak sendirian dalam hal itu. Tetapi tidak ada orang yang tidak setuju. Jika Anda mengatakan "model domain anemia dianggap oleh beberapa orang sebagai anti-pola," saya tidak akan mengatakan apa-apa. Terus terang, saya pikir seluruh jawaban Anda akan lebih baik tanpa paragraf terakhir. Paruh pertama akan membuat komentar yang lebih baik; bagian kedua tidak menawarkan apa pun untuk pertanyaan ini.
pdr

2

Membuat antarmuka tidak masalah, tetapi BUKAN cara kerja contoh Anda. Anda harus menghapus setter dari antarmuka, dan itu akan baik-baik saja:

interface ValueObject {
  String getName();
};

Ini memungkinkan banyak implementasi yang berbeda, seperti nama dapat diambil dari basis data ... Setter harus dalam antarmuka yang berbeda.


2

Antarmuka mendefinisikan kontrak antara kelas yang mengimplementasikan antarmuka dan klien mereka. Mereka digunakan sebagai mekanisme abstraksi sehingga klien dapat memanipulasi "barang yang memiliki perilaku tertentu".

Jadi jawaban umum untuk pertanyaan "haruskah saya membuat dan menggunakan antarmuka ini?" adalah: Ya, jika Anda dapat mengaitkan konsep (satu) yang semantik relevan bagi klien Anda.

Sebagai contoh, Comparable adalah antarmuka yang baik, karena menjelaskan bahwa banyak hal dapat dibandingkan berkat salah satu metode mereka, dan sebagai klien saya tertarik berurusan dengan objek yang sebanding (misalnya untuk menyortirnya). Sebuah contrario, CoolStuff bukan antarmuka yang baik jika Anda mengakui objek keren tidak memiliki perilaku tertentu (pada kenyataannya, Anda dapat membayangkan sebuah perangkat lunak di mana berurusan dengan objek keren masuk akal, karena mereka memiliki perilaku umum seperti beCool metode).

Dalam kasus khusus Anda, saya percaya antarmuka Anda tidak berguna. Siapa yang akan menggunakannya, bagaimana dan kapan? Anda tidak dapat membuat antarmuka untuk masing-masing nilai yang dapat diubah. Jadi tanyakan pada diri sendiri apa properti yang relevan dan menarik di balik metode Anda.

Jika yang Anda inginkan adalah berurusan dengan objek yang memiliki semua nilai yang dapat diubah yang dapat diakses melalui beberapa metode, lihat gagasan tentang kacang Jawa dan cara Anda dapat memaksa kelas Anda untuk mengadopsi konvensi mereka.


2

Seperti kata Michael, jangan tambahkan antarmuka kecuali Anda memiliki kebutuhan khusus untuk itu.

Pengujian adalah contoh alasan yang bagus. Meskipun saya lebih suka menggunakan kolaborator nyata jika mereka hanya "objek nilai" seperti yang Anda sebut, untuk isolasi unit test yang sebenarnya Anda mungkin perlu membuat objek palsu untuk pengujian, dalam hal ini antarmuka cukup membantu.


1
Antarmuka belum diperlukan untuk menggunakan kerangka kerja mengejek di usia.
Michael Borgwardt

Kedengarannya seperti Anda mengadvokasi monkeypatching. Saya sudah menyusuri jalan itu dengan Tahi Lalat di C # dan itu tidak cantik. Lebih baik untuk mengirim kolaborator Anda jika memungkinkan.
jhewlett

1
Meskipun dua kerangka kerja mengejek saya menggunakan Mockito dan easyMock tidak bisa mengejek kelas akhir saat membuatnya tidak berubah.
Archimedes Trajano

1

Jika Anda ingin objek ini memiliki semacam validasi bidang di masa mendatang, Anda harus merangkumnya pada tahap awal.


0

'Antarmuka untuk objek nilai' adalah apa yang saya gunakan untuk memanggil accessor.

Saya mengalami kebijakan berbeda tentang kebutuhan pengakses. Beberapa orang mengadvokasi untuk sebanyak mungkin, beberapa lainnya melarang untuk mengurangi jumlah kode untuk ditulis.

Beberapa alasan untuk pengakses (atau penggunaan nilai langsung) adalah sebagai berikut:

  • Accessor memungkinkan mengubah nanti cara nilai disimpan
  • Accessors memungkinkan menambahkan log akses ketika Anda ingin men-debug perangkat lunak Anda (saat menambahkan panggilan log dalam metode tunggal, Anda menangkap setiap perubahan nilai)
  • Accessor lebih sejalan dengan pemrograman objek, setiap variabel dienkapsulasi oleh metode
  • Accessor mengurangi ekspres kode (lebih banyak SLOC untuk hasil yang sama)
  • Accessors mengambil beberapa CPU

Saya pribadi menganjurkan untuk mengurangi jumlah pengakses, dan menggunakannya saat Anda mengharapkan setter (setName) menjadi lebih dari sekadar pengaruh sederhana nanti.


0

Objek nilai semacam ini levelnya cukup rendah. Saya sarankan mendorongnya ke dalam salah satu dari dua arah: (1) membuat objek nilai tidak berubah, yaitu, seperti nilai nyata , atau, (2) meningkatkan mutabilitas ke fungsi bisnis berorientasi domain tingkat lebih tinggi, artinya kita harus mengekspos antarmuka dalam hal domain unit fungsionalitas yang relevan.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.