Hay muchas maneras de abordar esto, esta es una de ellas. Digamos que tiene un esquema de base de datos similar a este:
Ahora puede hacer que AlbumMapper y ArtistMapper se encarguen de obtener esos objetos de la base de datos por usted:
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);
}
He puesto que AlbumMapper requiere ArtistMapper, por lo que con este mapeador, los álbumes siempre se devuelven con sus artistas. Ahora, una implementación de ejemplo puede ser así, donde utilizo un pequeño truco de indexación para adjuntar el artista a los álbumes:
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;
}
}
En este caso, su Álbum estará en la línea de:
class Album {
private $id;
private $title;
private $artists = array();
public function __construct($data) {
//initialize fields
}
public function addArtist(Artist $artist) {
$this->artists[] = $artist;
}
}
Al final de todo esto deberías tener una colección de objetos de Álbum inicializados con sus Artistas.