このようなヘルパー メソッドを注入するために特性を使用することに矛盾はありますか?
クラスフー { Helper\Array を使用します。 関数 isFooValid(配列 $foo) { $this->arrayContainsOnly('BarClass', $foo); を返します。 } }
それが特性の考え方です。
ただし、結合されたコードに注意する必要があります。Helper\Array
が含まれているものとはまったく異なる名前空間である場合は、Foo
この特定のアプローチを再考することをお勧めします。
トレイトが PHP に追加された理由は非常に単純です。PHP は多重継承をサポートしていません。簡単に言えば、クラスは一度に複数のクラスを拡張することはできません。他のクラスでも使用される 2 つの異なるクラスで宣言された機能が必要な場合、これは骨の折れる作業になります。その結果、蜘蛛の巣の霧に巻き込まれることなく仕事を完了するために、コードを繰り返さなければならなくなります。
特性を入力します。これらにより、再利用可能なメソッドを含むクラスの型を宣言できます。さらに良いことに、それらのメソッドは、使用する任意のクラスに直接注入でき、同じクラスで複数のトレイトを使用できます。簡単な Hello World の例を見てみましょう。
<?php
trait SayHello
{
private function hello()
{
return "Hello ";
}
private function world()
{
return "World";
}
}
trait Talk
{
private function speak()
{
echo $this->hello() . $this->world();
}
}
class HelloWorld
{
use SayHello;
use Talk;
public function __construct()
{
$this->speak();
}
}
$message = new HelloWorld(); // returns "Hello World";
私の意見では、アプリケーション内の結束について話すと、責任を分散することは良いことですが、責任を分散させることは、契約による設計とはまったく関係のないことです。これは、ヘルパーとしての特性に関する私の懸念です。私はアーキテクチャ内の特性の位置について多くのことを考えてきました、そして私は本当に特性がそれらが何であるかについて取られるべきだと思います:共有された実装は共有されたカプセル化を意味します。したがって、それらはインターフェースを置き換えるのではなく、それらの背後にとどまる必要があります。PHP固有のインターフェースは単なる抽象化ツールであり、特性は実装ツールにすぎないという事実を考えると、私はアーキテクチャーおよび言語に依存しない意味で「インターフェース」を取ります。インターフェースは実装の前にあります。具体的/詳細ではなく、抽象/インターフェースに依存します。したがって、トレイトはアプリケーションアーキテクチャを構造化せず、クラスコントラクトを開始するのではなく、それらの背後にあり、それらのサービスを提供することを覚えておくことが重要です。