Bagaimana global berbeda dari database?

250

Saya baru saja menemukan pertanyaan lama ini menanyakan apa yang begitu jahat tentang keadaan global, dan jawaban yang terpilih, diterima menegaskan bahwa Anda tidak dapat mempercayai kode apa pun yang bekerja dengan variabel global, karena beberapa kode lain di tempat lain mungkin ikut serta dan memodifikasi nilai dan kemudian Anda tidak tahu apa perilaku kode Anda karena data berbeda! Tetapi ketika saya melihat itu, saya berpikir bahwa itu adalah penjelasan yang sangat lemah, karena bagaimana bedanya dengan bekerja dengan data yang disimpan dalam database?

Ketika program Anda bekerja dengan data dari database, Anda tidak peduli apakah kode lain dalam sistem Anda mengubahnya, atau bahkan jika program yang sama sekali berbeda mengubahnya, dalam hal ini. Anda tidak peduli apa data itu; itulah intinya. Yang penting adalah bahwa kode Anda menangani dengan benar data yang ditemui. (Jelas saya sedang membahas masalah caching yang sering berduri di sini, tapi mari kita abaikan itu untuk saat ini.)

Tetapi jika data yang Anda kerjakan berasal dari sumber eksternal yang kode Anda tidak dapat mengontrolnya, seperti database (atau input pengguna, atau soket jaringan, atau file, dll ...) dan tidak ada yang salah dengan itu, lalu bagaimana data global di dalam kode itu sendiri - yang program Anda memiliki tingkat kontrol yang jauh lebih besar - entah bagaimana hal buruk ketika itu jelas jauh lebih buruk daripada hal-hal normal yang tidak ada yang melihat sebagai masalah?

Mason Wheeler
sumber
117
Sangat menyenangkan melihat anggota veteran sedikit menantang dogma ...
svidgen
10
Dalam suatu aplikasi, Anda biasanya menyediakan sarana untuk mengakses database, artinya ini diteruskan ke fungsi yang ingin mengakses database. Anda tidak melakukan itu dengan variabel global, Anda hanya tahu mereka ada di tangan. Itu perbedaan utama di sana.
Andy
45
Keadaan global seperti memiliki satu basis data dengan satu tabel dengan satu baris dengan tak terhingga banyaknya kolom yang diakses secara bersamaan oleh sejumlah aplikasi yang berubah-ubah.
BevynQ
42
Basis data juga jahat.
Stig Hemmer
27
Sangat menyenangkan untuk "membalikkan" argumen yang Anda buat di sini dan pergi ke arah lain. Sebuah struct yang memiliki pointer ke struct lain secara logis hanya kunci asing di satu baris dari satu tabel yang kunci ke baris lain dari tabel lain. Bagaimana cara bekerja dengan kode apa pun , termasuk daftar yang ditautkan berjalan berbeda dari memanipulasi data dalam database? Jawab: tidak. Pertanyaan: mengapa kita memanipulasi struktur data dalam memori dan struktur data dalam database menggunakan alat yang berbeda? Jawab: Saya benar-benar tidak tahu! Sepertinya kecelakaan sejarah daripada desain yang bagus.
Eric Lippert

Jawaban:

118

Pertama, saya akan mengatakan bahwa jawaban yang Anda tautkan melebih-lebihkan masalah khusus itu dan bahwa kejahatan utama negara global adalah bahwa ia memperkenalkan penggandengan dengan cara yang tidak dapat diprediksi yang dapat membuat sulit untuk mengubah perilaku sistem Anda di masa depan.

Tetapi menyelidiki masalah ini lebih lanjut, ada perbedaan antara keadaan global dalam aplikasi berorientasi objek khas dan negara yang disimpan dalam database. Secara singkat, yang paling penting dari ini adalah:

  • Sistem berorientasi objek memungkinkan penggantian objek dengan kelas objek yang berbeda, asalkan merupakan subtipe dari tipe aslinya. Ini memungkinkan perilaku diubah, bukan hanya data .

  • Keadaan global dalam suatu aplikasi biasanya tidak memberikan jaminan konsistensi yang kuat bahwa database melakukannya - tidak ada transaksi selama Anda melihat keadaan yang konsisten untuk itu, tidak ada pembaruan atom, dll.

Selain itu, kita dapat melihat status basis data sebagai kejahatan yang diperlukan; tidak mungkin untuk menghilangkannya dari sistem kami. Negara global, bagaimanapun, tidak perlu. Kita sepenuhnya bisa menghilangkannya. Jadi meskipun masalah dengan database sama buruknya, kita masih bisa menghilangkan beberapa masalah potensial dan solusi parsial lebih baik daripada tidak ada solusi.

Jules
sumber
44
Saya pikir titik konsistensi sebenarnya adalah alasan utama: Ketika variabel global digunakan dalam kode, biasanya tidak ada yang tahu kapan mereka sebenarnya diinisialisasi. Ketergantungan antara modul sangat tersembunyi di dalam urutan panggilan, dan hal-hal sederhana seperti bertukar dua panggilan dapat menghasilkan bug yang sangat buruk karena tiba-tiba beberapa variabel global tidak diinisialisasi dengan benar lagi ketika pertama kali digunakan. Setidaknya itulah masalah yang saya miliki dengan kode lama yang harus saya tangani, dan yang membuat refactoring menjadi mimpi buruk.
cmaster
24
@DavidHammen Saya sebenarnya telah bekerja pada simulasi keadaan-dunia untuk game online, yang jelas-jelas berada dalam kategori aplikasi yang Anda bicarakan, dan bahkan di sana saya tidak akan (dan tidak) menggunakan negara global untuk itu. Bahkan jika beberapa keuntungan efisiensi dapat dibuat dengan menggunakan negara global, masalahnya adalah bahwa negara global tidak dapat diskalakan . Menjadi sulit untuk digunakan setelah Anda berpindah dari arsitektur single-threaded ke multi-threaded. Itu menjadi tidak efisien ketika Anda pindah ke arsitektur NUMA. Menjadi tidak mungkin ketika Anda pindah ke arsitektur terdistribusi. Makalah yang Anda kutip tanggal dari ...
Jules
24
1993. Masalah-masalah ini kurang menjadi masalah saat itu. Para penulis sedang mengerjakan sistem prosesor tunggal, mensimulasikan interaksi 1.000 objek. Dalam sistem modern Anda mungkin akan menjalankan simulasi semacam itu pada setidaknya sistem dual-core, tetapi sangat mungkin bisa setidaknya 6 core dalam satu sistem. Untuk masalah yang lebih besar lagi, Anda akan menjalankannya di sebuah cluster. Untuk perubahan semacam ini, Anda harus menghindari negara global karena negara global tidak dapat dibagi secara efektif.
Jules
19
Saya pikir menyebut status basis data sebagai "kejahatan yang diperlukan" sedikit berlebihan. Maksudku, sejak kapan negara menjadi jahat? Negara adalah keseluruhan tujuan dari suatu basis data. Negara adalah informasi. Tanpa status, yang Anda miliki hanyalah operator. Apa gunanya operator tanpa sesuatu untuk beroperasi? Keadaan itu harus pergi ke suatu tempat. Pada akhirnya, pemrograman fungsional hanyalah sarana untuk mencapai tujuan dan tanpa negara bermutasi tidak akan ada gunanya melakukan apa pun. Ini seperti tukang roti yang menyebut kue itu jahat - itu tidak jahat. Itulah inti masalahnya.
J ...
5
@DavidHammen "masih ada beberapa objek yang tahu setidaknya sedikit tentang setiap objek dalam game" Belum tentu benar. Teknik utama dalam simulasi terdistribusi modern adalah mengambil keuntungan dari lokalitas dan membuat perkiraan sedemikian rupa sehingga objek yang jauh tidak perlu tahu tentang segala sesuatu yang jauh, hanya data apa yang diberikan kepada mereka oleh pemilik objek yang jauh itu.
JAB
75

Pertama, apa masalah dengan variabel global, berdasarkan jawaban yang diterima untuk pertanyaan yang Anda tautkan?

Sangat singkat, itu membuat keadaan program tidak dapat diprediksi.

Database, sebagian besar waktu, ACID compliant. ACID secara khusus menangani masalah mendasar yang akan membuat penyimpanan data tidak dapat diprediksi atau tidak dapat diandalkan.

Lebih lanjut, keadaan global merusak keterbacaan kode Anda.

Ini karena variabel global ada dalam cakupan yang jauh dari penggunaannya, bahkan mungkin dalam file yang berbeda. Saat menggunakan database, Anda menggunakan kumpulan catatan atau objek ORM yang lokal untuk kode yang Anda baca (atau seharusnya).

Driver database biasanya menyediakan antarmuka yang konsisten dan dapat dipahami untuk mengakses data yang sama terlepas dari domain masalah. Ketika Anda mendapatkan data dari database, program Anda memiliki salinan data. Pembaruan bersifat atomik. Kontras dengan variabel global, di mana banyak utas atau metode dapat beroperasi pada data yang sama tanpa atomisitas kecuali Anda menambahkan sinkronisasi sendiri. Pembaruan data tidak dapat diprediksi dan sulit dilacak. Pembaruan mungkin disisipkan, menyebabkan contoh buku teks standar rawa dari korupsi data multithreaded (mis. Peningkatan yang disisipkan).

Database biasanya memodelkan data yang berbeda dari variabel global untuk memulainya, tetapi menyisihkannya untuk sesaat, database dirancang dari bawah ke atas untuk menjadi penyimpanan data yang sesuai dengan ACID yang mengurangi banyak masalah dengan variabel global.


sumber
4
+1 Apa yang Anda katakan adalah bahwa basis data melakukan transaksi, sehingga memungkinkan untuk membaca dan menulis beberapa bagian dari keadaan global secara atom. Poin bagus, yang hanya dapat dielakkan dengan menggunakan variabel global untuk setiap informasi yang sepenuhnya independen.
l0b0
1
@ l0b0 transaksi adalah mekanisme yang mencapai sebagian besar tujuan ACID, benar. Tetapi antarmuka DB itu sendiri membuat kode lebih jelas dengan membawa data ke lingkup yang lebih lokal. Pikirkan untuk menggunakan JDBC RecordSet dengan blok coba-dengan-sumber daya, atau fungsi ORM yang mendapatkan sepotong data menggunakan panggilan fungsi tunggal. Bandingkan ini dengan mengelola data yang jauh dari kode yang Anda baca di suatu tempat global.
1
Jadi tidak apa-apa menggunakan variabel global jika saya menyalin nilai ke variabel lokal (dengan mutex) di awal fungsi, memodifikasi variabel lokal, dan kemudian menyalin nilai kembali ke variabel global di akhir fungsinya? (... dia bertanya retoris.)
RM
1
@ RM Dia menyebutkan dua poin. Apa yang Anda buang mungkin membahas yang pertama (keadaan program tidak dapat diprediksi), tetapi tidak membahas yang kedua (keterbacaan kode Anda). Bahkan, hal itu dapat membuat keterbacaan program Anda lebih buruk: P.
riwalk
1
@RM Fungsi Anda akan berjalan secara konsisten, ya. Tetapi Anda kemudian akan memiliki pertanyaan apakah sesuatu yang lain telah memodifikasi variabel global, dan modifikasi itu lebih penting daripada apa yang Anda tulis. Database mungkin memiliki masalah yang sama juga, tentu saja.
Graham
45

Saya akan menawarkan beberapa pengamatan:

Ya, basis data adalah keadaan global.

Sebenarnya, ini adalah negara super global, seperti yang Anda tunjukkan. Ini universal! Cakupannya mencakup apa pun atau siapa saja yang terhubung ke database. Dan, saya curiga banyak orang dengan pengalaman bertahun-tahun dapat menceritakan kisah horor tentang bagaimana "hal-hal aneh" dalam data menyebabkan "perilaku tak terduga" dalam satu atau lebih aplikasi yang relevan ...

Salah satu konsekuensi potensial dari penggunaan variabel global adalah bahwa dua "modul" yang berbeda akan menggunakan variabel itu untuk tujuan mereka sendiri yang berbeda. Dan sejauh itu, tabel database tidak berbeda. Itu bisa menjadi korban dari masalah yang sama.

Hmm ... Ini masalahnya:

Jika suatu modul tidak beroperasi secara ekstrinsik dalam beberapa cara, ia tidak melakukan apa-apa.

Modul yang berguna dapat diberikan data atau dapat menemukannya . Dan, itu bisa mengembalikan data atau bisa memodifikasi keadaan. Tetapi, jika itu tidak berinteraksi dengan dunia luar dalam beberapa cara, mungkin juga tidak melakukan apa-apa.

Sekarang, preferensi kami adalah menerima data dan mengembalikan data. Sebagian besar modul hanya lebih mudah untuk ditulis jika mereka dapat ditulis dengan mengabaikan apa yang dilakukan dunia luar. Tetapi pada akhirnya, sesuatu perlu menemukan data dan memodifikasi keadaan global eksternal itu.

Selanjutnya, dalam aplikasi dunia nyata, data ada sehingga dapat dibaca dan diperbarui oleh berbagai operasi. Beberapa masalah dicegah dengan kunci dan transaksi. Tetapi, mencegah operasi-operasi ini saling bertentangan pada prinsipnya , pada akhirnya, hanya melibatkan pemikiran yang cermat. (Dan membuat kesalahan ...)

Tetapi juga, kita umumnya tidak bekerja secara langsung dengan negara global.

Kecuali aplikasi tinggal di lapisan data (dalam SQL atau apa pun), objek modul kami bekerja dengan sebenarnya adalah salinan dari keadaan global bersama. Kita dapat melakukan apa pun yang kita inginkan itu tanpa berdampak pada keadaan bersama aktual.

Dan, dalam kasus di mana kita perlu mengubah negara global itu, dengan asumsi bahwa data yang kita berikan tidak berubah, kita biasanya dapat melakukan penguncian yang sama seperti yang kita lakukan pada global lokal kita.

Dan akhirnya, kami biasanya melakukan hal-hal yang berbeda dengan database daripada yang mungkin kami lakukan dengan global nakal.

Tampilan global yang nakal dan rusak seperti ini:

Int32 counter = 0;

public someMethod() {
  for (counter = 0; counter < whatever; counter++) {
    // do other stuff.
  }
}

public otherMethod() {
  for (counter = 100; counter < whatever; counter--) {
    // do other stuff.
  }
}

Kami hanya tidak menggunakan database untuk hal-hal dalam proses / operasional seperti itu. Dan mungkin sifat database yang lambat dan kenyamanan relatif dari variabel sederhana yang menghalangi kami: Interaksi kami yang lamban dan canggung dengan database hanya menjadikan mereka kandidat yang buruk untuk banyak kesalahan yang secara historis kami lakukan dengan variabel.

svidgen
sumber
3
Cara untuk menjamin (karena kami tidak dapat berasumsi) "bahwa data yang kami berikan tidak berubah" dalam database akan menjadi transaksi.
l0b0
Ya ... itu seharusnya disiratkan dengan "penguncian yang sama."
svidgen
Tapi, sulit untuk berpikir hati-hati di akhir hari.
Ya, basis data memang keadaan global - itulah sebabnya sangat menggoda untuk berbagi data menggunakan sesuatu seperti git atau ipfs.
William Payne
21

Saya tidak setuju dengan klaim mendasar bahwa:

Ketika program Anda bekerja dengan data dari database, Anda tidak peduli apakah kode lain dalam sistem Anda mengubahnya, atau bahkan jika program yang sama sekali berbeda mengubahnya, dalam hal ini.

Pikiran awal saya adalah "Wow. Hanya Wow". Begitu banyak waktu dan upaya yang dihabiskan untuk mencoba menghindari hal ini - dan mencari tahu apa kompromi dan kompromi yang bekerja untuk setiap aplikasi. Mengabaikannya adalah resep bencana.

Tapi saya juga setuju pada tingkat arsitektur. Variabel global bukan hanya keadaan global. Negara global yang dapat diakses dari mana saja secara transparan. Berbeda dengan menggunakan database Anda harus memiliki pegangan untuk itu - (kecuali Anda menyimpan daripada menangani dalam variabel global ....)

Misalnya menggunakan variabel global mungkin terlihat seperti ini

int looks_ok_but_isnt() {
  return global_int++;
}

int somewhere_else() {
  ...
  int v = looks_ok_but_isnt();
  ...
}

Tetapi melakukan hal yang sama dengan database harus lebih eksplisit tentang apa yang dilakukannya

int looks_like_its_using_a_database( MyDB * db ) {
   return db->get_and_increment("v");
}

int somewhere_else( MyBD * db ) { 
   ...
   v = looks_like_its_using_a_database(db);
   ...
}

Database yang satu jelas mucking dengan database. Jika Anda tidak ingin menggunakan database, Anda dapat menggunakan status eksplisit dan tampilannya hampir sama dengan case database.

int looks_like_it_uses_explicit_state( MyState * state ) {
   return state->v++;
}


int somewhere_else( MyState * state ) { 
   ...
   v = looks_like_it_uses_explicit_state(state);
   ...
}

Jadi saya berpendapat menggunakan database jauh lebih seperti menggunakan keadaan eksplisit, daripada menggunakan variabel global.

Michael Anderson
sumber
2
Ya, saya pikir itu menarik ketika OP berkata: " Anda tidak peduli apa datanya; itu intinya " - jika kita tidak peduli, lalu mengapa menyimpannya? Berikut ini sebuah pemikiran: mari kita berhenti menggunakan variabel dan data sama sekali . Itu seharusnya membuat segalanya lebih sederhana. "Hentikan dunia, aku ingin turun!"
1
+1 Utas atau aplikasi berbeda yang menulis dan membaca dari database yang sama merupakan sumber potensial dari sejumlah besar masalah terkenal, itulah sebabnya mengapa harus selalu ada strategi untuk menangani hal ini, baik di tingkat basis data atau aplikasi, atau kedua. Jadi jelas TIDAK benar bahwa Anda (pengembang aplikasi) tidak peduli siapa lagi yang membaca atau menulis dari database.
Andres F.
1
+1 Di samping catatan, jawaban ini cukup menjelaskan apa yang paling saya benci tentang injeksi ketergantungan. Ini menyembunyikan jenis dependensi ini.
jpmc26
@ jpmc26 Saya mungkin menandai kata-kata, tetapi bukankah di atas adalah contoh yang baik tentang bagaimana injeksi dependensi (sebagai lawan dari pencarian global) membantu membuat dependensi eksplisit? Sepertinya saya lebih suka mengambil masalah dengan API tertentu, seperti mungkin keajaiban penjelasan yang digunakan oleh JAX-RS dan Spring.
Emil Lundberg
2
@ EmilLundberg Tidak, masalahnya adalah ketika Anda memiliki hierarki. Ketergantungan injeksi menyembunyikan ketergantungan tingkat yang lebih rendah dari kode di tingkat yang lebih tinggi, sehingga sulit untuk melacak hal-hal yang berinteraksi. Misalnya, jika MakeNewThingbergantung pada MakeNewThingInDbdan kelas controller saya menggunakan MakeNewThing, maka tidak jelas dari kode di controller saya bahwa saya memodifikasi database. Jadi bagaimana jika saya menggunakan kelas lain yang benar-benar melakukan transaksi saya saat ini ke DB? DI membuatnya sangat sulit untuk mengontrol ruang lingkup suatu objek.
jpmc26
18

Poin bahwa satu-satunya alasan variabel global tidak dapat dipercaya karena negara dapat diubah di tempat lain adalah, dalam dirinya sendiri, bukan alasan yang cukup untuk tidak menggunakannya, setuju (itu alasan yang cukup bagus!). Kemungkinan jawabannya terutama menggambarkan penggunaan di mana membatasi akses variabel ke hanya area kode yang bersangkutan akan lebih masuk akal.

Akan tetapi, basis data adalah masalah yang berbeda, karena dirancang untuk tujuan diakses secara "global".

Sebagai contoh:

  • Database biasanya memiliki validasi tipe dan struktur bawaan yang lebih jauh dari bahasa yang mengaksesnya
  • Basis data hampir secara bulat memperbarui berdasarkan transaksi, yang mencegah keadaan tidak konsisten, di mana tidak ada jaminan seperti apa bentuk akhirnya di objek global (kecuali tersembunyi di balik singleton)
  • Struktur basis data paling tidak secara implisit didokumentasikan berdasarkan struktur tabel atau objek, lebih dari aplikasi yang menggunakannya

Yang paling penting, basis data melayani tujuan yang berbeda dari variabel global. Basis data adalah untuk menyimpan dan mencari data terorganisir dalam jumlah besar, di mana variabel global melayani celah khusus (bila dapat dibenarkan).

Jeffrey Sweeney
sumber
1
Hah. Anda mengalahkan saya untuk itu sementara saya setengah jalan menulis jawaban yang hampir identik. :)
Jules
@ Jules jawaban Anda memberikan detail lebih banyak dari sisi aplikasi hal; Simpan saja.
Jeffrey Sweeney
Tetapi, kecuali Anda bergantung sepenuhnya pada prosedur tersimpan untuk akses data, semua struktur itu akan tetap gagal untuk memaksakan bahwa tabel digunakan sebagaimana dimaksud. Atau bahwa operasi dilakukan dalam urutan yang sesuai. Atau kunci (transaksi) dibuat sesuai kebutuhan.
svidgen
Hai, apakah poin 1 dan 3 masih berlaku jika Anda menggunakan bahasa yang diketik statis seperti Java?
Jesvin Jose
@aitchnyu Belum tentu. Maksudnya adalah bahwa basis data dibangun untuk tujuan berbagi data secara andal, di mana variabel global biasanya tidak. Objek yang mengimplementasikan antarmuka self-documenting dalam bahasa yang ketat memiliki tujuan yang berbeda dari bahkan basis data NoSQL yang diketik sekalipun.
Jeffrey Sweeney
10

Tetapi ketika saya melihat itu, saya berpikir bahwa itu adalah penjelasan yang sangat lemah, karena bagaimana bedanya dengan bekerja dengan data yang disimpan dalam database?

Atau berbeda dari bekerja dengan perangkat interaktif, dengan file, dengan memori bersama, dll. Program yang melakukan hal yang persis sama setiap kali dijalankan adalah program yang sangat membosankan dan agak tidak berguna. Jadi ya, itu argumen yang lemah.

Bagi saya, perbedaan yang membuat perbedaan berkaitan dengan variabel global adalah bahwa mereka membentuk jalur komunikasi yang tersembunyi dan tidak terlindungi. Membaca dari keyboard sangat jelas dan terlindungi. Saya harus membuat panggilan fungsi tertentu, dan saya tidak dapat mengakses driver keyboard. Hal yang sama berlaku untuk akses file, memori bersama, dan contoh Anda, basis data. Jelas bagi pembaca kode yang membaca fungsi ini dari keyboard, bahwa fungsi mengakses file, beberapa fungsi lain mengakses memori bersama (dan lebih baik ada perlindungan di sekitar itu), namun beberapa fungsi lain mengakses database.

Dengan variabel global, di sisi lain, itu tidak jelas sama sekali. API mengatakan untuk menelepon foo(this_argument, that_argument). Tidak ada dalam urutan panggilan yang mengatakan variabel global g_DangerWillRobinsonharus diatur ke beberapa nilai tetapi sebelum memanggil foo(atau diperiksa setelah memanggil foo).


Google melarang penggunaan argumen referensi non-const di C ++ terutama karena tidak jelas bagi pembaca kode yang foo(x)akan berubah xkarena itu foomengambil referensi non-konstan sebagai argumen. (Bandingkan dengan C #, yang menentukan bahwa baik definisi fungsi dan situs panggilan harus memenuhi syarat parameter referensi dengan refkata kunci.) Sementara saya tidak setuju dengan standar Google tentang ini, saya mengerti maksud mereka.

Kode ditulis sekali dan dimodifikasi beberapa kali, tetapi jika bagus, kode itu dibaca berkali-kali. Jalur komunikasi yang tersembunyi adalah karma yang sangat buruk. Referensi non-const C ++ mewakili jalur komunikasi kecil yang tersembunyi. API yang bagus atau IDE yang bagus akan menunjukkan kepada saya bahwa "Oh! Ini adalah panggilan dengan referensi." Variabel global adalah jalur komunikasi yang sangat tersembunyi.

David Hammen
sumber
Jawaban Anda lebih masuk akal.
Billal Begueradj
8

Saya pikir penjelasan yang dikutip terlalu menyederhanakan masalah ke titik di mana alasannya menjadi konyol. Tentu saja, keadaan basis data eksternal berkontribusi pada keadaan global. Pertanyaan penting adalah bagaimanaprogram Anda tergantung pada keadaan global (bisa berubah). Jika fungsi pustaka untuk membagi string pada ruang putih akan tergantung pada hasil perantara yang disimpan dalam database, saya akan keberatan dengan desain ini setidaknya sebanyak yang saya keberatan dengan array karakter global yang digunakan untuk tujuan yang sama. Di sisi lain, jika Anda memutuskan bahwa aplikasi Anda tidak memerlukan DBMS yang lengkap untuk menyimpan data bisnis pada saat ini dan struktur nilai kunci dalam memori global akan berfungsi, ini bukan berarti desain yang buruk. Yang penting adalah bahwa - apa pun solusi yang Anda pilih untuk menyimpan data Anda - pilihan ini diisolasi untuk sebagian kecil dari sistem sehingga sebagian besar komponen dapat agnostik terhadap solusi yang dipilih untuk ditempatkan dan diuji unit secara terpisah dan dikerahkan. solusi dapat diubah di lain waktu dengan sedikit usaha.

5gon12eder
sumber
8

Sebagai seorang insinyur perangkat lunak yang bekerja terutama dengan firmware tertanam, saya hampir selalu menggunakan variabel global untuk apa pun yang terjadi di antara modul. Bahkan, ini praktik terbaik untuk disematkan. Mereka ditugaskan secara statis, sehingga tidak ada risiko meniup tumpukan / stack dan tidak ada waktu ekstra yang dibutuhkan untuk alokasi / pembersihan tumpukan pada fungsi masuk / keluar.

Kelemahan dari ini adalah bahwa kita tidak harus mempertimbangkan bagaimana variabel-variabel yang digunakan, dan banyak yang datang ke jenis yang sama pemikiran yang masuk ke dalam database-perselisihan. Setiap baca / tulis variabel tidak sinkron HARUS atom. Jika lebih dari satu tempat dapat menulis variabel, beberapa pemikiran harus memastikan mereka selalu menulis data yang valid, sehingga penulisan sebelumnya tidak diganti secara sewenang-wenang (atau bahwa penggantian sewenang-wenang adalah hal yang aman untuk dilakukan). Jika variabel yang sama dibaca lebih dari sekali, beberapa pemikiran harus mempertimbangkan apa yang terjadi jika variabel mengubah nilai antara membaca, atau salinan variabel harus diambil di awal sehingga pemrosesan dilakukan dengan menggunakan nilai yang konsisten, bahkan jika nilai itu menjadi basi selama pemrosesan.

(Untuk yang terakhir, pada hari pertama kontrak saya bekerja pada sistem penanggulangan pesawat terbang, yang sangat terkait keamanan, tim perangkat lunak mencari laporan bug yang mereka coba cari tahu selama sekitar satu minggu atau lebih. Saya punya cukup waktu untuk mengunduh alat dev dan salinan kodenya. Saya bertanya, "tidak bisakah variabel itu diperbarui antara terbaca dan menyebabkannya?" Tetapi tidak benar-benar mendapatkan jawaban. Hei, apa fungsinya? Lagipula, orang baru tahu? Jadi, sementara mereka masih mendiskusikannya, saya menambahkan kode pelindung untuk membaca variabel secara atom, apakah bangunan lokal, dan pada dasarnya mengatakan "hei teman, coba ini". Cara untuk membuktikan bahwa saya layak mendapatkan nilai kontrak saya :)

Jadi variabel global bukanlah hal yang buruk, tetapi mereka membuat Anda terbuka untuk berbagai masalah jika Anda tidak memikirkannya dengan hati-hati.

Graham
sumber
7

Bergantung pada aspek apa yang Anda nilai, variabel global dan akses basis data mungkin berbeda satu sama lain, tetapi selama kita menilai mereka sebagai dependensi, semuanya sama.

Mari kita pertimbangkan definisi pemrograman fungsional tentang fungsi murni yang menyatakan bahwa itu harus semata-mata bergantung pada parameter yang diperlukan sebagai input, menghasilkan output deterministik. Artinya, mengingat serangkaian argumen yang sama dua kali, itu harus menghasilkan hasil yang sama.

Ketika suatu fungsi tergantung pada variabel global, itu tidak lagi dapat dianggap murni, karena, untuk set atau argumen yang sama, itu dapat menghasilkan output yang berbeda karena nilai variabel global mungkin telah berubah di antara panggilan.

Namun, fungsi masih dapat dilihat sebagai deterministik jika kita menganggap variabel global sebagai bagian dari antarmuka fungsi sebagai argumen lainnya, jadi itu bukan masalah. Masalahnya hanya bahwa ini disembunyikan sampai saat kita dikejutkan oleh perilaku tak terduga dari fungsi yang tampak jelas, lalu baca implementasinya untuk menemukan dependensi tersembunyi .

Bagian ini, momen di mana variabel global menjadi ketergantungan tersembunyi adalah apa yang dianggap jahat oleh kami programmer. Itu membuat kode lebih sulit untuk dipikirkan, sulit untuk memprediksi bagaimana perilakunya, sulit untuk digunakan kembali, sulit untuk diuji dan terutama, itu meningkatkan debug dan memperbaiki waktu ketika masalah terjadi.

Hal yang sama terjadi ketika kita menyembunyikan ketergantungan pada database. Kita dapat memiliki fungsi atau objek yang melakukan panggilan langsung ke permintaan dan perintah basis data, menyembunyikan dependensi ini dan menyebabkan masalah yang sama persis yang disebabkan oleh variabel global; atau kita dapat membuatnya secara eksplisit, yang, pada gilirannya, dianggap sebagai praktik terbaik yang menggunakan banyak nama, seperti pola repositori, penyimpanan data, gateway, dll.

PS: Ada aspek-aspek lain yang penting untuk perbandingan ini, seperti apakah konkurensi terlibat, tetapi poin itu dicakup oleh jawaban lain di sini.

MichelHenrich
sumber
Saya suka Anda mengambil ini dari sudut dependensi.
cbojar
6

Oke, mari kita mulai dari titik sejarah.

Kami berada dalam aplikasi lama, ditulis dalam campuran perakitan dan C. khas Anda. Tidak ada fungsi, hanya prosedur . Saat Anda ingin memberikan argumen atau mengembalikan nilai dari suatu prosedur, Anda menggunakan variabel global. Tidak perlu dikatakan, ini cukup sulit untuk dilacak, dan secara umum, setiap prosedur dapat melakukan apa pun yang diinginkan dengan setiap variabel global. Tidak mengherankan, orang beralih ke argumen yang lewat dan mengembalikan nilai dengan cara yang berbeda segera setelah layak (kecuali itu penting untuk tidak melakukannya - misalnya melihat kode sumber Build Engine (Duke 3D)). Kebencian variabel global terlahir di sini - Anda hanya memiliki sedikit gagasan tentang keadaan global apa yang akan dibaca dan diubah oleh setiap prosedur, dan Anda tidak dapat benar-benar memanggil prosedur sarang dengan aman.

Apakah ini berarti bahwa kebencian variabel global adalah sesuatu dari masa lalu? Tidak terlalu.

Pertama, saya harus menyebutkan bahwa saya telah melihat pendekatan yang sama persis untuk melewati argumen dalam proyek yang sedang saya kerjakan sekarang. Untuk melewati dua contoh jenis referensi dalam C #, dalam proyek yang berusia sekitar 10 tahun. Tidak ada alasan yang tepat untuk melakukannya seperti ini, dan kemungkinan besar lahir dari kultus kargo, atau kesalahpahaman total tentang cara kerja C #.

Poin yang lebih besar adalah bahwa dengan menambahkan variabel global, Anda memperluas cakupan setiap bagian kode yang memiliki akses ke variabel global tersebut. Ingat semua rekomendasi itu seperti "singkatkan metode Anda"? Jika Anda memiliki 600 variabel global (sekali lagi, contoh dunia nyata: /), semua cakupan metode Anda secara implisit diperluas oleh 600 variabel global tersebut, dan tidak ada cara sederhana untuk melacak siapa yang memiliki akses ke apa.

Jika dilakukan salah (dengan cara biasa :)), variabel global mungkin memiliki kopling antara satu sama lain. Tetapi Anda tidak tahu bagaimana mereka digabungkan, dan tidak ada mekanisme untuk memastikan bahwa negara global selalu konsisten. Bahkan jika Anda memperkenalkan bagian-bagian penting untuk mencoba dan menjaga hal-hal tetap konsisten, Anda akan menemukan bahwa itu membandingkan dengan buruk ke database ACID yang tepat:

  • Tidak ada cara untuk mengembalikan sebagian pembaruan, kecuali Anda mempertahankan nilai-nilai lama sebelum "transaksi". Tak perlu dikatakan, pada titik ini, melewati nilai sebagai argumen sudah menang :)
  • Semua orang yang mengakses negara yang sama harus mematuhi proses sinkronisasi yang sama. Tetapi tidak ada cara untuk menegakkan ini - jika Anda lupa mengatur bagian kritis, Anda kacau.
  • Bahkan jika Anda menyinkronkan semua akses dengan benar, mungkin ada panggilan bersarang yang mengakses sebagian yang dimodifikasi. Ini berarti bahwa Anda menemui jalan buntu (jika bagian penting Anda tidak menarik), atau berurusan dengan data yang tidak konsisten (jika mereka berulang).

Apakah mungkin untuk menyelesaikan masalah ini? Tidak juga. Anda perlu enkapsulasi untuk menangani ini, atau disiplin yang sangat ketat. Sulit untuk melakukan hal yang benar, dan itu umumnya bukan resep yang sangat baik untuk sukses dalam pengembangan perangkat lunak :)

Lingkup yang lebih kecil cenderung membuat kode lebih mudah dipikirkan. Variabel global bahkan membuat potongan kode paling sederhana termasuk ruang lingkup yang luas.

Tentu saja, ini tidak berarti bahwa pelingkupan global adalah kejahatan. Ini seharusnya tidak menjadi solusi pertama yang Anda pilih - ini adalah contoh khas "sederhana untuk diterapkan, sulit untuk dipelihara".

Luaan
sumber
Kedengarannya sangat mirip dengan dunia fisik: sangat sulit untuk membalikkan keadaan.
Ini adalah jawaban yang baik, tetapi bisa berdiri pernyataan tesis (bagian TL; DR) di awal.
jpmc26
6

Variabel global adalah alat, dapat digunakan untuk kebaikan dan kejahatan.

Database adalah alat, dapat digunakan untuk kebaikan dan kejahatan.

Seperti dicatat oleh poster aslinya, perbedaannya tidak terlalu besar.

Siswa yang tidak berpengalaman sering berpikir bahwa bug adalah sesuatu yang terjadi pada orang lain. Guru menggunakan "Variabel global adalah kejahatan" sebagai alasan yang disederhanakan untuk menghukum desain yang buruk. Siswa pada umumnya tidak mengerti bahwa hanya karena program 100-line mereka bebas bug tidak berarti bahwa metode yang sama dapat digunakan untuk program 10.000-baris.

Ketika Anda bekerja dengan basis data, Anda tidak bisa begitu saja melarang negara global karena itulah tujuan dari program ini. Alih-alih, Anda mendapatkan panduan detail lainnya seperti ACID dan Normal Forms dan sebagainya.

Jika orang menggunakan pendekatan ACID ke variabel global, mereka tidak akan seburuk itu.

Di sisi lain, jika Anda mendesain database dengan buruk, itu bisa menjadi mimpi buruk.

Stig Hemmer
sumber
3
Klaim siswa pada stackoverflow: Bantu saya! Kode saya sempurna, tetapi tidak berfungsi dengan benar!
David Hammen
"Pendekatan ACID ke variabel global" - lihat referensi di Clojure.
Charles Duffy
@ Davidvidam dan Anda pikir para profesional memiliki otak yang tidak seperti siswa?
Billal Begueradj
@BillalBEGUERADJ - Itulah perbedaan antara profesional dan mahasiswa. Kita tahu bahwa terlepas dari pengalaman bertahun-tahun dan terlepas dari upaya terbaik tinjauan kode, pengujian, dll., Kode kita tidak sempurna.
David Hammen
5

Bagi saya, kejahatan utama adalah Global tidak memiliki perlindungan terhadap masalah konkurensi. Anda dapat menambahkan mekanisme untuk menangani masalah seperti itu dengan Globals, tetapi Anda akan menemukan bahwa semakin banyak masalah konkurensi yang Anda selesaikan, semakin banyak Globals Anda mulai meniru database. Kejahatan sekunder bukanlah kontrak penggunaan.

G DeMasters
sumber
3
Misalnya, errnodalam C.
David Hammen
1
Ini menjelaskan mengapa global dan database tidak sama. Mungkin ada perbedaan lain tetapi posting spesifik Anda menghancurkan konsep sepenuhnya. Jika Anda memberikan contoh kode cepat maka saya yakin Anda akan mendapatkan banyak upvotes. mis. MyFunc () {x = globalVar * 5; // .... Beberapa pemrosesan lainnya; y = globalVar * 34; // Ups, beberapa utas lainnya dapat mengubah globalVar selama Beberapa pemrosesan lainnya dan x dan y menggunakan nilai yang berbeda untuk globalVar dalam perhitungannya, yang hampir pasti tidak akan memberikan hasil yang diinginkan.
Dunk
5

Beberapa jawaban lain mencoba menjelaskan mengapa menggunakan database itu baik. Mereka salah! Basis data adalah keadaan global dan karena itu sama jahatnya dengan singleton atau variabel global. Ini semua salah untuk menggunakan database ketika Anda dapat dengan mudah menggunakan Peta lokal atau Array saja!

Variabel global memungkinkan akses global, yang membawa risiko penyalahgunaan. Variabel global juga memiliki kelebihan. Variabel global secara umum dikatakan sebagai sesuatu yang harus Anda hindari, bukan sesuatu yang seharusnya tidak pernah Anda gunakan. Jika Anda dapat dengan mudah menghindarinya, Anda harus menghindarinya. Tetapi jika manfaatnya melebihi kekurangannya, tentu saja Anda harus menggunakannya! *

Hal yang sama persis ** berlaku untuk database, yang merupakan keadaan global - seperti halnya variabel global. Jika Anda dapat melakukan tanpa mengakses database, dan logika yang dihasilkan melakukan semua yang Anda butuhkan dan sama rumitnya, menggunakan database menambah risiko untuk proyek Anda, tanpa manfaat yang sesuai.

Dalam kehidupan nyata, banyak aplikasi memerlukan desain global, terkadang bahkan kondisi global persisten - itulah sebabnya kami memiliki file, database, dll.


* Pengecualian di sini adalah siswa. Masuk akal untuk melarang siswa menggunakan variabel global sehingga mereka harus mempelajari apa alternatifnya.

** Beberapa jawaban secara keliru mengklaim bahwa basis data entah bagaimana terlindungi lebih baik daripada bentuk-bentuk negara global lainnya (pertanyaannya secara eksplisit tentang keadaan global , bukan hanya variabel global). Itu omong kosong. Perlindungan utama yang ditawarkan dalam skenario basis data adalah dengan konvensi, yang persis sama untuk negara global lainnya. Sebagian besar bahasa juga memungkinkan banyak perlindungan tambahan untuk keadaan global, dalam bentuk const, kelas-kelas yang tidak mengizinkan perubahan status mereka setelah ditetapkan dalam konstruktor, atau pengambil dan setter yang dapat mempertimbangkan informasi utas atau status program ke dalam akun.

Peter
sumber
2

Dalam arti tertentu, perbedaan antara variabel global dan database mirip dengan perbedaan antara anggota pribadi dan publik dari suatu objek (dengan asumsi siapa pun masih menggunakan bidang publik). Jika Anda menganggap keseluruhan program sebagai objek, maka global adalah variabel pribadi, dan basis datanya adalah bidang publik.

Perbedaan utama mereka di sini adalah salah satu tanggung jawab yang diemban.

Ketika Anda menulis objek, diasumsikan bahwa siapa pun yang memelihara metode anggota akan memastikan bidang pribadi tetap berperilaku baik. Tetapi Anda sudah menyerah asumsi tentang keadaan bidang publik dan memperlakukan mereka dengan ekstra hati-hati.

Asumsi yang sama berlaku pada tingkat yang lebih luas untuk basis data global v / s. Juga, bahasa pemrograman / ekosistem menjamin pembatasan akses pada publik v / s publik pada saat yang sama ketika ia memaksakan mereka pada (nonshared memory) basis data global v / s.

Ketika multithreading ikut berperan, konsep private v / s public v / s global v / s database hanyalah perbedaan di sepanjang spektrum.

static int global; // within process memory space
static int dbvar; // mirrors/caches data outside process memory space

class Cls {
    public: static int class_public; // essentially the same as global
    private: static int class_private; // but public to all methods in class

    private: static void method() {
        static int method_private; // but public to all scopes in method
        // ...
        {
            static int scope1_private; // mutex guarded
            int the_only_truly_private_data;
        }
        // ...
        {
            static int scope2_private; // mutex guarded
        }
    }
}
Benito Ciaro
sumber
1

Basis data dapat berupa keadaan global, tetapi tidak harus selalu demikian. Saya tidak setuju dengan asumsi bahwa Anda tidak memiliki kendali. Salah satu cara untuk mengelola itu adalah penguncian dan keamanan. Ini dapat dilakukan pada catatan, tabel atau seluruh database. Pendekatan lain adalah memiliki semacam bidang versi yang akan mencegah perubahan catatan jika datanya basi.

Seperti variabel global, nilai dalam database dapat diubah begitu mereka membuka kunci, tetapi ada banyak cara untuk mengontrol akses (Jangan berikan semua kata sandi pada akun yang diizinkan untuk mengubah data.). Jika Anda memiliki variabel yang memiliki akses terbatas, itu tidak terlalu global.

JeffO
sumber
0

Ada beberapa perbedaan:

  • Nilai basis data dapat dimodifikasi dengan cepat. Nilai global yang diatur dalam kode di sisi lain, tidak dapat diubah kecuali Anda memindahkan aplikasi Anda dan memodifikasi kode Anda. Sebenarnya, ini disengaja. Database adalah untuk nilai-nilai yang mungkin berubah dari waktu ke waktu, tetapi variabel global seharusnya hanya untuk hal-hal yang tidak akan pernah berubah dan ketika mereka tidak berisi data aktual.

  • Nilai basis data (baris, kolom) memiliki konteks dan pemetaan relasional dalam database. Relasi ini dapat dengan mudah diekstraksi dan dianalisis menggunakan alat-alat seperti Jailer (misalnya). Variabel global di sisi lain, sedikit berbeda. Anda dapat menemukan semua penggunaan, tetapi tidak mungkin bagi Anda untuk memberi tahu saya semua cara di mana variabel berinteraksi dengan seluruh dunia Anda.

  • Variabel global lebih cepat . Mendapatkan sesuatu dari basis data memerlukan koneksi basis data untuk dibuat, pilih untuk saya jalankan dan kemudian koneksi basis data harus ditutup. Konversi jenis apa pun yang mungkin Anda perlukan menjadi tambahan. Bandingkan dengan global yang diakses dalam kode Anda.

Ini adalah satu-satunya yang dapat saya pikirkan saat ini, tetapi saya yakin masih ada lagi. Sederhananya, mereka adalah dua hal yang berbeda dan harus digunakan untuk tujuan yang berbeda .

Arnab Datta
sumber
0

Tentu saja global tidak selalu tidak pantas. Mereka ada karena mereka memiliki penggunaan yang sah. Masalah utama dengan global, dan sumber utama peringatan untuk menghindarinya, adalah bahwa kode yang menggunakan global melekat pada satu itu dan hanya satu global.

Misalnya, pertimbangkan server HTTP yang menyimpan nama server.

Jika Anda menyimpan nama server di global, maka proses tidak dapat secara bersamaan menjalankan logika untuk dua nama server yang berbeda. Mungkin desain aslinya tidak pernah mempertimbangkan menjalankan lebih dari satu instance server pada satu waktu, tetapi jika Anda kemudian memutuskan ingin melakukan itu, Anda tidak akan bisa melakukannya jika nama server ada di global.

Sebaliknya, jika nama server ada dalam database, tidak ada masalah. Anda cukup membuat satu instance dari database itu untuk setiap instance dari server HTTP. Karena setiap instance dari server memiliki instance dari database, ia dapat memiliki nama server sendiri.

Jadi keberatan utama terhadap global, hanya ada satu nilai untuk semua kode yang mengakses global itu, tidak berlaku untuk entri basis data. Kode yang sama dapat dengan mudah mengakses instance basis data berbeda yang memiliki nilai berbeda untuk entri tertentu.

David Schwartz
sumber
0

Saya pikir ini adalah pertanyaan yang menarik tetapi sedikit sulit untuk dijawab karena ada dua masalah utama yang sedang digabungkan dengan istilah 'negara global'. Yang pertama adalah konsep 'global coupling'. Buktinya adalah bahwa alternatif yang diberikan untuk negara global adalah injeksi ketergantungan. Masalahnya adalah DI tidak harus menghilangkan negara global. Artinya, sangat mungkin dan umum untuk menyuntikkan dependensi pada negara global. Apa yang DI lakukan adalah menghapus kopling yang datang dengan variabel global dan pola Singleton yang umum digunakan. Selain dari desain yang sedikit kurang jelas, ada sedikit kelemahan untuk menghilangkan jenis sambungan ini dan manfaat dari menghilangkan sambungan meningkat secara eksponensial dengan jumlah ketergantungan pada global tersebut.

Aspek lain dari ini adalah keadaan bersama. Saya tidak yakin apakah ada perbedaan yang sangat jelas antara negara yang dibagikan secara global dan negara yang dibagikan secara umum, tetapi biaya dan manfaatnya jauh lebih bernuansa. Sederhananya ada sistem perangkat lunak yang tak terhitung banyaknya yang membutuhkan keadaan bersama untuk menjadi berguna. Bitcoin, misalnya, adalah cara yang sangat cerdas untuk berbagi keadaan secara global (secara harfiah) dengan cara yang terdesentralisasi. Berbagi keadaan yang bisa berubah dengan baik tanpa membuat kemacetan besar itu sulit tapi bermanfaat. Jadi, jika Anda tidak benar-benar perlu melakukannya, Anda dapat menyederhanakan aplikasi Anda dengan meminimalkan keadaan yang bisa diubah bersama.

Jadi pertanyaan tentang bagaimana database berbeda dari global juga dipisahkan dua aspek ini. Apakah mereka memperkenalkan kopling? Ya, mereka bisa tetapi itu sangat tergantung pada bagaimana aplikasi dirancang dan bagaimana database dirancang. Ada terlalu banyak faktor untuk memiliki satu jawaban apakah database memperkenalkan kopling global tanpa rincian desain. Seperti apakah mereka memperkenalkan berbagi negara, yah, itu semacam titik utama dari basis data. Pertanyaannya adalah apakah mereka melakukannya dengan baik. Sekali lagi, saya pikir ini terlalu rumit untuk dijawab tanpa banyak informasi lain seperti alternatif dan banyak pertukaran lainnya.

JimmyJames
sumber
0

Saya akan memikirkannya sedikit berbeda: "variabel global" seperti perilaku adalah harga yang dibayarkan oleh administrator basis data (DBA) karena merupakan kejahatan yang diperlukan untuk melakukan pekerjaan mereka.

Masalah dengan variabel global, seperti yang ditunjukkan beberapa orang lain, bukan masalah yang arbitrer. Masalahnya adalah penggunaannya membuat perilaku program Anda semakin tidak dapat diprediksi karena semakin sulit untuk menentukan siapa yang menggunakan variabel dan dengan cara apa. Ini adalah masalah besar untuk perangkat lunak modern, karena perangkat lunak modern biasanya diminta untuk melakukan banyak hal yang fleksibel. Ini mungkin melakukan miliaran atau bahkan triliunan manipulasi keadaan kompleks selama menjalankan. Kemampuan untuk membuktikan pernyataan yang benar tentang apa yang akan dilakukan perangkat lunak dalam miliaran atau triliunan operasi itu sangat berharga.

Dalam hal perangkat lunak modern, semua bahasa kami menyediakan alat untuk membantu dalam hal ini, seperti enkapsulasi. Pilihan untuk tidak menggunakannya tidaklah perlu, yang mengarah pada mentalitas "global adalah kejahatan". Di banyak wilayah bidang pengembangan perangkat lunak, satu-satunya orang yang menggunakannya adalah orang yang tidak tahu cara membuat kode dengan lebih baik. Ini berarti mereka tidak hanya masalah langsung, tetapi mereka secara tidak langsung menyarankan pengembang tidak tahu apa yang mereka lakukan. Di wilayah lain, Anda akan mendapati bahwa global benar-benar normal (perangkat lunak tertanam, khususnya, mencintai global, sebagian karena mereka bekerja dengan baik dengan ISR). Namun, di tengah banyak pengembang perangkat lunak di luar sana, mereka adalah suara minoritas, jadi satu-satunya suara yang Anda dengar adalah "global adalah kejahatan."

Pengembangan basis data adalah salah satu situasi suara minoritas itu. Alat yang diperlukan untuk melakukan pekerjaan DBA sangat kuat, dan teorinya tidak berakar pada enkapsulasi. Untuk mendapatkan setiap kelemahan kinerja dari basis data mereka, mereka membutuhkan akses penuh tanpa batas ke semuanya, mirip dengan global. Gunakan salah satu dari database 100 juta baris (atau lebih!) Monsterous mereka, dan Anda akan menghargai mengapa mereka tidak membiarkan mesin DB mereka menahan pukulan.

Mereka membayar harga untuk itu, harga sayang. DBA terpaksa hampir patologis dengan perhatian mereka terhadap detail, karena alat mereka tidak melindunginya. Yang terbaik yang mereka miliki dalam hal perlindungan adalah ASAM atau kunci asing. Mereka yang tidak patologis menemukan diri mereka dengan kekacauan tabel yang benar-benar tidak dapat digunakan, atau bahkan korup.

Tidak jarang memiliki paket perangkat lunak 100 ribu baris. Secara teori, garis apa pun dalam perangkat lunak dapat memengaruhi global mana pun pada titik waktu mana pun. Di DBA, Anda tidak pernah menemukan 100 ribu kueri berbeda yang dapat memodifikasi database. Itu tidak masuk akal untuk dipertahankan dengan memperhatikan detail yang dibutuhkan untuk melindungi Anda dari diri sendiri. Jika DBA memiliki sesuatu yang besar seperti itu, mereka akan dengan sengaja merangkum basis data mereka menggunakan pengakses, menghindari masalah "global like", dan kemudian melakukan sebanyak mungkin pekerjaan melalui mekanisme "aman" itu. Jadi, ketika push datang untuk mendorong, bahkan orang-orang database menghindari global. Mereka hanya datang dengan banyak bahaya, dan ada alternatif yang sama kuatnya, tetapi tidak sama berbahayanya.

Apakah Anda lebih suka berjalan-jalan di atas pecahan kaca, atau di trotoar yang tersapu dengan baik, jika semua hal lain sama? Ya, Anda bisa berjalan di atas pecahan kaca. Ya, beberapa orang bahkan mencari nafkah dengan melakukannya. Tapi tetap saja, biarkan saja mereka menyapu trotoar dan melanjutkan!

Cort Ammon
sumber
0

Saya pikir premisnya salah. Tidak ada alasan database perlu menjadi "keadaan global" daripada objek konteks (sangat besar). Jika Anda mengikat ke basis data tertentu yang digunakan kode Anda melalui variabel global atau parameter koneksi basis data global tetap, itu tidak berbeda, dan tidak lebih jahat, daripada keadaan global lainnya. Di sisi lain, jika Anda benar-benar membagikan objek konteks untuk koneksi database, itu hanya keadaan kontekstual yang besar (& banyak digunakan), bukan keadaan global.

Mengukur perbedaannya mudah: dapatkah Anda menjalankan dua contoh logika program Anda, masing-masing menggunakan basis datanya sendiri, dalam satu program / proses tanpa membuat perubahan invasif pada kode? Jika demikian, database Anda sebenarnya bukan "negara global".

R ..
sumber
-2

Global bukanlah kejahatan; mereka hanyalah alat. MISUSE dari global adalah masalah, seperti penyalahgunaan fitur pemrograman lainnya.

Rekomendasi umum saya adalah bahwa global hanya boleh digunakan dalam situasi yang dipahami dan dipikirkan dengan baik, di mana solusi lain kurang optimal. Yang paling penting, Anda ingin memastikan bahwa Anda telah mendokumentasikan dengan baik di mana nilai global tersebut dapat dimodifikasi, dan jika Anda menjalankan multithreaded, bahwa Anda memastikan bahwa global dan global yang saling tergantung akses mengakses dengan cara yang transaksional.

Byron Jones
sumber
Akankah beberapa downvoters keberatan menjelaskan downvotes Anda? Tampaknya tidak sopan untuk melakukan downvote tanpa penjelasan.
Byron Jones
-2

Pola Read-Only, dan menganggap data Anda tidak mutakhir saat Anda mencetaknya. Antrian menulis atau menangani konflik dengan cara lain. Selamat datang di neraka iblis, Anda menggunakan db global.

Vince
sumber