Arti Abstraksi Leaky?


90

Apa arti istilah "Abstraksi Leaky"? (Tolong jelaskan dengan contoh. Saya sering mengalami kesulitan membaca teori belaka.)



14
Anda mungkin ingin membaca artikel asli Joel Spolsky The Law of Leaky Abstractions yang sejauh yang saya tahu adalah asal muasal istilah tersebut.
Daniel Pryden

2
Sebagian besar jawaban dari penipuan yang diusulkan adalah tentang antarmuka yang lancar.
David Thornley

@David: Posting dengan suara terbanyak kedua menjawab apa arti abstraksi bocor, dan dengan contoh yang bagus.
missingfaktor

4
Saat Anda mencari di Google untuk pertanyaan ini 4 tahun kemudian, sulit untuk menebak pos mana yang dulunya menempati peringkat ke-2 dengan suara terbanyak.
John Reynolds

Jawaban:


108

Berikut contoh meatspace :

Mobil memiliki abstraksi untuk pengemudi. Dalam bentuknya yang paling murni, ada setir, akselerator, dan rem. Abstraksi ini menyembunyikan banyak detail tentang apa yang ada di bawah kap: mesin, cam, timing belt, busi, radiator, dll.

Hal yang rapi tentang abstraksi ini adalah kita dapat mengganti bagian implementasi dengan bagian yang lebih baik tanpa melatih kembali pengguna. Katakanlah kita mengganti tutup distributor dengan pengapian elektronik, dan kita mengganti cam tetap dengan cam variabel. Perubahan ini meningkatkan performa tetapi pengguna tetap mengemudi dengan roda dan menggunakan pedal untuk start dan stop.

Ini sebenarnya sangat luar biasa ... seorang yang berusia 16 tahun atau 80 tahun dapat mengoperasikan mesin yang rumit ini tanpa benar-benar mengetahui banyak tentang cara kerjanya di dalam!

Tapi ada bocoran. Transmisinya sedikit bocor. Pada transmisi otomatis Anda bisa merasakan mobil kehilangan tenaga sesaat saat persneling berpindah, sedangkan di CVT Anda merasakan torsi mulus di sepanjang jalan.

Ada kebocoran yang lebih besar juga. Jika Anda menyalakan mesin terlalu cepat, Anda dapat merusaknya. Jika blok mesin terlalu dingin, mobil mungkin tidak dapat distarter atau performanya buruk. Dan jika Anda menghidupkan radio, lampu depan, dan AC secara bersamaan, Anda akan melihat jarak tempuh bahan bakar Anda turun.


8
Terima kasih atas contohnya. Sepertinya tidak ada orang lain yang bisa memberikan penjelasan sederhana.
Sebastian Patten

8
Ini adalah jawaban yang bagus, terutama karena ini menunjukkan sudut pandang pengguna, yang merupakan inti dari versi perangkat lunak.
chad

1
Apa artinya meatspace? Penjelasan orang awam?
brumScouse

1
@brumScouse "meatspace" berarti dunia fisik, offline. Ini digunakan untuk membedakan dengan dunia online, dunia maya. Saya akan mengedit jawaban saya untuk menyertakan tautan ke definisi.
Mark E. Haase

1
Saya suka bagaimana posting ini menunjukkan bahwa "masih ada kebocoran". Ini semua tentang meminimalkannya.
alaboudi

52

Ini berarti bahwa abstraksi Anda memperlihatkan beberapa detail implementasi, atau bahwa Anda perlu mengetahui detail implementasi saat menggunakan abstraksi. Istilah ini dikaitkan dengan Joel Spolsky , sekitar tahun 2002. Lihat artikel wikipedia untuk informasi lebih lanjut.

Contoh klasik adalah pustaka jaringan yang memungkinkan Anda memperlakukan file jarak jauh sebagai file lokal. Pengembang yang menggunakan abstraksi ini harus menyadari bahwa masalah jaringan dapat menyebabkan kegagalan ini dengan cara yang tidak dilakukan oleh file lokal. Anda kemudian perlu mengembangkan kode untuk menangani kesalahan khusus di luar abstraksi yang disediakan oleh pustaka jaringan.


7
@mehaase Saya tidak mengerti betapa pentingnya apakah abstraksi Anda bocor karena desain atau kelalaian. Saya telah memperluas jawaban dengan contoh dan info lebih lanjut dari artikel yang direferensikan sehingga dapat berdiri sendiri. Lebih lanjut, saya tidak berpikir bahwa "abstraksi bocor" harus merendahkan. Bagi saya ini hanya menggambarkan situasi di mana Anda, sebagai pengembang, perlu lebih berhati-hati saat bekerja dengan abstraksi. Desainnya mungkin baik, buruk, atau acuh tak acuh terlepas dari "kebocoran".
tvanfosson

13

Wikipedia memiliki definisi yang cukup bagus untuk ini

Abstraksi bocor mengacu pada abstraksi yang diimplementasikan, dimaksudkan untuk mengurangi (atau menyembunyikan) kompleksitas, di mana detail yang mendasarinya tidak sepenuhnya tersembunyi

Atau dengan kata lain untuk perangkat lunak adalah saat Anda dapat mengamati detail implementasi fitur melalui batasan atau efek samping dalam program.

Contoh cepatnya adalah penutupan C # / VB.Net dan ketidakmampuannya untuk menangkap parameter ref / out. Alasan mereka tidak dapat ditangkap adalah karena detail implementasi tentang bagaimana proses pengangkatan terjadi. Ini bukan untuk mengatakan bahwa ada cara yang lebih baik untuk melakukan ini.


13

Berikut adalah contoh yang akrab bagi pengembang .NET: ASP.NET's Page Kelas mencoba menyembunyikan detail operasi HTTP, terutama pengelolaan data formulir, sehingga pengembang tidak perlu berurusan dengan nilai yang diposting (karena secara otomatis memetakan nilai formulir ke server kontrol).

Tetapi jika Anda berjalan melampaui skenario penggunaan yang paling dasar, Pageabstraksi mulai bocor dan menjadi sulit untuk bekerja dengan halaman kecuali Anda memahami detail implementasi kelas.

Salah satu contoh umum adalah secara dinamis menambahkan kontrol ke halaman - nilai kontrol yang ditambahkan secara dinamis tidak akan dipetakan untuk Anda kecuali Anda menambahkannya pada waktu yang tepat : sebelum mesin yang mendasari memetakan nilai formulir yang masuk ke kontrol yang sesuai. Ketika Anda harus mempelajarinya, abstraksi telah bocor .


Formulir web memiliki dasar bo dalam embernya. Yang lebih buruk adalah bahwa abstraksi terselubung sama dengan bekerja dengan Http seperti Anda bekerja di kotak sarung tangan.
brumScouse

10

Nah, di satu sisi itu adalah hal yang murni teoritis, meski bukan tidak penting.

Kami menggunakan abstraksi untuk membuat segalanya lebih mudah dipahami. Saya dapat beroperasi pada kelas string dalam beberapa bahasa untuk menyembunyikan fakta bahwa saya berurusan dengan serangkaian karakter yang dipesan yang merupakan item individual. Saya berurusan dengan serangkaian karakter yang dipesan untuk menyembunyikan fakta bahwa saya berurusan dengan angka. Saya berurusan dengan angka untuk menyembunyikan fakta bahwa saya berurusan dengan 1 dan 0.

Abstraksi bocor adalah abstraksi yang tidak menyembunyikan detail yang dimaksudkan untuk disembunyikan. Jika memanggil string.Length pada string 5 karakter di Java atau .NET Saya bisa mendapatkan jawaban apa pun dari 5 hingga 10, karena detail implementasi di mana bahasa-bahasa itu memanggil karakter sebenarnya adalah titik data UTF-16 yang dapat mewakili 1 atau 0,5 karakter. Abstraksi telah bocor. Tidak membocorkannya berarti bahwa mencari panjang akan membutuhkan lebih banyak ruang penyimpanan (untuk menyimpan panjang sebenarnya) atau mengubah dari O (1) ke O (n) (untuk mengetahui panjang sebenarnya). Jika saya peduli dengan jawaban yang sebenarnya (seringkali Anda tidak benar-benar), Anda perlu meningkatkan pengetahuan tentang apa yang sebenarnya terjadi.

Kasus yang lebih dapat diperdebatkan terjadi dengan kasus seperti di mana metode atau properti memungkinkan Anda masuk ke bagian dalam, apakah itu kebocoran abstraksi, atau cara yang jelas untuk pindah ke tingkat abstraksi yang lebih rendah, terkadang bisa menjadi masalah yang tidak disetujui orang.


2
Dan Anda bekerja dengan 1 dan 0 untuk menyembunyikan fakta bahwa Anda bekerja dengan elektronik dan fisika (saya tahu, komentar yang sangat terlambat)
Davy8

7

Saya akan terus memberikan contoh dengan menggunakan RPC.

Dalam dunia RPC yang ideal, panggilan prosedur jarak jauh harus terlihat seperti panggilan prosedur lokal (atau begitulah ceritanya). Ini harus benar-benar transparan bagi programmer sehingga ketika mereka menelepon SomeObject.someFunction()mereka tidak tahu apakah SomeObject(atau hanya someFunctiondalam hal ini) disimpan dan dijalankan secara lokal atau disimpan dan dijalankan dari jarak jauh. Menurut teori, ini membuat pemrograman lebih sederhana.

Kenyataannya berbeda karena ada perbedaan BESAR antara melakukan panggilan fungsi lokal (meskipun Anda menggunakan bahasa yang ditafsirkan paling lambat di dunia) dan:

  • menelepon melalui objek proxy
  • membuat serial parameter Anda
  • membuat koneksi jaringan (jika belum dibuat)
  • mentransmisikan data ke proxy jarak jauh
  • meminta proxy jarak jauh memulihkan data dan memanggil fungsi jarak jauh atas nama Anda
  • membuat serialisasi nilai kembali
  • mentransmisikan nilai kembali ke proxy lokal
  • memasang kembali data serial
  • mengembalikan respons dari fungsi jarak jauh

Dalam waktu saja, itu sekitar tiga orde (atau lebih!) Perbedaan besarnya. Tiga + urutan besarnya akan membuat perbedaan besar dalam kinerja yang akan membuat abstraksi Anda dari panggilan prosedur bocor dengan jelas saat pertama kali Anda salah memperlakukan RPC sebagai panggilan fungsi nyata. Selanjutnya panggilan fungsi nyata, kecuali masalah serius dalam kode Anda, akan memiliki sangat sedikit titik kegagalan di luar bug implementasi. Panggilan RPC memiliki semua kemungkinan masalah berikut yang akan diakibatkan sebagai kasus kegagalan yang melebihi dan di atas apa yang Anda harapkan dari panggilan lokal biasa:

  • Anda mungkin tidak dapat membuat instance proxy lokal Anda
  • Anda mungkin tidak dapat membuat proxy jarak jauh Anda
  • proxy mungkin tidak dapat terhubung
  • parameter yang Anda kirim mungkin tidak utuh atau tidak sama sekali
  • nilai kembali yang dikirim jarak jauh mungkin tidak membuatnya utuh atau sama sekali

Jadi sekarang panggilan RPC Anda yang "seperti panggilan fungsi lokal" memiliki keseluruhan kondisi kegagalan tambahan yang tidak perlu Anda hadapi saat melakukan panggilan fungsi lokal. Abstraksi bocor lagi, bahkan lebih keras.

Pada akhirnya RPC adalah abstraksi yang buruk karena bocor seperti saringan di setiap level - saat berhasil dan saat gagal keduanya.


<pimp> Saya lebih suka pendekatan Erlang ini karena tidak mencoba menyembunyikan perbedaan antara pemanggilan fungsi dan mengirim pesan ke proses ke titik di mana keduanya menggunakan sintaks yang sangat berbeda. Dan pengiriman pesan proses jarak jauh sangat terlihat berbeda dari pengiriman proses lokal, meskipun menggunakan sintaks umum yang sama. </pimp>
HANYA PENDAPAT SAYA yang benar

2
Nah, ini satu-satunya respon yang benar-benar memberikan contoh yang baik (pemahaman bacaan, teman-teman), jadi mendapat +1 saya.
Mark E. Haase

4

Contoh dalam contoh banyak-ke-banyak django ORM :

Perhatikan dalam Penggunaan API Contoh bahwa Anda perlu .save () objek Artikel dasar a1 sebelum Anda dapat menambahkan objek Publication ke atribut many-to-many. Dan perhatikan bahwa memperbarui atribut many-to-many akan segera menyimpan ke database yang mendasarinya, sedangkan memperbarui atribut singular tidak tercermin dalam db hingga .save () dipanggil.

Abstraksinya adalah kita mengerjakan grafik objek, di mana atribut nilai tunggal dan atribut multi-nilai hanyalah atribut. Tetapi implementasi sebagai database relasional yang didukung penyimpanan data bocor ... karena sistem integritas RDBS muncul melalui lapisan tipis antarmuka objek.


3

Apa itu abstraksi?

Abstraksi adalah cara menyederhanakan dunia. Artinya Anda tidak perlu khawatir tentang apa yang sebenarnya terjadi di bawah tenda, atau di balik tirai. Artinya ada sesuatu yang bukti bodoh.

Contoh Abstraksi: Kompleksitas Terbang 737/747 "disarikan"

Pesawat adalah bagian mesin yang sangat rumit. Anda memiliki mesin jet, sistem oksigen, sistem kelistrikan, sistem roda pendaratan, dll. Tetapi pilot tidak perlu khawatir tentang seluk-beluk mesin jet..semua itu "disarikan". Ini berarti pilot hanya perlu khawatir tentang menyetir pesawat: kiri ke kiri, dan kanan ke kanan, naik untuk mendapatkan elevasi, dan tekan ke bawah untuk turun.

Cukup sederhana ...... sebenarnya saya bohong: mengontrol setir sedikit lebih rumit. Dalam dunia yang ideal, itulah satu-satunya hal yang harus dikhawatirkan oleh pilot . Tapi ini tidak terjadi dalam kehidupan nyata: jika Anda menerbangkan pesawat seperti monyet, tanpa pemahaman nyata tentang bagaimana pesawat beroperasi, atau detail implementasinya, maka Anda kemungkinan akan menabrak dan membunuh semua orang di dalamnya.

Abstraksi Leaky di 737 Contoh

Pada kenyataannya, seorang pilot memang harus mengkhawatirkan BANYAK hal penting - tidak semuanya telah diabstraksi: pilot harus khawatir tentang kecepatan angin, daya dorong, sudut serang, bahan bakar, ketinggian, masalah cuaca, sudut turun, dan apakah pilot menuju ke arah yang benar. Komputer dapat membantu pilot dalam tugas ini, tetapi tidak semuanya otomatis / sederhana.

Misalnya, jika pilot menarik kolom terlalu keras - pesawat akan mematuhinya, tetapi kemudian pilot akan mengambil risiko menghentikan pesawat, dan sekali terhenti, akan sangat sulit untuk mendapatkan kembali kendali atas kolom tersebut, sebelum jatuh kembali ke tanah .

Dengan kata lain, pilot tidak cukup hanya mengontrol setir saja tanpa mengetahui hal lain ......... tidaaaaak ....... dia harus tahu tentang risiko dan keterbatasan yang mendasari pesawat. sebelum dia menerbangkannya ....... dia harus tahu bagaimana pesawat itu bekerja, dan bagaimana pesawat itu terbang; ia harus mengetahui detail implementasinya ..... ia harus tahu bahwa menarik terlalu keras akan mengakibatkan sebuah stall, atau pendaratan yang terlalu curam akan menghancurkan pesawat.

Hal-hal itu tidak disingkirkan. Banyak hal yang diabstraksi, tetapi tidak semuanya. Pilot hanya perlu mengkhawatirkan kolom kemudi, dan mungkin satu atau dua hal lainnya. Abstraksinya "bocor".

Abstraksi Bocor dalam Kode

...... itu hal yang sama di kode Anda. Jika Anda tidak mengetahui detail implementasi yang mendasari, maka lebih sering daripada tidak, Anda akan menyudutkan diri Anda sendiri.

Berikut adalah contoh dalam pengkodean:

ORM mengaburkan banyak kerumitan dalam menangani kueri basis data, tetapi jika Anda pernah melakukan sesuatu seperti:

User.all.each do |user|
   puts user.name # let's print each user's name
end

Kemudian Anda akan menyadari bahwa itu cara yang bagus untuk menghentikan aplikasi Anda jika Anda memiliki lebih dari beberapa juta pengguna. Tidak semuanya disarikan. Perlu Anda ketahui bahwa menelepon User.alldengan 25 juta pengguna akan meningkatkan penggunaan memori Anda, dan akan menimbulkan masalah. Anda perlu mengetahui beberapa detail yang mendasarinya. Abstraksinya bocor.


0

Fakta bahwa pada titik tertentu , yang akan dipandu oleh skala dan eksekusi Anda, Anda akan diminta untuk memahami detail implementasi kerangka kerja abstraksi Anda untuk memahami mengapa ia berperilaku seperti itu.

Misalnya, pertimbangkan SQLkueri ini :

SELECT id, first_name, last_name, age, subject FROM student_details;

Dan alternatifnya:

SELECT * FROM student_details;

Sekarang, mereka terlihat seperti solusi yang secara logis setara, tetapi kinerja yang pertama lebih baik karena spesifikasi nama kolom individual.

Ini adalah contoh yang sepele tetapi akhirnya kembali ke kutipan Joel Spolsky:

Semua abstraksi non-sepele, sampai taraf tertentu, bocor.

Pada titik tertentu, ketika Anda akan mencapai skala tertentu dalam operasi Anda, Anda akan ingin mengoptimalkan cara kerja DB (SQL) Anda. Untuk melakukannya, Anda perlu mengetahui cara kerja database relasional. Itu disarikan untuk Anda pada awalnya, tapi itu bocor. Anda perlu mempelajarinya di beberapa titik.


-1

Asumsikan, kami memiliki kode berikut di perpustakaan:

Object[] fetchDeviceColorAndModel(String serialNumberOfDevice)
{
    //fetch Device Color and Device Model from DB.
    //create new Object[] and set 0th field with color and 1st field with model value. 
}

Saat konsumen memanggil API, mereka mendapatkan Object []. Konsumen harus memahami bahwa bidang pertama dari larik objek memiliki nilai warna dan bidang kedua adalah nilai model. Di sini abstraksi telah bocor dari pustaka ke kode konsumen.

Salah satu solusinya adalah mengembalikan objek yang merangkum Model dan Warna Perangkat. Konsumen dapat memanggil objek tersebut untuk mendapatkan model dan nilai warna.

DeviceColorAndModel fetchDeviceColorAndModel(String serialNumberOfTheDevice)
{
    //fetch Device Color and Device Model from DB.
    return new DeviceColorAndModel(color, model);
}

-3

Abstraksi yang bocor adalah tentang keadaan enkapsulasi. contoh yang sangat sederhana dari abstraksi bocor:

$currentTime = new DateTime();

$bankAccount1->setLastRefresh($currentTime);
$bankAccount2->setLastRefresh($currentTime);
$currentTime->setTimestamp($aTimestamp);

class BankAccount {
    // ...

    public function setLastRefresh(DateTimeImmutable $lastRefresh)
    {
        $this->lastRefresh = $lastRefresh;
    } }

dan cara yang benar (bukan abstraksi bocor):

class BankAccount
{
    // ...

    public function setLastRefresh(DateTime $lastRefresh)
    {
        $this->lastRefresh = clone $lastRefresh;
    }
}

deskripsi lebih lanjut di sini .

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.