Bola dunia tidak bisa dihindari.
Ini adalah diskusi lama, tetapi saya masih ingin menambahkan beberapa pemikiran karena saya merindukannya dalam jawaban yang disebutkan di atas. Jawaban-jawaban itu menyederhanakan apa yang terlalu global dan menyajikan solusi yang sama sekali bukan solusi untuk masalah. Masalahnya adalah: apa cara yang tepat untuk menangani variabel global dan penggunaan kata kunci global? Untuk itu pertama-tama kita harus mengkaji dan mendeskripsikan apa itu global.
Lihatlah kode Zend ini - dan harap dipahami bahwa saya tidak menyarankan Zend ditulis dengan buruk:
class DecoratorPluginManager extends AbstractPluginManager
{
/**
* Default set of decorators
*
* @var array
*/
protected $invokableClasses = array(
'htmlcloud' => 'Zend\Tag\Cloud\Decorator\HtmlCloud',
'htmltag' => 'Zend\Tag\Cloud\Decorator\HtmlTag',
'tag' => 'Zend\Tag\Cloud\Decorator\HtmlTag',
);
Ada banyak dependensi yang tidak terlihat di sini. Konstanta itu sebenarnya adalah kelas. Anda juga dapat melihat require_once di beberapa halaman framework ini. Require_once adalah ketergantungan global, sehingga menciptakan ketergantungan eksternal. Itu tidak bisa dihindari untuk kerangka kerja. Bagaimana Anda bisa membuat kelas seperti DecoratorPluginManager tanpa banyak kode eksternal yang bergantung padanya? Itu tidak dapat berfungsi tanpa banyak tambahan. Menggunakan Zend framework, pernahkah Anda mengubah implementasi antarmuka? Sebuah antarmuka sebenarnya bersifat global.
Aplikasi lain yang digunakan secara global adalah Drupal. Mereka sangat memperhatikan desain yang tepat, tetapi seperti kerangka kerja besar lainnya, mereka memiliki banyak ketergantungan eksternal. Lihat global di halaman ini:
/**
* @file
* Initiates a browser-based installation of Drupal.
*/
/**
* Root directory of Drupal installation.
*/
define('DRUPAL_ROOT', getcwd());
/**
* Global flag to indicate that site is in installation mode.
*/
define('MAINTENANCE_MODE', 'install');
// Exit early if running an incompatible PHP version to avoid fatal errors.
if (version_compare(PHP_VERSION, '5.2.4') < 0) {
print 'Your PHP installation is too old. Drupal requires at least PHP 5.2.4. See the <a href="http://drupal.org/requirements">system requirements</a> page for more information.';
exit;
}
// Start the installer.
require_once DRUPAL_ROOT . '/includes/install.core.inc';
install_drupal();
Pernah menulis redirect ke halaman login? Itu mengubah nilai global. (Dan apakah Anda tidak mengatakan 'WTF', yang saya anggap sebagai reaksi yang baik terhadap dokumentasi aplikasi Anda yang buruk.) Masalah dengan global bukanlah bahwa mereka global, Anda membutuhkannya untuk memiliki aplikasi yang berarti. Masalahnya adalah kompleksitas dari keseluruhan aplikasi yang dapat membuatnya menjadi mimpi buruk untuk ditangani. Sesi bersifat global, $ _POST global, DRUPAL_ROOT global, include / install.core.inc 'adalah global yang tidak dapat dimodifikasi. Ada dunia besar di luar fungsi apa pun yang diperlukan agar fungsi tersebut dapat melakukan tugasnya.
Jawaban Gordon salah, karena dia melebih-lebihkan independensi suatu fungsi dan menyebut suatu fungsi sebagai pembohong terlalu menyederhanakan situasi. Fungsi tidak berbohong dan ketika Anda melihat contohnya, fungsi tersebut dirancang dengan tidak benar - contohnya adalah bug. (Ngomong-ngomong, saya setuju dengan kesimpulan ini bahwa seseorang harus memisahkan kode.) Jawaban dari penipuan sebenarnya bukanlah definisi yang tepat dari situasi tersebut. Fungsi selalu berfungsi dalam cakupan yang lebih luas dan contohnya terlalu sederhana. Kita semua akan setuju dengannya bahwa fungsi itu sama sekali tidak berguna, karena mengembalikan konstanta. Fungsi itu bagaimanapun juga merupakan desain yang buruk. Jika Anda ingin menunjukkan bahwa latihan itu buruk, harap berikan contoh yang relevan. Mengganti nama variabel di seluruh aplikasi bukanlah masalah besar jika memiliki IDE (atau alat) yang bagus. Pertanyaannya adalah tentang ruang lingkup variabel, bukan perbedaan ruang lingkup dengan fungsi. Ada waktu yang tepat bagi suatu fungsi untuk menjalankan perannya dalam proses (itulah sebabnya ia dibuat terlebih dahulu) dan pada waktu yang tepat itu dapat memengaruhi fungsi aplikasi secara keseluruhan, karenanya juga bekerja pada variabel global . Jawaban xzyfer adalah pernyataan tanpa argumentasi. Global sama hadirnya dalam aplikasi jika Anda memiliki fungsi prosedural atau desain OOP. Dua cara berikutnya untuk mengubah nilai global pada dasarnya sama: karenanya juga bekerja pada variabel global. Jawaban xzyfer adalah pernyataan tanpa argumentasi. Global sama hadirnya dalam aplikasi jika Anda memiliki fungsi prosedural atau desain OOP. Dua cara berikutnya untuk mengubah nilai global pada dasarnya sama: karenanya juga bekerja pada variabel global. Jawaban xzyfer adalah pernyataan tanpa argumentasi. Global sama hadirnya dalam aplikasi jika Anda memiliki fungsi prosedural atau desain OOP. Dua cara berikutnya untuk mengubah nilai global pada dasarnya sama:
function xzy($var){
global $z;
$z = $var;
}
function setZ($var){
$this->z = $var;
}
Dalam kedua contoh, nilai $ z diubah dalam fungsi tertentu. Dalam kedua cara pemrograman, Anda dapat membuat perubahan tersebut di banyak tempat lain dalam kode. Anda dapat mengatakan bahwa menggunakan global Anda dapat memanggil $ z di mana saja dan mengubahnya di sana. Ya kamu bisa. Tapi maukah kamu? Dan jika dilakukan di tempat-tempat yang tidak tepat, bukankah itu harus disebut bug?
Bob Fanger mengomentari xzyfer.
Haruskah ada yang menggunakan apa saja dan terutama kata kunci 'global'? Tidak, tetapi seperti semua jenis desain, cobalah untuk menganalisis apa itu tergantung dan bergantung padanya. Cobalah untuk mencari tahu kapan itu berubah dan bagaimana itu berubah. Mengubah nilai global seharusnya hanya terjadi dengan variabel yang dapat berubah dengan setiap permintaan / tanggapan. Artinya, hanya untuk variabel yang termasuk dalam aliran fungsional suatu proses, bukan implementasi teknisnya. Pengalihan URL ke halaman login termasuk dalam aliran fungsional suatu proses, kelas implementasi yang digunakan untuk antarmuka ke implementasi teknis. Anda dapat mengubah yang terakhir selama versi aplikasi yang berbeda, tetapi tidak boleh mengubahnya dengan setiap permintaan / tanggapan.
Untuk lebih memahami kapan masalah bekerja dengan global dan kata kunci global dan kapan tidak, saya akan memperkenalkan kalimat berikutnya, yang berasal dari Wim de Bie saat menulis tentang blog: 'Personal yes, private no'. Ketika suatu fungsi mengubah nilai variabel global demi fungsinya sendiri, maka saya akan menyebutnya penggunaan pribadi variabel global dan bug. Tetapi ketika perubahan variabel global dibuat untuk pemrosesan aplikasi yang tepat secara keseluruhan, seperti pengalihan pengguna ke halaman login, maka menurut saya mungkin desainnya bagus, bukan menurut definisi buruk dan tentu saja bukan anti pola.
Dalam retrospeksi terhadap jawaban Gordon, menipu dan xzyfer: mereka semua memiliki 'private yes' (dan bug) sebagai contoh. Itulah mengapa mereka menentang penggunaan global. Saya akan melakukannya juga. Namun, mereka tidak datang dengan contoh 'pribadi ya, tidak pribadi' seperti yang telah saya lakukan dalam jawaban ini beberapa kali.