Có nhiều cách để tiếp cận điều này, đây là một trong số đó. Giả sử bạn có một giản đồ db tương tự như sau:
Bây giờ bạn có thể yêu cầu AlbumMapper và ArtistMapper chịu trách nhiệm tìm nạp các đối tượng đó từ db cho bạn:
interface AlbumMapper {
/**
* Fetches the albums from the db based on criteria
* @param type $albumCriteria
* @param ArtistMapper $artistMapper
*
* Note: the ArtistMapper here can be also made optional depends on your app
*/
public function fetchBySomeCriteria($albumCriteria, ArtistMapper $artistMapper);
}
interface ArtistMapper {
/**
* @param array $ids
* @return Artist[]
*/
public function fetchByAlbumIds(array $ids);
}
Tôi đã nói rằng AlbumMapper yêu cầu ArtistMapper vì vậy với trình liên kết này, các Album luôn được trả lại cùng với các nghệ sĩ của họ. Bây giờ, một ví dụ triển khai có thể giống như thế này, trong đó tôi sử dụng một thủ thuật lập chỉ mục nhỏ để đính kèm nghệ sĩ vào album:
class ConcreteAlbumMapper implements AlbumMapper {
public function fetchBySomeCriteria($albumCriteria, ArtistMapper $artistMapper) {
//sql for fetching rows from album table based on album criteria
$albums = array();
foreach ($albumRows as $albumRow) {
$albums[$albumRow['id']] = new Album($albumRow);
}
$artists = $artistMapper->fetchByAlbumIds(array_keys($albums));
//marrying album and artists
foreach ($artists as $artist) {
/**
* not crazy about the getAlbumId() part, would be better to say
* $artist->attachYourselfToAnAlbumFromThisIndexedCollection($albums);
* but going with this for simplicity
*/
$albums[$artist->getAlbumId()]->addArtist($artist);
}
return $albums;
}
}
Trong trường hợp này, Album của bạn sẽ nằm dọc theo các dòng:
class Album {
private $id;
private $title;
private $artists = array();
public function __construct($data) {
//initialize fields
}
public function addArtist(Artist $artist) {
$this->artists[] = $artist;
}
}
Cuối cùng, bạn sẽ có một bộ sưu tập các đối tượng Album được khởi tạo bằng Nghệ sĩ của chúng.