Küreseller kaçınılmazdır.
Bu eski bir tartışma, ancak yine de bazı düşüncelerimi eklemek istiyorum çünkü yukarıda bahsedilen cevaplarda onları özlüyorum. Bu cevaplar, küreselin ne kadar fazla olduğunu basitleştiriyor ve soruna hiçbir şekilde çözüm olmayan çözümler sunuyor. Sorun şudur: global bir değişkenle başa çıkmanın ve global anahtar kelimesinin kullanımının doğru yolu nedir? Bunun için önce globalin ne olduğunu incelemeli ve tanımlamalıyız.
Bu Zend koduna bir göz atın - ve lütfen Zend'in kötü yazılmış olduğunu önermediğimi anlayın:
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',
);
Burada pek çok görünmez bağımlılık var. Bu sabitler aslında sınıflardır. Bu çerçevenin bazı sayfalarında da require_once görebilirsiniz. Require_once küresel bir bağımlılıktır, dolayısıyla harici bağımlılıklar oluşturur. Bu bir çerçeve için kaçınılmazdır. DecoratorPluginManager gibi bir sınıfı, bağlı olduğu çok fazla harici kod olmadan nasıl oluşturabilirsiniz? Çok fazla ekstra olmadan çalışamaz. Zend çerçevesini kullanarak, bir arayüzün uygulamasını hiç değiştirdiniz mi? Bir arayüz aslında küreseldir.
Dünya çapında kullanılan bir diğer uygulama Drupal'dır. Doğru tasarım konusunda çok endişeliler, ancak tıpkı herhangi bir büyük çerçeve gibi, birçok dış bağımlılıkları var. Bu sayfadaki küresellere bir göz atın:
/**
* @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();
Giriş sayfasına hiç yönlendirme yazdınız mı? Bu küresel bir değeri değiştiriyor. (Ve sonra, uygulamanızın kötü belgelenmesine iyi bir tepki olarak gördüğüm 'WTF' demiyor musunuz?) Küresellerle ilgili sorun, küresel olmaları değil, anlamlı bir uygulamaya sahip olmak için onlara ihtiyacınız var. Sorun, genel uygulamanın karmaşıklığı ve bunun üstesinden gelinmesi bir kabus haline gelmesidir. Oturumlar globaldir, $ _POST globaldir, DRUPAL_ROOT globaldir, include / install.core.inc 'değiştirilemez bir globaldir. Bu işlevin işini yapmasına izin vermek için gereken herhangi bir işlevin dışında büyük bir dünya vardır.
Gordon'un cevabı yanlıştır, çünkü bir fonksiyonun bağımsızlığını geçersiz kılar ve bir fonksiyonu yalancı olarak adlandırmak durumu aşırı basitleştirir. İşlevler yalan söylemez ve onun örneğine baktığınızda işlev yanlış tasarlanmış - örneği bir hata. (Bu arada, kodun ayrıştırılması gerektiği sonucuna katılıyorum.) Deceze'in yanıtı, durumun uygun bir tanımı değildir. Fonksiyonlar her zaman daha geniş bir kapsamda çalışır ve onun örneği çok basittir. Hepimiz, bu fonksiyonun tamamen yararsız olduğu konusunda hemfikir olacağız, çünkü bir sabit döndürüyor. Bu işlev zaten kötü bir tasarım. Uygulamanın kötü olduğunu göstermek istiyorsanız, lütfen ilgili bir örnekle gelin. Bir uygulama boyunca değişkenleri yeniden adlandırmak, iyi bir IDE'ye (veya bir araca) sahip olmak önemli değildir. Soru, işlevle kapsam farkı değil, değişkenin kapsamı ile ilgilidir. Bir işlevin süreçteki rolünü yerine getirmesi için uygun bir zaman vardır (bu nedenle ilk etapta yaratılmıştır) ve bu uygun zamanda uygulamanın bir bütün olarak işleyişini etkileyebilir, dolayısıyla küresel değişkenler üzerinde de çalışabilir. . Xzyfer'in cevabı, tartışmasız bir ifadedir. Prosedürel işlevleriniz veya OOP tasarımınız varsa, küreseller bir uygulamada olduğu gibi mevcuttur. Bir globalin değerini değiştirmenin sonraki iki yolu temelde aynıdır: dolayısıyla küresel değişkenler üzerinde de çalışıyoruz. Xzyfer'in cevabı, tartışmasız bir ifadedir. Prosedürel işlevleriniz veya OOP tasarımınız varsa, küreseller bir uygulamada olduğu gibi mevcuttur. Bir globalin değerini değiştirmenin sonraki iki yolu temelde aynıdır: dolayısıyla küresel değişkenler üzerinde de çalışıyoruz. Xzyfer'in cevabı, tartışmasız bir ifadedir. Prosedürel işlevleriniz veya OOP tasarımınız varsa, küreseller bir uygulamada olduğu gibi mevcuttur. Bir globalin değerini değiştirmenin sonraki iki yolu temelde aynıdır:
function xzy($var){
global $z;
$z = $var;
}
function setZ($var){
$this->z = $var;
}
Her iki durumda da, belirli bir işlev içinde değiştirilen $ z değeri. Her iki programlama yönteminde de, bu değişiklikleri koddaki bir dizi başka yerde yapabilirsiniz. Global kullanarak $ z'yi her yerde arayabileceğinizi ve orada değiştirebileceğinizi söyleyebilirsiniz. Evet yapabilirsin. Ama yapacak mısın? Ve uyumsuz yerlerde yapıldığında, o zaman bir böcek olarak adlandırılmamalı mı?
Bob Fanger, xzyfer hakkında yorum yapıyor.
O halde herhangi biri herhangi bir şeyi ve özellikle 'global' anahtar kelimesini kullanmalı mı? Hayır, ancak herhangi bir tasarım türü gibi, neye bağlı olduğunu ve neye bağlı olduğunu analiz etmeye çalışın. Ne zaman ve nasıl değiştiğini bulmaya çalışın. Global değerlerin değiştirilmesi, yalnızca her istek / yanıtla değişebilen değişkenlerle gerçekleşmelidir. Yani, teknik uygulamasına değil, yalnızca bir sürecin işlevsel akışına ait olan değişkenlere. Bir URL'nin oturum açma sayfasına yönlendirilmesi, bir sürecin işlevsel akışına, teknik uygulamaya yönelik bir arabirim için kullanılan uygulama sınıfına aittir. İkincisini uygulamanın farklı sürümleri sırasında değiştirebilirsiniz, ancak bunları her istek / yanıtla değiştirmemelisiniz.
Ne zaman globallerle ve global anahtar kelimesiyle çalışmanın bir sorun olduğunu daha iyi anlamak için, bloglar hakkında yazarken Wim de Bie'den gelen bir sonraki cümleyi tanıtacağım: 'Kişisel evet, özel hayır'. Bir fonksiyon, kendi işleyişi adına bir global değişkenin değerini değiştirdiğinde, o zaman global bir değişkenin özel kullanımına ve bir hataya diyeceğim. Ancak genel değişkenin değişikliği, uygulamanın bir bütün olarak düzgün bir şekilde işlenmesi için yapıldığında, kullanıcının oturum açma sayfasına yönlendirilmesi gibi, o zaman bana göre muhtemelen iyi bir tasarım, tanımı gereği kötü değil ve kesinlikle bir anti-desen.
Gordon, deceze ve xzyfer'in yanıtlarına geriye dönüp bakıldığında: Hepsinde örnek olarak 'özel evet' (ve böcekler) var. Bu yüzden küresellerin kullanımına karşı çıkıyorlar. Ben de yapardım. Bununla birlikte, bu cevapta birkaç kez yaptığım gibi 'kişisel evet, özel hayır' örnekleri ile gelmiyorlar.