PHP5の時点で、言語にインターフェースが追加されていることに気付きました。ただし、PHPは非常に緩やかに型付けされているため、インターフェイスを使用する利点のほとんどが失われているようです。なぜこれが言語に含まれているのですか?
PHP5の時点で、言語にインターフェースが追加されていることに気付きました。ただし、PHPは非常に緩やかに型付けされているため、インターフェイスを使用する利点のほとんどが失われているようです。なぜこれが言語に含まれているのですか?
回答:
PHPのインターフェイスの主な利点は、クラスが複数のインターフェイスを実装できることです。これにより、いくつかの機能を共有するが、必ずしも親クラスを共有しないクラスをグループ化できます。いくつかの例には、特定の方法でのクラスのプロパティのキャッシュ、出力、またはアクセスが含まれます。
コードでは、クラス名を確認する代わりに、クラスが特定のインターフェイスを実装しているかどうかを確認できます。その後、新しいクラスが追加されてもコードは機能します。
PHPは、http://php.net/manual/en/reserved.interfaces.phpなど、さまざまな状況で役立ついくつかの事前定義されたインターフェースを提供します。
編集-サンプルの追加
MyInterfaceという名前のインターフェイスがあり、一部の機能を共有する場合と共有しない場合がある異なるクラスの複数のオブジェクトを操作している場合、インターフェイスを使用すると次のようなことができます。
// 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は緩やかに型付けされていますが、メソッドパラメーターなどについて強く型付けできます。
次の例を考えてみましょう。
interface Car { function go(); }
class Porsche { function go() {} }
function drive(Car $car) {}
$porsche = new Porsche();
drive($porsche);
上記のコードは次を出力します:
drive()に渡される引数1は、インターフェイスCar、指定されたポルシェのインスタンスを実装する必要があります
null
ただし、パラメータにデフォルト値を設定できます。
drive
が必要な場合は、とにかくCar
渡すnull
ことはあまり役に立ちません
function addView($name, Template $template, SecurityMode $securityMode = null, $methodName = null);
がありますが$methodName
、ありません$securityMode
。
インターフェイスを使用すると、オープンクローズの原則を実装し、疎結合のコードベースを維持し、最高のOOPデザインパターンの多くを実装できます。
たとえば、あるクラスが別のクラスを引数として受け入れる場合:
class A {
public function __construct(B $class_b) {
// use class b
$class_b->run();
}
}
クラスAとクラスBは密結合になり、クラスAはB以外の他のクラスを使用できません。型のヒントにより、正しい型の引数があることが確認されますが、AとBの関係は強固になりました。
ただし、クラスAでrun()メソッドを持つすべてのタイプのクラスを使用できるようにしたいとします。これは基本的に(完全ではありませんが)コマンドデザインパターンです。解決するには、代わりに具体的なクラスの代わりにインターフェースを使用してヒントを入力します。Bは、そのインターフェイスを実装し、クラスAの引数として受け入れられます。このようにして、クラスAは、そのインターフェイスをコンストラクタの引数として使用するクラスを受け入れることができます。
このタイプのコーディングは、ほとんどのOOP設計パターンで使用され、後でコードを非常に簡単に変更できます。これらは、AGILEプログラミングの基礎の一部です。
@pjskepticには良い答えがあり、@ KamilTomšíkにはその答えに対する良いコメントがあります。
PHPのような動的に型付けされた言語の素晴らしい点は、オブジェクトでメソッドを使用しようとすることができ、メソッドが存在しない限り叫びません。
PHPのような動的に型付けされた言語の問題は、オブジェクトでメソッドを使用しようとすることができ、メソッドが存在しないときに悲鳴を上げることです。
インターフェイスは、未知のオブジェクトのメソッドを呼び出す便利な方法を追加し、メソッドがそこにあることを確実にします(必ずしも正しいか、機能するわけではありません)。これは言語の必須部分ではありませんが、コーディングをより便利にします。これにより、強く型付けされたOOP開発者は強く型付けされたPHPコードを記述でき、別のPHP開発者によって記述された緩く型付けされたPHPコードと一緒に動作できます。
次のような関数:
foo( IBar $bar )
{
$baz = $bar->baz();
...
}
より便利です:
foo( $bar )
{
if ( method_exists( $bar, 'baz' ) )
{
$baz = $bar->baz();
}
else
{
throw new Exception('OMGWTF NO BAZ IN BAR!');
}
...
}
そして、私見のシンプルで読みやすいコードは、より良いコードです。
PHPは緩くも強くもありませんが、動的に型付けされます。
インターフェイスについて、最初に自問すべきことは次のとおりです。インターフェイスの利点のほとんどは何ですか?
OOPでは、インターフェイスは型だけでなく、動作についても同様です。
PHPには型ヒント機能もあるため、Javaなどの純粋なoo言語の場合と同じようにインターフェイスを使用できます。
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インターフェースの実装では、PHPUnitを使用して抽象クラスのモックを作成することもできます。これは機能の地獄です:
public function testSomething()
{
$mock = $this->getMockForAbstractClass('File');
$mock->expects($this->once())
->method('getLines')
->will($this->returnValue(array()));
// do your assertions
}
したがって、基本的に、言語機能を使用してPHPでSOLID互換アプリケーションを作成できます。そのうちの1つはインターフェイスです。
依存関係の注入には、具体的なものよりもインターフェースがはるかに役立ちます。最低限の例として:
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);
ニーズが変わって、pdfに保存する場合は、次のように言います。Articleクラスを汚染する代わりに、その目的のために新しいクラスを作成できます。
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);
Articleクラスには、保存に使用するクラスがIstoreインターフェイスを実装する必要があるというコントラクトがあります。どこに保存するか、どのように保存するかは気にしません。
多くの人がこの方法で答えるのを嫌うかもしれませんが、入力の問題の解決策はPHPで簡単に修正できます。はいタイプがデフォルトで想定しているので、PHPは緩くれ、入力されることができます、特にほとんどの人が問題とする比較演算において、いくつかの問題引き起こす性あり。そうは言っても、使用しているものを必要な型にキャストし、ビットごとの比較演算子を使用すると、PHPは厳密に型指定された言語と同じくらい厳密になります。私が言っていることについて考えることができる最も簡単な例は次のとおりです。
$ myVar =(int)0; $ myOtherVar = '0';
比較($ myVar == $ myVar)は等しい(bool)true
しかし、($ myVar === $ myVar)を比較すると、「型指定された」比較のようにfalse(bool)になります
PHPの動作に問題がある場合、Javaでプログラムを実行してライブにするか、それが目的どおりに機能するように使用するか、開発者がこれらのことについて議論するのを止めてほしいと思います。とにかく、それについての愚痴はあなたにとって何をしますか?一日中めちゃくちゃに言い訳をする?他の人よりも見栄えを良くしますか?自分自身について非常に強く感じているので、他の誰かを悪く見せたいと思っているのは素晴らしいことですが、実際にはあなたの好みであり、誰にでもあなたの信念を強要することは、彼らが3つのことを引き起こすことに慣れていない方法でコードを作るだけです:
1)彼らはあなたの方法でコーディングしますが、あなたの標準では「面倒」です(Javaプログラマーが最初のPHPプログラムを作成するのを見たことがありますか?その逆も同様です。
2)泣き言を言う他の何かを見つける
3)彼らが生産するのにおそらく時間がかかるでしょう。また、短期的には見た目が良くなるかもしれませんが、チーム全体としては悪く見えます(コードが他の誰かよりも遅くなる可能性があり、チームが妥当な時間枠で成果物を満たしている限り、それは必ずしも悪いことではありません、しかし、通常少し速く走っている人に習慣を強要すると、チーム全体が遅くなり、非常に厳しいワークフローで悪化する可能性があります)
私は個人的に手続き型のPHPコードを書くことを好みますが、いくつかの異なる言語でOOPを使用して完全なプログラムを書くことができます。そうは言っても、良いOOPコードと悪いOOPコード、そして良い手順コードと悪い手順コードを見てきました...それは実際には練習とは関係ありませんが、あなたが使用する習慣と、多くのことが私の解釈された感情です...それは、それらの開発者について悪い話をしたり、「私のやり方は最高です」と自慢することを意味するわけではありませんBS、それは私にぴったりです私の仕事に満足しており、それを誇りに思っています。標準を確立する必要がある理由はありますが、選択した標準に含めることは非常に重要です...それを胸から出してくれてありがとう。すてきな一日を。
例:データをキャッシュする必要があります。どうやって?キャッシングにはさまざまなエンジンがありますが、どれが最適ですか?key、get、put、clearなどの一連のメソッドを持つICacheDriverインターフェイスを持つ抽象レイヤーがある場合、誰が気にします。現在のプロジェクトで必要なものを実装し、別のプロジェクトが必要なときに変更します。または、toStringの単純な使用法。さまざまな表示可能なオブジェクトのセットがあります。Stringableインターフェイスを実装し(toStringメソッドについて説明します[PHPには実際にはそのようなインターフェイスはありませんが、たとえば)]、すべてのオブジェクトを(string)$ objで相互作用します。switch(true){case $ obj isntanceof A1: "do 1";の代わりに必要なことはすべてあります。ブレーク; ...}
シンプル。だから「なぜ?」という質問はありません。「それをもっとうまく使う方法」があります。;-) がんばろう。
私の推測。
PHPは多くの初心者レベルのプログラマーによって使用されており、初心者レベルのプログラマーは大学でjavaを教えられています。
プログラミング101コースの後、彼らはZendのしつこい作業を始めます。Java機能が欲しいのは、それが彼らが考えるように教えられた方法だからです。
Zendは実用的です。機能を追加する方が、ずっと先にふりをするよりも簡単です。
これにより、ユーザーを退場させる代わりに、より多くのユーザーを獲得できるため、良い結果になります。
このプロセスの別のインスタンス?.NETやJavaのコースを卒業したばかりの人も、Foundation ClassesのFrameworksを望んでいます。ZendがZend Frameworkを芽生えさせるまで、彼らはそれを口にしません。これにより、さらに多くのユーザーが購入します。そしてさらに...
(PHPチームがいることが知られている唯一の言語機能戦っ年間では、ありますgoto
)
PHP12
は、おそらく機能とデータ型のパラダイムへのウィンクを備えた世界のすべての構文機能を備えています(perlを殺したので、抽象化レイヤーランタイムを取得しないことを願っています)goto
。