I’m writing an app that manages playlists.
Basically, my actual logic looks like
//define playlist props
class Playlist{
public tracks = [];
}
class ApiPlaylist extends Playlist{
//fill playlist withs (single page) data from API
public async loadPage(paginationSettings){
const pageTracks = await...
this.tracks = [...this.tracks,...pageTracks]; //concat tracks
}
}
class Paginated extends ApiPlaylist{
private iterations = 0;
private endReached = false;
public async loadAll(){
while (!this.endReached){
this.loadNext();
}
}
public async loadNext(){
this.iterations++;
await this.loadPage(); //call ApiPlaylist method
if(...){
this.endReached = true; //stop iterating
}
}
}
const playlist = new Paginated();
playlist.loadAll();
It works.
But what if I have different others paginated datas to get, that are not related to playlists ?
I would like to use the mechanism from PaginatedPlaylist
with another classes, without having to duplicate it.
Acually, Paginated
extends ApiPlaylist
.
Is there a simple way to implement the methods from Paginated
to ApiPlaylist
without using extends
?
Something like
class ApiPlaylist [implements] Paginated{}
class ApiPost [implements] Paginated{}
class ApiPage [implements] Paginated{}
Thanks for your help !
2
Answers
As it already has been pointed out, the correct pattern to use is mixin or trait based composition.
The next provided example code demonstrates the usage of a function-based mixin which implements and applies the feature/behavior of "loadable tracks".
There’s a pattern for this in other OO languages called CRTP (curiously recurring template pattern), and you can do it in JavaScript with a function that creates classes.
I think it’s a lot easier to understand than the various ways of doing mixins, and causes fewer problems: