Statik yöntemler kullanarak karşı iki ana nedeni vardır:
- Statik yöntemler kullanarak kodu test zordur
- Statik yöntemler kullanarak kodu extend zordur
Diğer bazı yöntem içinde statik bir yöntem çağrısı sahip global bir değişken içe aslında daha kötüdür. PHP, sınıflar yüzden her zaman küresel bir sembol (sınıf adı) güveniyor statik bir yöntem aramak, küresel semboller vardır. Küresel kötü olduğunda bu bir durumdur. Ben Zend Framework bazı bileşeni ile yaklaşım, bu tür sorunları vardı. Nesneleri oluşturmak için statik yöntem çağrıları (fabrikalar) kullanmak sınıfları vardır. Bana özel bir nesne geri almak için bu örneği başka bir fabrika tedarik imkansız oldu. Bu sorunun çözümü ancak örneklerini ve instace yöntemleri kullanın ve programın başında singletons ve benzeri zorlamaktır.
Miško Hevery, Google'da bir Çevik Antrenör olarak çalışan kim, biz nesneyi kullanmak zaman nesne oluşturma zaman ayırmak gerektiğini, ilginç bir teorisi var, ya da daha doğrusu tavsiye ederiz. Yani bir programın yaşam döngüsü ikiye bölünür. Uygulama ve fiili çalışır kesiminde tüm nesne kablolama önemser ilk bölümü (main()
yöntemi diyelim).
Yani yerine sahip:
class HttpClient
{
public function request()
{
return HttpResponse::build();
}
}
Biz oldukça yapmalıyız:
class HttpClient
{
private $httpResponseFactory;
public function __construct($httpResponseFactory)
{
$this->httpResponseFactory = $httpResponseFactory;
}
public function request()
{
return $this->httpResponseFactory->build();
}
}
Ve sonra, dizin / ana sayfasında, biz (bu nesne kablolama adım, ya da program tarafından kullanılacak örnekleri grafik oluşturmak için zamanı) yapardım:
$httpResponseFactory = new HttpResponseFactory;
$httpClient = new HttpClient($httpResponseFactory);
$httpResponse = $httpClient->request();
Ana fikir, sınıfların dışında bağımlılıkları decouple etmektir. Bu şekilde kod çok daha genişletilebilir ve benim için en önemli parçası, test edilebilir. Neden sınanabilir olması daha önemlidir? Ben hep kütüphane kod yazmak istemiyorum, bu yüzden genişletilebilirlik o kadar önemli değil, ama ben üstlenmeden yaptığınızda testability önemlidir çünkü. Her neyse, sınanabilir kodu genellikle genişletilebilir kod verir, bu yüzden gerçekten bir ya-ya da durum değil.
Miško Hevery de (veya sermaye S olmadan) tekiz Singletons arasında net bir ayrım yapar. Fark çok basittir. Düşük bir durumda "s" ile Singletons ana endeksinde / de kablo yürütür. Sen not Singleton deseni uygulamak ve sadece ihtiyacı herhangi bir diğer örneği bu örneği geçmek dikkat etmez, bir sınıfın bir nesne örneğini. Öte yandan, bir sermaye "S" ile Singleton, klasik (anti-) desen bir uygulamasıdır. PHP dünyada çok kullanıma sahip olmadığı kılık temelde küresel bir. Ben bu noktaya kadar birini görmedim. İsterseniz tüm sınıfları tarafından kullanılacak bir tek DB bağlantı gibi bunu yapmak daha iyidir:
$db = new DbConnection;
$users = new UserCollection($db);
$posts = new PostCollection($db);
$comments = new CommentsCollection($db);
Yukarıdaki yaparak biz singleton'ununu var ve biz de testlerde bir mock veya bir taslaktır enjekte etmek için güzel bir yol olduğu açıktır. Bu ünite testleri daha iyi bir tasarım yol nasıl şaşırtıcı bulunuyor. Eğer testler bu kodu kullanmak istiyorum yol hakkında düşünmeye zorlar düşünüyorum ama ne zaman bu anlamda çok yapar.
/**
* An example of a test using PHPUnit. The point is to see how easy it is to
* pass the UserCollection constructor an alternative implementation of
* DbCollection.
*/
class UserCollection extends PHPUnit_Framework_TestCase
{
public function testGetAllComments()
{
$mockedMethods = array('query');
$dbMock = $this->getMock('DbConnection', $mockedMethods);
$dbMock->expects($this->any())
->method('query')
->will($this->returnValue(array('John', 'George')));
$userCollection = new UserCollection($dbMock);
$allUsers = $userCollection->getAll();
$this->assertEquals(array('John', 'George'), $allUsers);
}
}
Ben ilgili alan aynı değeri çapraz örnek olacağını biliyorum ben kullanmak istiyorum (ve PHP 5.3 JavaScript prototip nesnesi taklit etmek için onları kullandım) statik üyeleri tek durumdur. Bu noktada statik bir özellik ve belki statik alıcı / ayarlayıcı yöntemleri bir çift kullanabilirsiniz. Neyse, bir örneği üyesi ile statik üyesi geçersiz için olasılığı eklemek için unutmayın. Örneğin Zend Framework Zend_Db_Table
örneklerini kullanılan DB adaptör sınıfın adını belirtmek için bir statik özelliğini kullanarak edildi. Bu artık alakalı olabilir bu yüzden ben onları kullandım beri süre oldu, ama ben hatırlıyorum nasıl oluyor.
Statik özellikleri ile anlaşma yok Statik yöntemler fonksiyonları olmalıdır. PHP fonksiyonları vardır ve biz bunları kullanmak gerekir.