[Java] Explain the merits of State pattern by movie rating judgment

5 minute read

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

A movie rating system is a regulation that limits the age. G: All ages PG12: 12 years old or older R15+: Over 15 years old R18+: 18 years old or older There is a division such as.

Class diagram

The state pattern is inside the red frame, and it is in the form that User uses it. image.png Use RatingSystem as an interface, and implement each restriction in G/PG12/R15. The absence of R18 is an assumption that you are not handling R18 movies.

merit

  • You can limit the age limit to the implementation class (G/PG/R15) of RatingSystem. (Localization of implementation)
  • Since it handles R18 movies, it can be easily handled even if specifications are added. (Ease of 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() + "plays.");
        if(!movie.checkLimit(_age)) {
            System.out.println(" >>>Cannot play due to an age limitation error.");
            stop(movie);
        }
    }

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

Main (execute)

Main.java


package state.rating;

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

        Movie torasan = new Movie("Man is hard, Torajirou Yuyaki Koyaki", new G());
        Movie titan = new Movie("Attack on Titan ATTACK ON TITAN", new PG12());
        Movie jingi = new Movie("Battle without Religion", new R15());

        User shinnosuke = new User("Nohara Shinnosuke", 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 subject to age restrictions will be forced to stop.

Shinosuke Nohara The man is tough and plays Torajiro Yuyaki Kogaki. Play Attack on Titan ATTACK ON TITAN. >>> Cannot play due to an age restriction error. Stop Attack on Titan ATTACK ON TITAN. Play a battle without righteousness. >>> Cannot play due to an age restriction error. Stop the battle without righteousness.

Taro The man is tough and plays Torajiro Yuyaki Kogaki. Play Attack on Titan ATTACK ON TITAN. Play a battle without righteousness. >>> Cannot play due to an age restriction error. Stop the battle without righteousness.

Hanako The man is tough and plays Torajiro Yuyaki Kogaki. Play Attack on Titan ATTACK ON TITAN. Play a battle without righteousness.

Supporting additional requirements for #R18+ In practice, specification changes are common. Here, we assume a situation where “additional requirements have also occurred to handle R18 movies.”

“I decided to handle R18 movies, so could you repair it?” You should be able to change it immediately when asked?

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

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 (execute)

Main.java


package state.rating;

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

        Movie torasan = new Movie("Man is hard, Torajirou Yuyaki Koyaki", new G());
        Movie titan = new Movie("Attack on Titan ATTACK ON TITAN", new PG12());
        Movie jingi = new Movie("Battle without Religion", new R15());
        Movie devil = new Movie("Devil's Poisonous Monster", new R18()); // *Additional part

        User shinnosuke = new User("Nohara Shinnosuke", 5);
        System.out.println(shinnosuke.name());
        shinnosuke.play(torasan);
        shinnosuke.play(titan);
        shinnosuke.play(jingi);
        shinnosuke.play(devil); // * Addition
        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); // * Addition
        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); // * Addition
        System.out.println();

        // * Addition
        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

In the above User, you can see the R18 movie (devil’s poisonous monster), Only the “university student who has reincarnated in another world” who is 18 years old.

Shinosuke Nohara The man is tough and plays Torajiro Yuyaki Kogaki. Play Attack on Titan ATTACK ON TITAN. >>> Cannot play due to an age restriction error. Stop Attack on Titan ATTACK ON TITAN. Play a battle without righteousness. >>> Cannot play due to an age restriction error. Stop the battle without righteousness. Play the devil’s poisonous monsters. >>> Cannot play due to an age restriction error. Stop the devil’s poisonous monsters.

Taro The man is tough and plays Torajiro Yuyaki Kogaki. Play Attack on Titan ATTACK ON TITAN. Play a battle without righteousness. >>> Cannot play due to an age restriction error. Stop the battle without righteousness. Play the devil’s poisonous monsters. >>> Cannot play due to an age restriction error. Stop the devil’s poisonous monsters.

Hanako The man is tough and plays Torajiro Yuyaki Kogaki. Play Attack on Titan ATTACK ON TITAN. Play a battle without righteousness. Play the devil’s poisonous monsters. >>> Cannot play due to an age restriction error. Stop the devil’s poisonous monsters.

A college student who reincarnated in a different world The man is tough and plays Torajiro Yuyaki Kogaki. Play Attack on Titan ATTACK ON TITAN. Play a battle without righteousness. Play the devil’s poisonous monsters.

Summary

・It is possible to limit the judgments and functions by state to a specific class. (Localization of implementation)

  • It is relatively easy to add or modify specifications. (Ease of change)