Apakah ada kekurangan sebenarnya untuk rantai metode referensial mandiri?


14

Baru-baru ini saya menyarankan metode chaining diimplementasikan untuk kelas tertentu dalam proyek tertentu sehingga keterbacaan kode dapat ditingkatkan. Saya mendapat "antarmuka yang lancar tidak seharusnya diimplementasikan hanya untuk kenyamanan, tetapi untuk semantik" menjawab dan saran saya ditembak jatuh. Saya menjawab bahwa saya tidak menyarankan antarmuka yang lancar tetapi metode chaining itu sendiri (keduanya dapat dikacaukan satu sama lain, baca di bawah) untuk meningkatkan keterbacaan dan kenyamanan pengkodean, saran itu ditembak jatuh lagi.

Bagaimanapun, ini membuat saya berpikir bahwa mungkin saya dapat mengalami praktik buruk dengan selalu mengembalikan "ini" dalam metode yang tidak seharusnya mengembalikan apa pun (misalnya seter).

Pertanyaan saya adalah: dapatkah menerapkan konvensi sebelumnya dianggap sebagai praktik atau penyalahgunaan yang buruk ?, mengapa? Saya tidak berpikir ada kekurangan kinerja, atau ada?


2
Lihatlah pertanyaan ini untuk programer
bagus.stackexchange.com/questions/48419/…

@KeesDijk Terima kasih, saya mengedit pertanyaan saya sedikit jadi tidak mirip dengan yang itu, karena saya lebih tertarik pada kasus metode chaining dari kelas yang sama
dukeofgaming

1
di SO, mereka mengatakan kepada saya, bahwa rantai bukan untuk C ++ - stackoverflow.com/questions/5760551/… - apa pendapat Anda?
kagali-san

1
@ mhambra Sepertinya Anda hanya perlu berhati-hati saat menerapkan metode chaining dan menetapkan standar yang jelas untuk itu.
dukeofgaming

Jawaban:


10

Tidak

Seperti yang ditunjukkan oleh Kent Beck , kode dibaca jauh lebih sering daripada yang tertulis.

Jika metode chaining membuat kode Anda lebih mudah dibaca, maka gunakan metode chaining.


1
Buku hebat .. +1
Rein Henrichs

5
TAPI , bagaimana jika Anda satu-satunya metode menemukan rantai yang lebih mudah dibaca? Jika ini adalah masalah masalah sytilistic, maka Anda harus tetap berpegang pada seperangkat konvensi pengkodean: ini berarti, menulis dengan cara yang sama dengan kode yang ada, untuk konsistensi.
coredump

@coredump Kedengarannya OP sudah diberitahu untuk melakukan itu, tapi saya pikir Steven hanya mengatakan ini jika metode chaining membuatnya lebih mudah dibaca.
Panzercrisis

1
@Panzercrisis OP telah diberitahu untuk menahan diri menggunakan metode chaining karena kenyamanan vs semantik. Jawaban Steven pada dasarnya mengatakan "lakukan saja" dan hanya mempertimbangkan keterbacaan kode OP dengan sendirinya, tanpa mempertimbangkan pendapat atau konsistensi tim. Bagaimana jika OP ingin menulis ulang setiap kelas yang ada di proyek sehingga sesuai dengan seleranya mengenai keterbacaan kode? Begitulah cara saya memahami argumen kenyamanan / semantik: harus ada alasan "teknis" untuk memiliki metode chaining (btw, argumen itu juga terdengar seolah-olah orang lain mengarang alasan untuk pilihannya sendiri)
coredump

9

Ya, ada kekurangannya

Kode yang mudah dibaca itu baik, tetapi juga berhati-hatilah dengan apa yang dikomunikasikan kode juga. Ketika metode objek selalu mengembalikan objek, itu mengkomunikasikan beberapa hal:

  1. Saya memerlukan konfigurasi lanjutan yang belum tentu jelas dengan urutan hal mana yang harus diatur atau dikonfigurasi
  2. Setiap panggilan metode selanjutnya dibangun berdasarkan yang terakhir

Kasing Penggunaan yang Valid: Kueri Basis Data Ad Hoc

Pustaka kelas ada di sebagian besar setiap bahasa yang memungkinkan Anda untuk query database tanpa menggunakan SQL kode keras. Ambil Entity Framework untuk .NET sebagai contoh:

DBContext db = new DBContext();
List<Post> posts = db.Posts
    .Where(post => post.Title.Contains("Test"))
    .OrderBy(post => post.DateCreated)
    .ToList();

Ini adalah antarmuka yang lancar di mana setiap panggilan metode selanjutnya dibangun di atas yang sebelumnya. Membaca panggilan ini secara logis masuk akal dalam konteks permintaan basis data.

Case Penggunaan Tidak Valid: Gula Sintaksis Untuk Mengatur Properti

Sekarang mari kita gunakan pola yang sama dengan Postkelas:

public class Post
{
    public string Title { get; set; }
    public DateTime DateCreated { get; set; }
    public string Body { get; set; }

    public Post SetTitle(string title)
    {
        Title = title;

        return this;
    }

    public Post SetDateCreated(DateTime created)
    {
        DateCreated = created;

        return this;
    }

    public Post SetBody(string body)
    {
        Body = body;

        return this;
    }
}

Sekarang mari kita lihat bagaimana Anda akan menggunakan kelas ini:

Post post = new Post()
    .SetTitle("Test")
    .SetDateCreated(DateTime.Now)
    .SetBody("Just a test");

Ketika saya melihat kode ini, saya langsung menanyakan pertanyaan ini: "Setelah menelepon SetBody, apakah ini meminta basis data? Apakah saya perlu memanggil metode lain untuk mengatakan 'Saya sudah selesai?'"

Apa yang metode panggilan berantai berkomunikasi ke kode menggunakan Postkelas?

  1. Saya memiliki pengaturan yang rumit
  2. Setiap pemanggilan metode dibangun dari yang sebelumnya

Apakah ini benar ? Tidak. PostKelas tidak memiliki pengaturan yang rumit. Pengaturan judul, tanggal dibuat dan tubuh tidak membangun satu sama lain menuju tujuan akhir yang lebih rumit. Anda telah menumbuk pasak persegi menjadi lubang bundar.

Kekurangan dari metode self-referential chain adalah bahwa Anda berkomunikasi bahwa beberapa panggilan metode diperlukan untuk melakukan sesuatu, dan bahwa setiap panggilan dibangun dari yang terakhir. Jika ini tidak benar, maka metode chaining bisa mengkomunikasikan hal yang salah kepada programmer lain.

Ketika rekan kerja Anda berkata:

Antarmuka yang lancar tidak harus diimplementasikan hanya untuk kenyamanan, tetapi untuk semantik

Mereka benar sekali. Antarmuka yang lancar, atau metode chaining, mengkomunikasikan sesuatu di dalam dan dari dirinya sendiri yang mungkin tidak benar.


Ini mengasumsikan bahwa metode chaining dan konfigurasi kompleks selalu berjalan seiring. Mereka adalah entitas yang berbeda dan kehadiran satu tidak seharusnya membuat Anda menganggap yang lain.
Jack

Ini bukan hanya "konfigurasi yang kompleks," itu juga "panggilan metode selanjutnya membangun yang sebelumnya". Metode chaining memiliki meta komunikasi tentang hal itu yang tidak selalu benar untuk tujuan suatu kelas.
Greg Burghardt

1
Metode selanjutnya memanggil membangun dari yang sebelumnya berbeda dari metode chaining juga, dan saya tidak berpikir bahwa memperlakukan sintaksis metode chaining sebagai komunikasi yang kuat untuk semantik seri urutan-tergantung dari operasi efek samping dapat diandalkan atau berguna. Ini adalah singkatan sintaksis, tidak lebih. Gunakan di tempat yang membuat segalanya lebih pendek dan lebih mudah dibaca.
Jack

1
Saya mengerti Anda berpikir metode chaining terpisah, tapi aku mengatakan bahwa programmer lain yang tidak di dalam kepala Anda dan menggunakan perpustakaan kelas lain yang tidak menerapkan metode chaining untuk alasan ini bisa berakhir membuat asumsi tentang kode Anda yang tidak benar. Perlu diketahui bahwa metode chaining dapat menyiratkan sesuatu yang Anda, pembuat kode, tidak berniat. Kode yang berkomunikasi dengan jelas sama pentingnya dengan kode yang mudah dibaca. Jangan mengorbankan satu untuk yang lain.
Greg Burghardt

1
When an object's methods always return the object, it communicates a couple of things- Saya pikir ini adalah pendapat pribadi; sulit untuk mengklaim bahwa semua orang yang melihat metode dirantai akan menganggap hal yang sama.
Sam Dufel

1

Kelemahan utama adalah hilangnya kejelasan. Contohnya:

x.foo();
x.bar();
x.baz();

Karena tidak satu pun dari pernyataan tersebut yang mengembalikan nilai (atau jika benar, itu diabaikan), mereka hanya dapat berguna jika menghasilkan efek samping. Bandingkan itu dengan:

x.foo()
 .bar()
 .baz();

Pertama, tidak jelas itu bardan bazberoperasi pada objek dengan tipe yang sama x, kecuali jika Anda tahu fakta bahwa xkelas adalah satu-satunya kelas dengan metode tersebut. Bahkan jika itu masalahnya, tidak jelas metode beroperasi x, atau objek baru.

Menyoroti bagian-bagian kode yang memiliki efek samping berguna, karena Anda perlu melacak efek samping tersebut untuk alasan tentang program ini. Anda harus mempertimbangkan potensi hilangnya kejelasan terhadap potensi keuntungan dalam kemudahan menulis kode, tetapi juga mempertimbangkan bahwa kode lebih banyak dibaca daripada yang tertulis.


0

Pertimbangkan semua elemen gaya bahasa pemrograman (sebagai lawan dari bahasa mesin pengkodean tangan), dan itu melemahkan argumen "semantik bukan kenyamanan".

Banyak hal yang kami lakukan sebagai insinyur memberikan kenyamanan di semantik.

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.