ホームページ >バックエンド開発 >PHPチュートリアル >インターフェースとは何ですか? PHP のインターフェイスを使用してエレガントなコードを記述するにはどうすればよいですか?
インターフェースとは何ですか? PHP でインターフェイスを使用するにはどうすればよいですか?この記事では、インターフェイスを使用してよりエレガントな PHP コードを記述する方法について説明します。
プログラミングでは、コードが読みやすく、保守しやすく、拡張可能で、テストが容易であることを保証することが重要です。インターフェイスを使用することで、まさにこれらすべての要素を改善することができます。コード メソッドの 1 つ。
この記事は、OOP (オブジェクト指向プログラミング) の概念を基本的に理解し、PHP で継承を使用する開発者を対象としています。 PHP コードで継承を使用する方法を知っている場合は、この記事をよく理解できるはずです。
要するに、インターフェイスはクラスが何をすべきかを単に記述したものであり、インターフェイスを実装するクラスに、インターフェイス内で定義されているすべてのパブリック メソッドが確実に含まれるようにするために使用できます。
Interfacecan:
インターフェイスはインスタンス化できません。
interface DownloadableReport { public function getName(): string; public function getHeaders(): array; public function getData(): array; }
php.net ドキュメントによると、インターフェイスには 2 つの主な目的があることがわかります。 :
Iterable、
Cacheable、
Renderable などの名前が付けられます。
class BlogReport { public function getName(): string { return 'Blog report'; } }ご覧のとおり、文字列を返す関数を含むクラスを定義しました。このようにしてメソッドの動作を定義するので、
getName() がどのように文字列を返すかがわかります。ただし、このメソッドを別のクラスで呼び出すとします。このクラスは文字列の構築方法を気にする必要はなく、メソッドがコンテンツを返すかどうかだけを気にします。たとえば、別のクラスでこのメソッドを呼び出す方法を見てみましょう。
class ReportDownloadService { public function downloadPDF(BlogReport $report) { $name = $report->getName(); // 下载文件…… } }上記のコードは通常どおり実行されますが、
UsersReport クラスにダウンロードを追加するとします。ユーザー。明らかに、
ReportDownloadService の既存のメソッドは使用できません。これは、このメソッドには
BlogReport クラスのみを渡すことが強制されているためです。したがって、以下に示すように、元のダウンロード メソッドの名前を変更して (名前の重複を避けるため)、同様のメソッドを追加する必要があります。
class ReportDownloadService { public function downloadBlogReportPDF(BlogReport $report) { $name = $report->getName(); // 下载文件…… } public function downloadUsersReportPDF(UsersReport $report) { $name = $report->getName(); // 下载文件…… } }上記のメソッドのダウンロード ファイル部分 ( out 部分) は同じコードを使用しており、これらの同じコードを別のメソッドに記述することもできますが、それでもコードの一部が繰り返されることになります (翻訳者注: 各メソッドの
を指します $name = $report->getName ();) ほぼ同じクラスのエントリが複数あります。これにより、将来的にコードの拡張やテストのための追加作業が発生する可能性があります。
AnalyticsReport を作成するとします。このクラスに新しい
downloadAnalyticsReportPDF() メソッドを追加する必要があります。このファイルがどのように拡張されるかがはっきりとわかります。これはインターフェイスを使用するのに最適なシナリオです。
DownloadableReport という名前を付け、次のように定義します。
interface DownloadableReport { public function getName(): string; public function getHeaders(): array; public function getData(): array; }これで、
BlogReport と # を更新できるようになります。次の例に示すように、##UsersReport
を使用して DownloadableReport
インターフェイスを実装します。ただし、デモンストレーションの目的で、UsersReport
のコードを意図的に間違って記述したことに注意してください: <pre class="brush:php;toolbar:false">class BlogReport implements DownloadableReport
{
public function getName(): string
{
return 'Blog report';
}
public function getHeaders(): array
{
return ['The headers go here'];
}
public function getData(): array
{
return ['The data for the report is here.'];
}
}</pre>
<pre class="brush:php;toolbar:false">class UsersReport implements DownloadableReport
{
public function getName()
{
return ['Users Report'];
}
public function getData(): string
{
return 'The data for the report is here.';
}
}</pre>
しかし、コードを実行しようとすると、次の理由でエラーが発生します :
缺少 getHeaders()
方法.
getName()
方法不包括接口的方法签名中定义的返回类型。
getData()
方法定义了一个返回类型,但它与接口的方法签名中定义的类型不同。
因此,为了修复 UsersReport
使其正确实现 DownloadableReport
接口,我们可以将其修改为:
class UsersReport implements DownloadableReport { public function getName(): string { return 'Users Report'; } public function getHeaders(): array { return []; } public function getData(): array { return ['The data for the report is here.']; } }
现在两个报告类都实现了相同的接口,我们可以这样更新我们的 ReportDownloadService
:
class ReportDownloadService { public function downloadReportPDF(DownloadableReport $report) { $name = $report->getName(); // 下载文件…… } }
我们现在可以把 UsersReport
或 BlogReport
对象传入 downloadReportPDF
方法中,而且不会出现任何错误。这是因为我们知道该对象实现了报告类的必要方法,并且将返回我们期望的数据类型。
通过向方法传递了一个接口,而不是一个具体的类,我们可以根据方法的实际作用(而不是方法的实现原理)来解耦 ReportDownloadService
类和这些报告类。
如果我们想创建一个新的 AnalyticsReport
,我们可以让它实现相同的接口。这样一来,我们不必添加任何新的方法,只需要将报告对象传递给同一个的 downloadReportPDF()
方法。如果你正在构建你自己的包或框架,接口可能对你特别有用。你只需要告诉使用者要实现哪个接口,然后他们就可以创建自己的类。例如,在 Laravel 中,我们可以通过实现 Illuminate\Contracts\Cache\Store
接口来创建自己的自定义缓存驱动类。
除了能改进代码之外,我喜欢使用接口的另一个原因是 —— 它们起到了“代码即文档”的作用。例如,如果我想弄清楚一个类能做什么,不能做什么,我倾向于先看接口,然后再看实现它的类。接口能够告诉我们所有可被调用的方法,而不需要我们过多地关心这些方法的底层实现方式是怎样的。
值得注意的是,Laravel
中的“契约(contract)”和“接口(interface)”这两个词语是可互换的。根据 Laravel 文档,“契约是一组由框架提供的核心服务的接口”。所以,记住:契约是一个接口,但接口不一定是契约。通常情况下,契约只是框架提供的一个接口。关于使用契约的更多信息,我建议大家可以阅读这一篇文档。它很好地剖析了契约究竟是什么,也对使用契约的方式与场景做了一定的叙述。
希望通过阅读这篇文章,你能对什么是接口、如何在 PHP 中使用接口以及使用接口的好处有一个简单的了解。
原文地址:https://dev.to/ashallendesign/using-interfaces-to-write-better-php-code-391f
原文作者:Ash Allen
译者:kamly、jaredliw
推荐学习:《PHP视频教程》
以上がインターフェースとは何ですか? PHP のインターフェイスを使用してエレガントなコードを記述するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。