[JAVA] Explain the benefits of the State pattern with a movie rating

Implement the work that the user can see so that it can be sorted according to the movie rating system.

A movie rating system is an age-restricting regulation. G: All ages PG12: 12 years old and over R15 +: 15 years and over R18 +: 18 years old and over There are categories such as.

Class diagram

The state pattern is in the red frame, and it is used by the User. image.png The RatingSystem is used as an interface, and each restriction is implemented in G / PG12 / R15. The lack of R18 assumes that you are not dealing with R18 movies.

merit

-The age limit can be limited to the RatingSystem implementation class (G / PG / R15). (Implementation localization) ・ R18 movies will be handled, and even if specifications are added, it can be easily handled. (Easy to change)

Source code

interface RatingSystem

RatingSystem.java


package state.rating;

public interface RatingSystem {
    public boolean checkLimit(int age);
}

class G

G.java


package state.rating;

public class G implements RatingSystem {

    @Override
    public boolean checkLimit(int age) {
        return true;
    }
}

class PG12

PG12.java


package state.rating;

public class PG12 implements RatingSystem {

    @Override
    public boolean checkLimit(int age) {
        if(12 <= age)
            return true;
        return false;
    }
}

class R15

R15.java


package state.rating;

public class R15 implements RatingSystem {

    @Override
    public boolean checkLimit(int age) {
        if(15 <= age)
            return true;
        return false;
    }
}

class Movie

Movie.java


package state.rating;

public class Movie {
    private String _title;
    private RatingSystem _rating;

    public Movie(String title, RatingSystem rating) {
        _title = title;
        _rating = rating;
    }

    public String title() {
        return _title;
    }

    public boolean checkLimit(int age) {
        return _rating.checkLimit(age);
    }
}

class User

User.java


package state.rating;

public class User {
    private String _name;
    private int _age;

    User(String name, int age){
        _name = name;
        _age = age;
    }

    public String name() {
        return _name;
    }

    public int age() {
        return _age;
    }

    public void play(Movie movie) {
        System.out.println(movie.title() + "To play.");
        if(!movie.checkLimit(_age)) {
            System.out.println(" >>>Cannot play due to age limit error.");
            stop(movie);
        }
    }

    public void stop(Movie movie) {
        System.out.println(movie.title() + "To stop.");
    }
}

Main

Main.java


package state.rating;

public class Main {
    public static void main(String... args) {

        Movie torasan = new Movie("It's hard for a man, Torajiro Sunset, small burn", new G());
        Movie titan = new Movie("Attack on Titan ATTACK ON TITAN", new PG12());
        Movie jingi = new Movie("Battle Without Honor", new R15());

        User shinnosuke = new User("Shinnosuke Nohara", 5);
        System.out.println(shinnosuke.name());
        shinnosuke.play(torasan);
        shinnosuke.play(titan);
        shinnosuke.play(jingi);
        System.out.println();

        User taro = new User("Taro", 12);
        System.out.println(taro.name());
        taro.play(torasan);
        taro.play(titan);
        taro.play(jingi);
        System.out.println();

        User hanako = new User("Hanako", 17);
        System.out.println(hanako.name());
        hanako.play(torasan);
        hanako.play(titan);
        hanako.play(jingi);
        System.out.println();
    }
}

Execution result

Depending on the age of each user, movies that are caught in the age limit will be forcibly stopped.

Shinnosuke Nohara It's hard for a man to play Torajiro Sunset Small Burn. Play Attack on Titan ATTACK ON TITAN. \ >>> Cannot play due to age limit error. Stop Attack on Titan ATTACK ON TITAN. Play Battle Without Honor. \ >>> Cannot play due to age limit error. Stop the battle without honor.

Taro It's hard for a man to play Torajiro Sunset Small Burn. Play Attack on Titan ATTACK ON TITAN. Play Battle Without Honor. \ >>> Cannot play due to age limit error. Stop the battle without honor.

Hanako It's hard for a man to play Torajiro Sunset Small Burn. Play Attack on Titan ATTACK ON TITAN. Play Battle Without Honor.

Support for additional requirements for R18 +

In practice, specification changes are common. Here, we assume a situation where "additional requirements for handling R18 movies have occurred".

"I decided to handle R18 movies, so could you fix it?" If you are told, you should be able to change it immediately, right?

If it's a State pattern, add the R18 class and you're done. There is no need to search for and correct the age limit judgment process (if statement) from here and there.

class R18

R18.java


package state.rating;

public class R18 implements RatingSystem {

    @Override
    public boolean checkLimit(int age) {
        if(18 <= age)
            return true;
        return false;
    }
}

Main

Main.java


package state.rating;

public class Main {
    public static void main(String... args) {

        Movie torasan = new Movie("It's hard for a man, Torajiro Sunset, small burn", new G());
        Movie titan = new Movie("Attack on Titan ATTACK ON TITAN", new PG12());
        Movie jingi = new Movie("Battle Without Honor", new R15());
        Movie devil = new Movie("Devil's Poisonous Monster", new R18());   //* Additional notes

        User shinnosuke = new User("Shinnosuke Nohara", 5);
        System.out.println(shinnosuke.name());
        shinnosuke.play(torasan);
        shinnosuke.play(titan);
        shinnosuke.play(jingi);
        shinnosuke.play(devil); //* Additional notes
        System.out.println();

        User taro = new User("Taro", 12);
        System.out.println(taro.name());
        taro.play(torasan);
        taro.play(titan);
        taro.play(jingi);
        taro.play(devil);   //* Additional notes
        System.out.println();

        User hanako = new User("Hanako", 17);
        System.out.println(hanako.name());
        hanako.play(torasan);
        hanako.play(titan);
        hanako.play(jingi);
        hanako.play(devil); //* Additional notes
        System.out.println();

        //* Additional notes
        User isekai = new User("University student reincarnated in another world", 18);
        System.out.println(isekai.name());
        isekai.play(torasan);
        isekai.play(titan);
        isekai.play(jingi);
        isekai.play(devil);
        System.out.println();
    }
}

Execution result

Among the above Users, the one who can see the R18 movie (The Toxic Avenger Monster) is Only 18-year-old "university students reincarnated in another world".

Shinnosuke Nohara It's hard for a man to play Torajiro Sunset Small Burn. Play Attack on Titan ATTACK ON TITAN. \ >>> Cannot play due to age limit error. Stop Attack on Titan ATTACK ON TITAN. Play Battle Without Honor. \ >>> Cannot play due to age limit error. Stop the battle without honor. Play the devil's poisonous monster. \ >>> Cannot play due to age limit error. Stop the devil's poisonous monster.

Taro It's hard for a man to play Torajiro Sunset Small Burn. Play Attack on Titan ATTACK ON TITAN. Play Battle Without Honor. \ >>> Cannot play due to age limit error. Stop the battle without honor. Play the devil's poisonous monster. \ >>> Cannot play due to age limit error. Stop the devil's poisonous monster.

Hanako It's hard for a man to play Torajiro Sunset Small Burn. Play Attack on Titan ATTACK ON TITAN. Play Battle Without Honor. Play the devil's poisonous monster. \ >>> Cannot play due to age limit error. Stop the devil's poisonous monster.

University student reincarnated in another world It's hard for a man to play Torajiro Sunset Small Burn. Play Attack on Titan ATTACK ON TITAN. Play Battle Without Honor. Play the devil's poisonous monster.

Summary

・ Judgment and functions based on the status can be limited to a specific class. (Implementation localization) -It is relatively easy to add or modify specifications. (Easy to change)

Recommended Posts

Explain the benefits of the State pattern with a movie rating
Refactor the Decorator pattern implementation with a functional interface
The story of making a reverse proxy with ProxyServlet
Monitor the internal state of Java programs with Kubernetes
A story packed with the basics of Spring Boot (solved)
Check the operation of two roles with a chat application
Find the number of days in a month with Kotlin
The basics of the process of making a call with an Android app
The story of the first Rails app refactored with a self-made helper
Try to imitate the idea of a two-dimensional array with a one-dimensional array
A story about hitting the League Of Legends API with JAVA
A story that struggled with the introduction of Web Apple Pay
[Illustration] Finding the sum of coins with a recursive function [Ruby]
A memorandum of the FizzBuzz problem
Explain the column of Spree :: Product
A monad is a design pattern for "expressing the existence of side effects in a method with a return type".
Make a daily build of the TOPPERS kernel with Gitlab and Docker
Android application: Let's explain the mechanism of screen transition with simple code
Let's express the result of analyzing Java bytecode with a class diagram
(Note) Get a set of dependent library jars with the help of Gradle
What a Strategy pattern Factory, not a State
Create a jar file with the command
Check the contents of params with pry
Run a DMN with the Camunda DMN Engine
Extract a part of a string with Ruby
About the treatment of BigDecimal (with reflection)
I studied the State pattern and the Strategy pattern
Format the contents of LocalDate with DateTimeFormatter
Find the difference from a multiple of 10
How to get the ID of a user authenticated with Firebase in Swift
Send a notification to slack with the free version of sentry (using lambda)
Validate the identity token of a user authenticated with AWS Cognito in Java
A quick note on using jshell with the official Docker image of the JDK