私の問題を説明するために、分析がより簡単な特定の類推を使用します。私の意見では、私の問題をよく反映しています。
本と本棚の 2 つのリストを含む Library クラスがあるとします。PHP では両方のリストを配列として実装するのが最も簡単で、私はそうしました。クラス ライブラリに book と bookshelves という 2 つのパブリック フィールドを作成し、コンストラクターでそれらを配列で初期化しました。
class Library
{
public $books;
public $bookshelves;
public function __construct () {
$this->books = array();
$this->bookshelves = array();
}
}
配列に実装されたメソッドで十分なので、すべてがうまくいくでしょう。しかし、プログラミングのベスト プラクティスの観点からは、このコードは正しくないように思えます。このクラスはそれほど密閉的ではないと思いますよね?そのフィールドが何に使用され、どのように扱われるかを覚えておく必要があります。たとえば、本をライブラリに追加したい場合は、Library クラスのメソッド addBook を検索します。Library クラスのフィールド ブックに対してメソッド add を実行する必要があるとは思いもしませんでした。
したがって、ブックとブックシェルフのフィールドを非公開にし、Library クラスで addBook/addBookshelf、removeBook/removeBookshelf、getBook/getBookshelf などの関数を実装する必要があります。
class Library
{
private $books;
private $bookshelves;
public function __construct () {
$this->books = array();
$this->bookshelves = array();
}
public function addBook (Book $book) {
$this->books[] = $book;
}
public function removeBook ($id) {
$this->books[$id] = [];
}
public function getBook ($id) {
return $this->books[$id];
}
public function addBookhelf (Book $book) {
$this->bookshelf[] = $book;
}
public function removeBookhelf ($id) {
$this->bookshelf[$id] = [];
}
public function getBookhelf ($id) {
return $this->bookshelf[$id];
}
}
しかし、それも間違っています。すでに配列に実装されているのと同じものを2回目に書くのに、なぜ誰かが時間を費やすのでしょうか? では、原則として 1 つのクラス、1 つの責任についてはどうでしょうか。
3 つ目は、ArrayObject クラスを拡張した BooksList と BookshelveList の 2 つのクラスを作成する方法です。追加のメソッドやフィールドはありません。
class BooksList extends ArrayObject
{
}
class BookshelvesList extends ArrayObject
{
}
次に、パブリック フィールドの本と本棚をこのクラスで初期化する必要があります。
class Library
{
private $books;
private $bookshelves;
public function __construct ()
{
$this->books = new BooksList();
$this->bookshelves = new BookshelvesList();
}
}
その場合、Library クラスは本と本棚の操作を担当しません。また、配列操作は 2 回目に書き込まれることはありません。しかし、何か新しいものを追加していない 2 つの奇妙なオブジェクトを作成しています。
そこで、私は自分の問題を実装する 3 つの可能性を考え出しましたが、すべてにいくつかの欠陥があります。これは複雑な関係ではなく、これを実装する簡単でエレガントな方法です。この問題に適合するデザインパターンを探しましたが、見つかりませんでした。したがって、ここで質問していますが、これを正しく実装する方法は?