Mengapa PHP memiliki antarmuka?

35

Saya perhatikan bahwa pada PHP5, antarmuka telah ditambahkan ke bahasa. Namun, karena PHP diketik secara longgar, tampaknya sebagian besar manfaat menggunakan antarmuka hilang. Mengapa ini termasuk dalam bahasa?

GSto
sumber
5
Saya pikir pertanyaan yang benar adalah, mengapa tidak?
Alberto Fernández
5
karena mereka tampaknya tidak menawarkan manfaat apa pun, jadi mengapa memasukkannya?
GSto
4
@HorusKol dan sebelum diimplementasikan, mereka tidak digunakan, sehingga Anda dapat melihat bagaimana mereka tidak digunakan dan tidak berguna hanya versi sebelumnya. Anda juga harus membuat dan mendukung klaim bahwa penggunaannya entah bagaimana merupakan peningkatan untuk mengatakan bahwa mereka bermanfaat.
Rein Henrichs
6
@HorusKol Tidak bermusuhan sama sekali. Sangat mudah untuk menunjukkan proposisi nilai palu. Pertanyaan ini meminta seseorang untuk menunjukkan proposisi nilai antarmuka PHP, bukan hanya untuk menyatakan bahwa mereka bernilai secara argumentatif.
Rein Henrichs
3
Dan ingat bahwa antarmuka bukan hanya tentang mengetik. Antarmuka adalah kontrak yang menyatakan bahwa kelas pelaksana harus menyertakan metode yang ditetapkannya. Berguna untuk hal-hal seperti mesin plugin.
Michael

Jawaban:

30

Keuntungan utama dari antarmuka dalam PHP adalah bahwa kelas dapat mengimplementasikan banyak antarmuka. Ini memungkinkan Anda untuk mengelompokkan kelas-kelas yang berbagi beberapa fungsi tetapi tidak harus berbagi kelas induk. Beberapa contoh mungkin termasuk caching, output, atau mengakses properti kelas dengan cara tertentu.

Dalam kode Anda, Anda dapat memeriksa apakah suatu kelas mengimplementasikan antarmuka yang diberikan alih-alih memeriksa nama kelas. Kemudian, kode Anda akan tetap berfungsi ketika kelas-kelas baru ditambahkan.

PHP menyediakan beberapa antarmuka standar yang mungkin berguna dalam berbagai situasi: http://php.net/manual/en/reserved.interfaces.php .

EDIT - Menambahkan contoh

Jika Anda memiliki antarmuka bernama MyInterface dan Anda bekerja dengan beberapa objek dari berbagai kelas yang mungkin atau mungkin tidak berbagi beberapa fungsi, antarmuka memungkinkan Anda untuk melakukan sesuatu seperti ini:

// Assume $objects is an array of instances of various classes
foreach($objects as $obj) {
 if($obj instanceof MyInterface) {
     $obj->a();
     $obj->b();
     $obj->c();
   }
}
pjskeptik
sumber
23
Dengan kata lain: "Anda dapat sepenuhnya mengabaikan semua manfaat dari bahasa yang diketik secara dinamis"
Kamil Tomšík
11
@ Kamil, saya pikir lebih sebagai bisa mengambil keuntungan dari manfaat pengetikan statis tanpa mengalami kekurangan saat Anda tidak menginginkannya.
Karl Bielefeldt
9
Apakah kamu serius? contoh? jika-maka-jika-maka-jika-maka-sepanjang-waktu, bukankah itu terdengar akrab? ah, ya, pemrograman prosedural.
Kamil Tomšík
23
@Kamil Tomšík Namun penghinaan lain pada bahasa PHP daripada orang-orang yang menggunakannya tidak kompeten. PHP memiliki semua alat untuk pemrograman berorientasi objek yang lengkap. Apakah Anda menggunakannya atau tidak, itu tergantung pada programmer. Lebih jauh, tidak ada yang salah dengan pemrograman prosedural dalam dan dari dirinya sendiri.
Lotus Notes
18
@ Kamil - betapa anehnya, dengan membaca komentar Anda, orang mungkin berkesimpulan bahwa tidak ada if-s di OOP dan entah bagaimana, secara ajaib - semuanya mulai berfungsi. Wow.
Michael JV
23

PHP diketik secara longgar, tetapi dapat diketik dengan kuat tentang hal-hal seperti parameter metode.

Perhatikan contoh berikut:

interface Car { function go(); }

class Porsche { function go() {} }

function drive(Car $car) {}

$porsche = new Porsche();

drive($porsche);

Kode di atas akan menampilkan:

Argumen 1 diteruskan ke drive () harus mengimplementasikan antarmuka Mobil, contoh dari Porsche yang diberikan

Emanuil Rusev
sumber
1
Tentu, ini terlalu buruk. Anda dapat memiliki nullnilai default untuk parameter tersebut.
Emanuil Rusev
5
tetapi jika drivememerlukan Car, maka lulus nulltidak akan sangat membantu ...
HorusKol
7
Tidak pernah lulus nol. Gunakan objek "Kasus Khusus" (Google untuk penjelasan Martin Fowler).
Martin Blore
2
RRenesis Jika Anda menetapkan nilai default ke nol, Anda dapat meneruskan null ke dalam metode tipe yang diisyaratkan. (CAR $ car = null) akan memungkinkan Anda untuk memanggil metode ini dengan null sebagai argumen. Namun ini akan menjadi praktik yang cukup konyol. Mengapa Anda ingin bisa melakukan itu?
dqhendricks
2
Contoh nyata: function addView($name, Template $template, SecurityMode $securityMode = null, $methodName = null);Anda mungkin memiliki $methodNametetapi tidak $securityMode.
Nicole
7

Antarmuka memungkinkan Anda untuk menerapkan prinsip buka-tutup, mempertahankan basis kode yang digabungkan secara longgar, dan menerapkan banyak pola desain OOP terbaik.

Misalnya, jika satu kelas menerima kelas lain sebagai argumen:

class A {

    public function __construct(B $class_b) {
        // use class b
        $class_b->run();
    }
}

Kelas A dan kelas B Anda sekarang memiliki kopling ketat, dan kelas A tidak dapat menggunakan kelas lain kecuali B. Petunjuk tipe memastikan bahwa Anda memiliki tipe argumen yang benar, tetapi sekarang telah memperkuat hubungan antara A dan B.

Katakanlah bahwa Anda ingin kelas A dapat menggunakan semua jenis kelas yang memiliki metode run (). Ini pada dasarnya (tetapi tidak cukup) pola desain PERINTAH. Untuk menyelesaikannya, Anda lebih baik mengetikkan petunjuk menggunakan antarmuka alih-alih kelas beton. B akan mereka mengimplementasikan antarmuka itu, dan akan diterima sebagai argumen untuk kelas A. Dengan cara ini kelas A dapat menerima setiap kelas yang menggunakan antarmuka itu sebagai argumen untuk konstruktornya.

Jenis pengkodean ini digunakan di sebagian besar pola desain OOP, dan memungkinkan untuk JAUH perubahan kode yang lebih mudah di lain waktu. Ini adalah bagian dari dasar-dasar pemrograman AGILE.

dqhendricks
sumber
1
Atau subkelas dari B
Mez
7

@ pjskeptic memiliki jawaban yang bagus , dan @Kamil Tomšík memiliki komentar yang bagus tentang jawaban itu.

Hal terbaik tentang bahasa yang diketik secara dinamis seperti PHP adalah Anda dapat mencoba menggunakan metode pada objek dan itu tidak akan meneriaki Anda kecuali metode itu tidak ada.

Masalah dengan bahasa yang diketik secara dinamis seperti PHP adalah bahwa Anda dapat mencoba menggunakan metode pada objek dan itu akan berteriak pada Anda ketika metode itu tidak ada.

Antarmuka menambahkan cara yang mudah memanggil metode pada objek yang tidak dikenal dan memastikan bahwa metode ada di sana (bukan berarti mereka benar atau akan bekerja). Ini bukan bagian penting dari suatu bahasa, tetapi itu membuat pengkodean lebih nyaman. Hal ini memungkinkan pengembang OOP sangat mengetik untuk menulis kode PHP sangat diketik, yang kemudian dapat bekerja bersama kode PHP diketik longgar yang ditulis oleh pengembang PHP yang berbeda.

fungsi seperti:

foo( IBar $bar )
{
  $baz = $bar->baz();
  ...
}

lebih nyaman daripada:

foo( $bar )
{
  if ( method_exists( $bar, 'baz' ) )
  {
    $baz = $bar->baz();
  }
  else
  {
    throw new Exception('OMGWTF NO BAZ IN BAR!');
  }
  ...
}

dan IMHO sederhana, kode yang dapat dibaca adalah kode yang lebih baik.

zzzzBov
sumber
1
apa yang Anda lakukan malah tidak memeriksa metode dan crash dan membakar ketika seseorang memanggil fungsi Anda dengan data yang salah. Itu bukan masalah Anda jika seseorang menggunakan fungsi Anda salah.
Raynos
tidak persis - contoh Anda adalah mimpi buruk bagi siapa saja yang ingin memberikan "bebek" dinamis, seperti proxy, adaptor, dekorator dll.
Kamil Tomšík
1
@ Kamil? Bagaimana. Proxy akan menjadi kelas pembungkus untuk sesuatu yang tidak mengimplementasikan antarmuka untuk memungkinkannya digunakan dengan fungsi ini.
tylermac
@tylermac dynamic proxy menggunakan __call () - dan jika __call adalah satu-satunya metode di sana, ia tidak dapat mengimplementasikan IBar, yang berarti Anda tidak dapat meneruskannya ke foo (bar $ IBar)
Kamil Tomšík
5

Mereka benar-benar tidak berguna jika Anda bebek-typer, sebenarnya ketika Anda melakukan bebek-mengetik, itu cukup menjengkelkan untuk bekerja dengan perpustakaan / kerangka kerja yang menggunakan petunjuk tipe apa pun.

Ini berlaku juga untuk semua jenis pemrograman meta dinamis (metode ajaib).

Kamil Tomšík
sumber
3

PHP tidak longgar atau kuat, tetapi diketik secara dinamis .

Tentang antarmuka, hal pertama yang harus Anda tanyakan pada diri sendiri adalah: apa manfaat paling banyak dari antarmuka?

Dalam OOP, antarmuka bukan hanya tentang tipe, tetapi juga tentang perilaku.

Karena PHP juga memiliki fitur petunjuk jenis , Anda dapat menggunakan antarmuka seperti yang Anda lakukan dalam bahasa oo murni, seperti Java.

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
        }
    }
}

Dengan implementasi antarmuka PHP, Anda juga dapat membuat tiruan untuk kelas abstrak menggunakan PHPUnit - dan ini adalah fitur yang luar biasa:

public function testSomething()
{
    $mock = $this->getMockForAbstractClass('File');

    $mock->expects($this->once())
         ->method('getLines')
         ->will($this->returnValue(array()));

    // do your assertions
}

Jadi, pada dasarnya, Anda dapat memiliki aplikasi yang SOLID kompatibel di PHP dengan menggunakan fitur bahasa, salah satunya adalah antarmuka.

Daniel Ribeiro
sumber
0

Antarmuka berguna untuk injeksi ketergantungan lebih dari beton. Sebagai contoh barebones:

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

Sekarang katakan jika kebutuhan Anda berubah dan Anda ingin menyimpan ke pdf. Anda dapat membuat kelas baru untuk tujuan itu alih-alih mencemari kelas Artikel.

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

Kelas Artikel sekarang memiliki kontrak yang digunakan kelas untuk menyimpan harus mengimplementasikan antarmuka Istore. Itu tidak peduli di mana ia menyimpan atau bagaimana ia menyelamatkan.

Pete
sumber
-1

Anda dapat memberikan objek nyata "Palsu" yang mengimplementasikan antarmuka. Anda kemudian dapat menguji unit bagian dari kode Anda tanpa memerlukan server nyata, sistem file, soket, database dll.

Martin Blore
sumber
-3

Banyak orang mungkin akan membenci saya karena menjawab seperti ini tetapi solusi untuk masalah pengetikan Anda dapat dengan mudah diperbaiki dengan PHP. Ya PHP diketik secara longgar sehingga jenis diasumsikan secara default, yang bisa menyebabkan beberapa masalah, terutama dalam operasi perbandingan yang merupakan masalah kebanyakan orang. Karena itu, PHP bisa seketat bahasa apa pun yang diketik dengan kuat jika Anda memasukkan apa yang Anda gunakan ke dalam jenis yang Anda inginkan, dan kemudian menggunakan operator perbandingan bitwise. Ini adalah contoh termudah yang dapat saya pikirkan tentang apa yang saya katakan:

$ myVar = (int) 0; $ myOtherVar = '0';

membandingkan ($ myVar == $ myVar) akan sama dengan (bool) true

tetapi membandingkan ($ myVar === $ myVar) akan sama dengan (bool) false sama seperti perbandingan "diketik"

Saya benar-benar hanya berharap pengembang berhenti berdebat tentang hal-hal ini, jika Anda memiliki masalah dengan cara kerja PHP baik pergi program di java dan hidup dan biarkan hidup, atau menggunakannya dengan cara yang akan melakukan apa yang Anda inginkan .. Lagipula, apa gunanya mengomel untukmu? Apakah Anda punya alasan untuk berkeliaran sepanjang hari? Membuat Anda terlihat lebih baik dari orang lain? Ya, hebat bahwa Anda merasa begitu tinggi tentang diri Anda sehingga Anda ingin membuat orang lain terlihat buruk, tetapi pada kenyataannya itu adalah preferensi Anda dan memaksakan keyakinan Anda pada siapa pun benar-benar hanya membuat mereka kode dengan cara mereka tidak nyaman dengan menyebabkan tiga hal:

1) Mereka akan mengkodekan cara Anda tetapi "berantakan" dengan standar Anda (pikirkan, apakah Anda pernah melihat seorang programmer java membuat program PHP pertama mereka atau sebaliknya? Ini akan menjadi cara yang sama mengubah metodologi mereka atau bahkan mungkin lebih buruk.)

2) Anda akan menemukan hal lain untuk dikeluhkan

3) Mungkin perlu waktu lebih lama bagi mereka untuk berproduksi. Dan mungkin itu akan membuat Anda terlihat lebih baik dalam jangka pendek, tetapi tim secara keseluruhan akan terlihat lebih buruk untuk itu (ingat Anda mungkin kode lebih lambat dari orang lain dan itu tidak selalu buruk selama tim memenuhi kiriman dalam jangka waktu yang masuk akal, tetapi memaksakan kebiasaan Anda pada seseorang yang biasanya melakukan sedikit lebih cepat mungkin akhirnya membuat seluruh tim Anda melambat sehingga terlihat lebih buruk dalam alur kerja yang sangat menuntut)

Saya pribadi lebih suka menulis kode PHP prosedural meskipun saya dapat, dan memiliki, menulis program lengkap menggunakan OOP dalam beberapa bahasa yang berbeda. Yang sedang berkata, saya telah melihat kode OOP yang baik dan kode OOP yang buruk, dan kode prosedural yang baik dan kode prosedural yang buruk dalam hal ini ... Itu benar-benar tidak ada hubungannya dengan praktik, tetapi dengan kebiasaan yang Anda gunakan dan bahkan kemudian, banyak hal adalah perasaan saya yang ditafsirkan ... itu tidak berarti saya akan berbicara buruk tentang para pengembang tersebut atau mengatakan sombong dengan "cara saya yang terbaik" BS, itu tepat untuk saya, dan perusahaan tempat saya bekerja cukup senang dengan pekerjaan saya dan saya bangga akan hal itu. Ada alasan standar harus ditetapkan tetapi apa yang Anda masukkan dalam standar yang Anda pilih SANGAT penting ... Terima kasih telah membiarkan saya melepaskannya dari dada. Semoga hari mu menyenangkan.

Jake Pogorelec
sumber
-4
  1. Antarmuka adalah bagian dari paradigma OOP. Jadi itu sangat berguna dalam banyak kasus ketika Anda mencoba membuat bagian-bagian berorientasi objek atau sistem Anda.
  2. Begitu. Kenapa tidak? ;-)

Contoh: Anda perlu cache data Anda. Bagaimana? Ada banyak mesin berbeda untuk caching, mana yang terbaik? Siapa yang peduli jika Anda memiliki lapisan abstrak yang memiliki beberapa antarmuka ICacheDriver dengan serangkaian metode seperti kunci, dapatkan, masukkan, hapus, dll. Cukup terapkan padanya apa yang Anda butuhkan dalam proyek saat ini dan ubah ketika Anda membutuhkan yang lain. Atau penggunaan sederhana toString. Anda memiliki satu set objek yang dapat ditampilkan yang berbeda. Anda hanya mengimplementasikan antarmuka Stringable (yang menggambarkan metode toString [tidak ada antarmuka seperti itu di PHP, tetapi misalnya]) dan hanya menginterpretasikan semua objek Anda dengan (string) $ obj. Hanya itu yang perlu Anda lakukan alih-alih beralih (true) {case $ obj isntanceof A1: "do 1"; istirahat; ...}

Sederhana. Jadi tidak ada pertanyaan "Kenapa?". Ada "bagaimana cara menggunakannya dengan lebih baik?". ;-) Semoga berhasil.

Alex Yaroshevich
sumber
-5

Tebakanku.

PHP digunakan oleh banyak programmer level entry, programmer level entry diajarkan java di perguruan tinggi.

Setelah kursus Pemrograman 101 mereka, mereka mulai mengomel Zend mereka ingin fitur java karena itulah cara mereka telah diajarkan untuk berpikir, pemikiran tentang istilah Anda sendiri (atau memahami mengetik bebek) sulit, ketika Anda hanya 20.

Zend pragmatis, lebih mudah untuk menambahkan fitur selain berpura-pura mereka benar.
Ini juga membeli lebih banyak pengguna daripada membuat mereka pergi, jadi pasti bagus.

Contoh lain dari proses ini? Orang-orang yang baru keluar dari kursus .NET dan Java juga menginginkan Frameworks of Foundation Classes , mereka mengomel tentang hal itu sampai Zend mengeluarkan Zend Framework . Ini membeli lebih banyak pengguna. Dan terus dan terus ...

(Satu-satunya fitur bahasa yang diketahui oleh tim PHP telah diperjuangkan , selama bertahun-tahun adalah goto)

ZJR
sumber
Dalam visi saya, PHP12mungkin akan memiliki semua fitur sintaks dunia (saya harap itu tidak mendapatkan runtime lapisan abstraksi, sulit, karena itulah yang membunuh perl) dengan mengedipkan mata ke paradigma fungsional dan tipe data, dan masih belum goto.
ZJR
"Sulit, ketika kamu baru berusia 20" Bagaimana mungkin usia bisa ada hubungannya dengan memahami salah satu dari konsep-konsep itu?
Evicatos
@Evicatos sekolah menengah semacam program, tetapi mereka biasanya memiliki guru yang buruk, konvensi penamaan yang buruk, dan menghasilkan gumpalan yang tidak dapat dipertahankan. Mereka belajar memprogram dengan benar saat mulai kuliah, perlu beberapa tahun untuk mewujudkannya. Kemudian mereka mulai menyimpang dari bahasa-bahasa yang diketik dengan keras, diberkahi industri, diakui secara profesional, yang telah mereka ajarkan pada tahun-tahun pertama itu, dan beralih ke bahasa yang lebih pragmatis, bertipe bebek. Saya percaya ini adalah bushido yang dibagikan oleh banyak programmer. Kemudian lagi, ini mungkin tidak mencerminkan pengalaman Anda, Anda mungkin seorang ahli otodidak. Jika demikian, tunjukkan caranya.
ZJR