Skip to content

Instantly share code, notes, and snippets.

@mcsee
Last active May 30, 2022 20:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mcsee/884f18fcdf4e1ada78a4ad095abb5c1e to your computer and use it in GitHub Desktop.
Save mcsee/884f18fcdf4e1ada78a4ad095abb5c1e to your computer and use it in GitHub Desktop.
class Age {
}
class AgeLessThan13 extends Age {
assertCanWatchPG13Movie() {
throw new Error("You are not allowed to watch this movie");
}
assertCanWatchAdultMovie() {
throw new Error("You are not allowed to watch this movie");
}
}
class AgeBetween13And18 extends Age {
assertCanWatchPG13Movie() {
// No Problem
}
assertCanWatchAdultMovie() {
throw new Error("You are not allowed to watch this movie");
}
}
class MovieRate {
// If language permits this should be declared abstract
// abstract assertCanWatch();
}
class PG13MovieRate extends MovieRate {
//2. Move every *IF Body* to the former abstraction
assertCanWatch(age) {
age.assertCanWatchPG13Movie()
}
}
class AdultsOnlyMovieRate extends MovieRate {
//2. Move every *IF Body* to the former abstraction
assertCanWatch(age) {
age.assertCanWatchAdultMovie()
}
}
class Movie {
constructor(rate) {
this._rate = rate; // Rate is now private
}
watchByMe(moviegoer) {
this._rate.assertCanWatch(moviegoer.age);
}
}
class Moviegoer {
constructor(age) {
this.age = age;
}
watchMovie(movie) {
movie.watchByMe(this);
}
}
let theExorcist = new Movie(new AdultsOnlyMovieRate());
let gremlins = new Movie(new PG13MovieRate());
let jane = new Moviegoer(new AgeLessThan13());
// jane.watchMovie(theExorcist);
// Jane cannot watch the exorcist since she is 12
// jane.watchMovie(gremlins);
// Jane cannot watch gremlins since she is 12
let joe = new Moviegoer(new AgeBetween13And18());
// joe.watchMovie(theExorcist);
// Joe cannot watch the exorcist since he is 16
joe.watchMovie(gremlins);
// Joe CAN watch gremlins since he is 16
@tombartling
Copy link

Thanks for this example. It really helps me better understand, but I have a question. How do you determine the arguments for each new Movie() and new Moviegoer()?

In this example you're hardcoding let jane = new Moviegoer(new AgeLessThan13());, but in the real world the moviegoer's age is just a value in the database. You've removed the if statements, but you're not showing the logic that actually replaces the work that the if statement does.

If jane.age = 12, one year from now it will be jane.age = 13 and let jane = new Moviegoer(new AgeLessThan13()) will be incorrect.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment