PHP5'ten itibaren, arayüzlerin dile eklendiğini fark ettim. Ancak, PHP çok gevşek bir şekilde yazıldığından, arayüzleri kullanmanın yararlarının çoğunun kaybolduğu görülmektedir. Neden bu dilde var?
PHP5'ten itibaren, arayüzlerin dile eklendiğini fark ettim. Ancak, PHP çok gevşek bir şekilde yazıldığından, arayüzleri kullanmanın yararlarının çoğunun kaybolduğu görülmektedir. Neden bu dilde var?
Yanıtlar:
PHP'deki arayüzlerin temel avantajı, sınıfların çoklu arayüzleri uygulayabilmesidir. Bu, bazı işlevleri paylaşan ancak mutlaka bir üst sınıfı paylaşmayan sınıfları gruplandırmanıza izin verir. Bazı örnekler, sınıfın özelliklerine belirli bir şekilde önbellekleme, çıktı veya erişme içerebilir.
Kodunuzda, bir sınıfın sınıf adını kontrol etmek yerine belirli bir arayüz uygulayıp uygulamadığını kontrol edebilirsiniz. Ardından, yeni sınıflar eklendiğinde kodunuz çalışmaya devam eder.
PHP, çeşitli durumlarda kullanışlı olabilecek bazı önceden tanımlanmış arayüzler sunar: http://php.net/manual/tr/reserved.interfaces.php .
EDIT - Bir örnek ekleme
MyInterface adında bir arabiriminiz varsa ve bazı işlevleri paylaşabilen veya paylaşamayacağınız farklı sınıflardan birden çok nesneyle çalışıyorsanız, arabirimler şöyle bir şey yapmanıza izin verir:
// Assume $objects is an array of instances of various classes
foreach($objects as $obj) {
if($obj instanceof MyInterface) {
$obj->a();
$obj->b();
$obj->c();
}
}
PHP gevşek bir şekilde yazılmıştır, ancak yöntem parametreleri gibi şeyler hakkında kesinlikle yazılabilir.
Aşağıdaki örneği düşünün:
interface Car { function go(); }
class Porsche { function go() {} }
function drive(Car $car) {}
$porsche = new Porsche();
drive($porsche);
Yukarıdaki kod çıktı verecek:
Drive () öğesine iletilen bağımsız değişken 1, verilen Porsche örneğinin Car arabirimini uygulamalıdır.
null
Yine de parametre için varsayılan bir değere sahip olabilirsiniz .
drive
gerektirirse Car
, o zaman geçme null
zaten çok yardımcı olmaz ...
function addView($name, Template $template, SecurityMode $securityMode = null, $methodName = null);
Bir $methodName
ama hayır olabilir $securityMode
.
Arayüzler, açık-kapalı prensibi uygulamanıza, gevşek bir şekilde bağlı kod tabanını korumanıza ve en iyi OOP tasarım modellerinin çoğunu uygulamanıza izin verir.
Örneğin, bir sınıf başka bir sınıfı argüman olarak kabul ederse:
class A {
public function __construct(B $class_b) {
// use class b
$class_b->run();
}
}
A ve B sınıfı artık sıkı bir bağlantıya sahip ve A sınıfı, B hariç başka hiçbir sınıfı kullanamaz.
Diyelim ki A sınıfı, run () yöntemine sahip tüm sınıf türlerini kullanabilmenizi istiyor. Bu temelde (ama tam değil) COMMAND tasarım desenidir. Çözmek için, bunun yerine somut bir sınıf yerine bir arayüz kullanarak ipucu yazın. B, bu arayüzü uygularlar ve A sınıfı için bir argüman olarak kabul edilirler.
Bu kodlama türü, çoğu OOP tasarım modelinde kullanılır ve daha sonraki bir zamanda MUCH'nin kod değişikliklerini kolaylaştırmasını sağlar. Bunlar, AGILE programlamasının temellerinin bir parçasıdır.
@pjskeptic iyi bir cevaba sahip , @Kamil Tomšík bu cevaba iyi bir yorum yaptı.
PHP gibi dinamik olarak yazılmış dillerle ilgili en iyi şey, nesneler üzerinde yöntemleri kullanmaya çalışabileceğiniz ve yöntem olmadığı sürece size çığlık atmayacak olmanızdır.
PHP gibi dinamik olarak yazılmış dillerle ilgili sorun, nesneler üzerinde yöntemleri kullanmaya çalışabileceğiniz ve yöntem orada olmadığı zaman size çığlık atacak olmasıdır.
Arabirimler, bilinmeyen bir nesneye yöntem çağırmanın ve yöntemlerin orada olduklarından emin olmanın uygun bir yolunu ekler (mutlaka doğru olmaları ya da işe yaramaları gerekmez). Bir dilin gerekli bir parçası değil, fakat kodlamayı daha uygun hale getiriyor. Güçlü yazılmış OOP geliştiricilerinin, daha sonra farklı bir PHP geliştiricisi tarafından yazılmış, gevşek yazılmış bir PHP kodu ile birlikte çalışabilecekleri güçlü bir şekilde yazılmış PHP kodu yazmalarını sağlar.
Gibi bir işlev:
foo( IBar $bar )
{
$baz = $bar->baz();
...
}
şundan daha uygundur:
foo( $bar )
{
if ( method_exists( $bar, 'baz' ) )
{
$baz = $bar->baz();
}
else
{
throw new Exception('OMGWTF NO BAZ IN BAR!');
}
...
}
ve IMHO basit, okunabilir kod daha iyi koddur.
Ördek yazarsanız, aslında ördek yazma yaptığınızda, herhangi bir tür ipucu kullanan kütüphanelerle / çerçeveyle çalışmak oldukça can sıkıcıdır.
Bu, her türlü dinamik meta programlama için de geçerlidir (sihirli yöntemler).
PHP gevşek veya güçlü değil , dinamik olarak yazılmıştır .
Arayüzler hakkında, kendinize sormanız gereken ilk şey şudur: Arayüzlerin faydalarının çoğu nedir?
OOP'de arayüzler sadece tiplerle değil davranışlarla da ilgilidir.
PHP ayrıca bir tür ipucu özelliğine sahip olduğundan , arabirimleri tıpkı Java gibi saf bir oo dilinde olduğu gibi kullanabilirsiniz.
interface File
{
public function getLines();
}
CSVFile implements File
{
public function getLines()
{}
}
XMLFile implements File
{
public function getLines()
{}
}
JSONFile implements File
{
public function getLines()
{}
}
class FileReader
{
public function read(File $file)
{
foreach($file->getLines() as $line)
{
// do something
}
}
}
PHP arabirim uygulamasıyla, PHPUnit kullanarak soyut sınıflar için alay yaratabilirsiniz - ve bu bir özellik cehennemidir:
public function testSomething()
{
$mock = $this->getMockForAbstractClass('File');
$mock->expects($this->once())
->method('getLines')
->will($this->returnValue(array()));
// do your assertions
}
Dolayısıyla, temelde, biri arayüz olan dil özelliklerini kullanarak PHP'de SOLID uyumlu bir uygulamaya sahip olabilirsiniz .
Arayüzler, bağımlılık enjeksiyonunda betondan çok daha fazla faydalıdır. Bir barebones örneği olarak:
interface Istore {
public function save();
}
class Article_DB implements Istore
{
public function save($data)
{
// do save to format needed.
}
}
class Article
{
private $content;
public function content($content)
{
$this->content = $content;
}
public function save(Istore $store)
{
$store->save($this->content);
}
}
$article = new Article();
$article->content('Some content');
$store = new Article_DB();
$article->save($store);
Şimdi ihtiyaçlarınız değişirse ve bir pdf'e kaydetmek istiyorsanız, söyleyin. Makale sınıfını kirletmek yerine, bu amaç için yeni bir sınıf oluşturabilirsiniz.
class Article_PDF implements Istore
{
public function save($data)
{
// do save to format needed.
}
}
$article = new Article();
$article->content('Some content');
$store = new Article_PDF();
$article->save($store);
Makale sınıfının artık kaydetmek için kullandığı sınıfların Istore arabirimini uygulaması gereken bir sözleşmesi var. Nerede ve nasıl koruduğu umrunda değil.
Arayüzü uygulayan "Sahte" gerçek nesneleri sağlayabilirsiniz. Daha sonra gerçek sunucular, dosya sistemleri, soketler, veritabanları vb. Gerektirmeden kodunuzun bir bölümünü test edebilirsiniz.
Pek çok insan muhtemelen bu şekilde cevap verdiğim için benden nefret edecek, ancak yazım sorunlarınızın çözümü PHP ile kolayca düzeltilebilir. Evet PHP gevşek bir şekilde yazılmıştır, bu nedenle türler varsayılan olarak varsayılır, bu da özellikle onunla en çok sorun olan karşılaştırma işlemlerinde bazı sorunlara neden olabilir. Olduğu söyleniyor, PHP, herhangi bir şekilde yazılmış bir dil kadar katı olabilir, kullanmanız gereken türün içine kullanıyorsanız, sonra da bitsel karşılaştırma işleçlerini kullanın. İşte ne dediğimi düşünebilecek en kolay örnek:
$ myVar = (int) 0; $ myOtherVar = '0';
Karşılaştırma ($ myVar == $ myVar) eşittir (bool) doğru
ancak karşılaştırma ($ myVar === $ myVar), herhangi bir "yazılan" karşılaştırma gibi (bool) eşit olur
Gerçekten sadece geliştiricilerin bu gibi şeyleri tartışmayı bırakmalarını diliyorum, PHP'nin çalışma biçiminde bir sorun varsa ya java'da programa girip yaşayabilir ve yaşayabilir ya da istediğinizi yapacak şekilde kullanabilirsiniz. Bu konuda ısırgan olmanın senin için ne önemi var ki? Bütün gün uğraşmak için bahane mi veriyorsun? Başka birinden daha mı iyi görünüyorsun? Bir başkasının kötü görünmesini isteme konusunda kendin hakkında çok fazla şey hissetmen harika ama gerçekte senin tercihin ve kimseye olan inancını zorlamak, onları üç şeye neden olmaktan hoşlanmadıkları bir şekilde kodlamalarını sağlıyor:
1) Yolunuzu kodlayacaklar ancak standartlarınıza göre "dağınık" olacaklar (bir java programcısının ilk PHP programını ya da tam tersini oluşturduğunu hiç gördünüz mü? Bu, metodolojisini değiştirirken ya da daha da kötüsüyle aynı şekilde olacak).
2) Sızacak başka bir şey bulacaksın
3) Üretmeleri muhtemelen daha uzun sürecektir. Ve belki de kısa vadede daha iyi görünmenizi sağlayacaktır, ancak takımın bunun için daha kötü görünmesi gerekir (bir başkasından daha yavaş kod yazabileceğinizi unutmayın ve takım makul bir süre zarfında teslim edilebildiği sürece bu mutlaka kötü değildir), ama alışkanlıklarınızı tipik olarak biraz daha hızlı performans gösteren birine zorlamak, tüm takımınızın yavaşlamasını sağlayarak son derece zorlu bir iş akışında daha kötü görünmesini sağlayabilir.
İşlemsel PHP kodu yazmayı kişisel olarak tercih ediyorum, ancak birkaç farklı dilde OOP kullanarak tam programlar yazabiliyor ve yazabiliyorum. Olduğu söyleniyor, iyi OOP kodu ve kötü OOP kodu, iyi prosedür kodu ve bu konuda kötü prosedür kodu görmüştüm ... Gerçekten uygulama ile ilgisi yok, ama kullandığın alışkanlıklarla ve hatta bir çok şey benim yorumlanmış hislerim ... bu, bu geliştiriciler hakkında kötü konuşacağım ya da "benim için en iyisi" olan övünmeyeceğimi söyleyeceğim anlamına gelmiyor BS, benim için doğru ve çalıştığım şirket güzel işimden memnun ve bununla gurur duyuyorum. Bir standardın oluşturulmasının gerekçeleri var ama seçtiğiniz standarda dahil ettiğiniz şey ÇOK önemli ... Bunu göğsümden almama izin verdiğiniz için teşekkür ederiz. İyi günler.
Örnekler: Verilerinizi önbelleğe almanız gerekir. Nasıl? Önbellekleme için bir sürü farklı motor var, hangisi en iyisi? Bazı ICacheDriver arabirimine sahip, anahtar, elde, koy, temizle vb. Gibi bir dizi yöntem içeren soyut bir katmana sahip olmanız kimin umrunda, sadece mevcut projede ihtiyacınız olanı uygulayın ve bir başkasına ihtiyacınız olduğunda değiştirin. Veya toString'in basit kullanımı. Farklı gösterilebilir nesneler var. Siz sadece Stringable arayüzünü uygularsınız (bu, toString metodunu [PHP'de böyle bir arayüz yoktur, fakat örneğin]) ve sadece tüm nesneniz üzerinde (string) $ obj ile etkileşime girersiniz. Switch (true) yerine yapmanız gereken tek şey var {case $ obj isntanceof A1: "do 1"; break; ...}
Basit. Yani "Neden?" Sorusu yok. "Nasıl daha iyi kullanılır?" Var. ;-) İyi şanslar.
Tahminimce.
PHP birçok giriş seviyesi programcısı tarafından kullanılır , giriş seviyesi programcıları üniversitede java öğretilir .
Programlama 101 derslerinden sonra Zend'i dırdırmaya başlıyorlar, java özelliklerini istiyorlar çünkü kendilerine göre düşünme (ya da ördek yazmayı anlama) düşüncesi zor, çünkü sadece 20 yaşına geldin.
Zend pragmatiktir, özelliği, her yerde oldukları gibi yapmaktan başka bir özellik eklemek kolaydır .
Bu da onları terk etmek yerine daha fazla kullanıcı satın alıyor , bu yüzden iyi olmalı.
Bu sürecin başka bir örneği? .NET ve Java kurslarından yeni çıkanlar , aynı zamanda Zend, Zend Framework'ü açana kadar Hazırlık Sınıfları Çerçeveleri'ni de istiyor . Bu daha da fazla kullanıcı alır. Ve sürekli ve ...
(PHP ekibinin yıllar boyunca mücadele ettiği bilinen tek dil özelliği goto
)
PHP12
muhtemelen dünyadaki tüm sözdizimi özelliklerine sahip olacak (umarım bir soyutlama katmanı çalışma zamanı, zor, perl'i öldüren şey bu olmaz), işlevsel ve veri türü paradigmalara göz kırpıyor ve hala yok goto
.