Der er mange måder at gribe dette an på, dette er en af dem. Lad os sige, at du har et db-skema, der ligner dette:
Nu kan du have AlbumMapper og ArtistMapper ansvarlige for at hente disse objekter fra databasen for dig:
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);
}
Jeg har sagt, at AlbumMapper kræver ArtistMapper, så med denne mapper returneres album altid med deres kunstnere. Nu kan et eksempel på implementering være sådan her, hvor jeg bruger et lille indekseringstrick til at vedhæfte kunstner til 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;
}
}
I dette tilfælde vil dit album være på linje med:
class Album {
private $id;
private $title;
private $artists = array();
public function __construct($data) {
//initialize fields
}
public function addArtist(Artist $artist) {
$this->artists[] = $artist;
}
}
I slutningen af alt dette bør du have en samling af albumobjekter initialiseret med deres kunstnere.