Last active
May 30, 2022 20:25
-
-
Save mcsee/884f18fcdf4e1ada78a4ad095abb5c1e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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 bejane.age = 13
andlet jane = new Moviegoer(new AgeLessThan13())
will be incorrect.