PHP neden arayüze sahiptir?


35

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?


5
Bence doğru soru, neden olmasın?
Alberto Fernández

5
Çünkü herhangi bir fayda sunmuyor gibi görünüyorlar, peki neden bunları dahil etmelisiniz?
GSto

4
@HorusKol ve uygulanmadan önce kullanılmamışlardı, bu yüzden nasıl kullanıldıklarını ve bir önceki versiyonun nasıl kullanıldığını görebiliyordunuz. Ayrıca, kullanımlarının bir şekilde yararlı olduklarını söylemek için bir gelişme olduğu iddiasını da desteklemelisiniz.
Rein Henrich,

6
@HorusKol Hiç aldatıcı değil. Çekiç değerinin değerini göstermek kolaydır. Bu soru birisinden PHP arayüzlerinin değer önerisini göstermesini, sadece tartışmacı bir şekilde değerli olduklarını beyan etmesini istemektir.
Rein Henrichs

3
Ve arayüzlerin sadece yazmadan ibaret olmadığını unutmayın. Arayüz, uygulayıcı bir sınıfın ortaya koyduğu yöntemleri içermesi gerektiğini belirten bir sözleşmedir . Eklenti motorları gibi şeyler için kullanışlıdır.
Michael,

Yanıtlar:


30

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();
   }
}

23
Başka bir deyişle: "Dinamik-yazılan dillerin tüm faydalarını tamamen görmezden gelebilirsiniz"
Kamil Tomšík

11
@Kamil, daha fazla dezavantaj yaşamadan statik yazmanın faydalarından yararlanabildiğini düşünüyorum.
Karl Bielefeldt

9
ciddi misin? örneği? if-then-if-then-if-o zaman-her zaman, tanıdık gelmiyor mu? ah, evet, prosedürel programlama.
Kamil Tomšík

23
@Kamil Tomšík Beceriksizce kullananlardan ziyade PHP dilinde başka bir hakaret. PHP, nesne yönelimli programlama için tüm araçlara sahiptir. Bunları kullanıp kullanmamanız programlayıcıya bağlıdır. Ayrıca, kendi başına prosedürel programlamada hiçbir sorun yoktur.
Lotus Notes

18
@Kamil - ne kadar garip, yorumunuzu okuduğunuzda, OOP'da if'ler olmadığı ve bir şekilde, sihirli bir şekilde - işlerin işe yarayacağı sonucuna varılabilir. Vay.
Michael JV

23

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.


1
Tabii, çok kötü. nullYine de parametre için varsayılan bir değere sahip olabilirsiniz .
Emanuil Rusev

5
Ama eğer bir drivegerektirirse Car, o zaman geçme nullzaten çok yardımcı olmaz ...
HorusKol

7
Asla boş vermeyin. Bir "Özel Durum" nesnesi kullanın (Martin Fowler'in açıklaması için Google).
Martin Blore

2
@Renesis Varsayılan değeri null değerine ayarlarsanız, null türünü ipucu yöntemlere geçirebilirsiniz. (CAR $ car = null) bu yöntemi null ile argüman olarak çağırmanıza izin verir. Ancak bu oldukça saçma bir uygulama olacaktır. Neden yeryüzünde bunu yapabilmek istiyorsun?
dqhendricks

2
Somut örnek: function addView($name, Template $template, SecurityMode $securityMode = null, $methodName = null);Bir $methodNameama hayır olabilir $securityMode.
Nicole,

7

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.


1
Veya B
Mez'teki

7

@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.


1
Bunun yerine, sadece yöntemi kontrol edip kilitlemeyin ve birisi işlevinizi yanlış verilerle çağırdığında kilitleyin ve yazdırın. Birisi işlevini yanlış kullanıyorsa, bu senin sorunun değil.
Raynos

hayır - tam olarak - örneğin, proxy, adaptör, dekoratör vb. gibi dinamik bir “ördek” i geçmek isteyen herkes için kabus.
Kamil Tomšík

1
@Kamil? Nasıl yani. Proxy, bu fonksiyonla kullanılmasına izin vermek için arayüzü uygulamayan bir şey için bir sarmalayıcı sınıfı olacaktır.
tylermac

@ tylermac dinamik proxy __call () kullanarak - ve __call buradaki tek yöntemse, basitçe IBar uygulayamaz, yani foo'ya geçemezsiniz (IBar $ bar)
Kamil Tomšík

5

Ö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).


3

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 .


0

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.


-1

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.


-3

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.


-4
  1. Arayüzler OOP paradigmasının bir parçasıdır. Bu nedenle, nesne yönelimli parçalar veya sisteminiz yapmaya çalıştığınızda çoğu zaman çok kullanışlıdır.
  2. Yani. Neden olmasın? ;-)

Ö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.


-5

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)


Vizyonumda, PHP12muhtemelen 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.
ZJR

“Zor, sadece 20 yaşınızdayken” Yaşın, bu kavramlardan herhangi birini anlamakla nasıl bir ilgisi olabilir?
Evicatos

@Evicatos lise öğrencilerine program sıralama programı, ancak genellikle kötü öğretmenleri, zayıf isimlendirme kuralları ve sürdürülemez blobları var. Onlar programı öğrenmek sağ üniversiteye başlamadan ederken, o gidiş almak için birkaç yıl sürer. Sonra, o ilk yıllarda öğretildikleri zor yazılmış, endüstri tarafından kutsanmış, akademi olarak kabul görmüş dillerden ayrılmaya başlarlar ve daha pragmatik, ördek tipinde olanlara dönerler. Bunun birçok programcının paylaştığı bir bushido olduğuna inanıyorum. Sonra tekrar, bu deneyiminizi yansıtmayabilir, kendi kendini yetiştiren bir uzman olabilirsiniz. Öyleyse bize yolu göster.
ZJR
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.