ステータスモード(State Pattern)、ステータス管理動作


学習の動機.


CrewたちとBlack Jackのミッションについて話していたら、アヒルからステータスモードが聞こえてきました.ニオは今日、授業でステータスモードを運用する過程を示しました.不思議なので、自分で実現するために勉強しました.現在のミッションはプレイヤーが自分の状態を設定し、ゲーム終了後にプレイヤーが計算を行う.これを状態モードとして実施すれば、状態に応じて挙動を変えることができる.

じょうたいアレイ


定義:


オブジェクトの動作はステータスによって異なります.

<例>
1.テレビのリモコンはテレビの状態によって動作が変わります.
  • テレビがオン:音量増加ボタンを押すと音量を増加させることができます.
  • TVオフ:音量増加ボタンを押すと、何も起こりません.
  • ブログの文章の状態によって、書く時に他の人に見せることができず、コメントを残すこともできません.
  • 公開:クエリー、はい、
  • コメント可能
  • 非公開状態:作者以外は閲覧可能で、よく、
  • はコメントできません
  • ブラックタスクでは、ゲームの進行状態に応じて実施することができる.
  • 游戏状态:可接受卡,不能计算分数
  • ゲーム終了状態:カードを受け取ることができず、点数
  • を計算することができます.

    適用例


    オンラインレッスンを定義します.状態は3種類あります:記入して、記入して、密文.
    次の2つの機能が必要です.
    <機能実装リスト>
    1.コメント登録機能
    2.カリキュラム登録機能

  • コメントの登録機能작성완료 상태または비밀글이지만 해당 학생은 접근 가능한 상태の場合は、コメントを追加できます.そうでない場合は、コメントを作成できません.

  • カリキュラム登録機能작성 완료 상태작성중 상태、または비밀 글이지만 접근가능한 상태の場合は学習者を追加できますが、そうでない場合は学習者を受け入れることができません.
  • ステータスモード記述コードを適用しない場合は、このように記述できます.

    <適用前>

    public class OnlineCourse {
    
        public enum State {
            DRAFT, PUBLISHED, PRIVATE
        }
    
        private State state = State.DRAFT;
        private final List<String> reviews = new ArrayList<>();
        private final List<Student> students = new ArrayList<>();
    
        public void addReview(String review, Student student) {
            if (this.state == State.PUBLISHED) {
                this.reviews.add(review);
            } else if (this.state == State.PRIVATE && this.students.contains(student)) {
                this.reviews.add(review);
            } else {
                throw new UnsupportedOperationException("리뷰를 작성할 수 없습니다.");
            }
        }
    
        public void addStudent(Student student) {
            if (this.state == State.DRAFT || this.state == State.PUBLISHED) {
                this.students.add(student);
            } else if (this.state == State.PRIVATE && availableTo(student)) {
                this.students.add(student);
            } else {
                throw new UnsupportedOperationException("학생을 해당 수업에 추가할 수 없습니다.");
            }
    
            if (this.students.size() > 1) {
                this.state = State.PRIVATE;
            }
        }
    
    一見コードにif文が多すぎて、一つずつ条件を作って確認し、同じことを繰り返す必要があります.もしここに新しい状態が加わったら?すべてのコードは変更されます.これはメンテナンスに適さないコードになります.次に、ステータスモードを適用して、それを実装する方法を見てみましょう.

    <適用後>

    public class OnlineCourse {
        private State state = new Draft(this);
    
        private List<Student> students = new ArrayList<>();
        private List<String> reviews = new ArrayList<>();
    
        public void addStudent(Student student) {
            this.state.addStudent(student);
        }
    
        public void addReview(String review, Student student) {
            this.state.addReview(review, student);
        }
    
    上記のコードと同様に、stateをフィールドとし、stateで動作を受信して使用します.生徒を追加する場合、OnlineCourseで条件を確認するのではなく、その状態を示す実装体で機能を実現することができる.
    public interface State {
    
        void addReview(String review, Student student);
    
        void addStudent(Student student);
    }
    
    public class Draft implements State{
    
        private OnlineCourse onlineCourse;
    
        public Draft(OnlineCourse onlineCourse) {
            this.onlineCourse = onlineCourse;
        }
    
        @Override
        public void addReview(String review, Student student) {
            throw new UnsupportedOperationException("드래프트 상태에서는 리뷰를 남길 수 없습니다.");
        }
    
        @Override
        public void addStudent(Student student) {
            this.onlineCourse.getStudents().add(student);
            if (onlineCourse.getStudents().size() > 1) {
                onlineCourse.changeState(new Private(this.onlineCourse));
            }
        }
    }
    
    状態インタフェースでは抽象的に機能を実現し,各状態の実現体では対応する条件に従って機能を実現する.これにより、ステータスに応じて動作を変更するオブジェクトを作成できます.

    メリットとデメリット


    長所

  • 状態の動作に従って、各クラスで管理することができる.
  • の新しい状態を追加する場合、既存の状態に従って動作を変更する必要はありません.
  • 短所


    単純な状態で実施すると、過剰な工事が行われる可能性が高い

    整理する


    ブラックジャックの場合、状態によって機能が異なります.ステータスモードを使用すると、クラスは多くなりますが、ドアを減らすとメンテナンスに有利なコードが現れる可能性があります.

    Reference


    https://www.inflearn.com/course/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4