JavaにおけるStateデザインパターンとは何ですか?
ステートデザインパターンは、行動のデザインパターンの一つです。オブジェクトが内部の状態に基づいて振る舞いを変える必要がある場合に使用されます。
状態デザインパターン
もしオブジェクトの振る舞いをその状態に基づいて変えなければならない場合、オブジェクト内に状態変数を持つことができます。そして、状態に基づいて異なるアクションを実行するために、if-elseの条件文を使います。状態デザインパターンは、ContextとStateの実装を通じて、これを体系的かつ緩く結合された方法で実現するために使用されます。State Pattern Contextは、Stateの具象実装のうちの1つへのState参照を持つクラスです。Contextはリクエストを状態オブジェクトに転送して処理します。簡単な例を使って理解しましょう。テレビのリモコンを単一のボタンでアクションを実行するように実装したいとします。もし状態がONであれば、テレビをオンにし、状態がOFFであれば、テレビをオフにします。以下のようにif-elseの条件文を使って実装することができます。TVRemoteBasic.java
package com.scdev.design.state;
public class TVRemoteBasic {
private String state="";
public void setState(String state){
this.state=state;
}
public void doAction(){
if(state.equalsIgnoreCase("ON")){
System.out.println("TV is turned ON");
}else if(state.equalsIgnoreCase("OFF")){
System.out.println("TV is turned OFF");
}
}
public static void main(String args[]){
TVRemoteBasic remote = new TVRemoteBasic();
remote.setState("ON");
remote.doAction();
remote.setState("OFF");
remote.doAction();
}
}
クライアントのコードでは、リモートの状態を設定するために使用する特定の値を知る必要があることに注意してください。さらに、状態の数が増えると、実装とクライアントのコードの強い結合は非常に維持および拡張が難しくなるでしょう。この上記のTVリモコンの例を実装するために、Stateパターンを使用します。
ステートデザインパターンのインターフェース
まず第一に、異なる具象状態およびコンテキストクラスによって実装されるべき方法を定義するStateインターフェースを作成します。State.java
package com.scdev.design.state;
public interface State {
public void doAction();
}
状態デザインパターンの具体的な状態の実装
私たちの例では、TVをオンにするための状態と、オフにするための別の状態の2つがあります。したがって、これらの振る舞いに対する2つの具体的な状態実装を作成します。 TVStartState.java
package com.scdev.design.state;
public class TVStartState implements State {
@Override
public void doAction() {
System.out.println("TV is turned ON");
}
}
テレビの停止状態を示すTVStopState.java
package com.scdev.design.state;
public class TVStopState implements State {
@Override
public void doAction() {
System.out.println("TV is turned OFF");
}
}
今、内部状態に基づいて振る舞いを変えるContextオブジェクトを実装する準備ができました。
ステートデザインパターンのコンテキスト実装
TVContext.javaの日本語での同義語は次の通りです:
テレビコンテキスト.java
package com.scdev.design.state;
public class TVContext implements State {
private State tvState;
public void setState(State state) {
this.tvState=state;
}
public State getState() {
return this.tvState;
}
@Override
public void doAction() {
this.tvState.doAction();
}
}
現在の状態を保持し、その状態に応じてリクエストを状態の実装に転送するために、ContextはStateも実装していることに注意してください。
状態デザインパターンのテストプログラム
では、テレビリモコンの状態パターンの実装をテストするために、簡単なプログラムを書いてみましょう。TVRemote.java
package com.scdev.design.state;
public class TVRemote {
public static void main(String[] args) {
TVContext context = new TVContext();
State tvStartState = new TVStartState();
State tvStopState = new TVStopState();
context.setState(tvStartState);
context.doAction();
context.setState(tvStopState);
context.doAction();
}
}
上記のプログラムの出力は、状態パターンを使用せずに基本的なテレビリモコンの実装と同じです。
状態デザインパターンの利点
Stateパターンを使用して多様な振る舞いを実装することの利点は明らかです。エラーの可能性が少なく、さらなる振る舞いのための追加の状態を非常に簡単に追加することができます。これにより、コードがより強固で、メンテナンスが容易で柔軟性が向上します。また、Stateパターンは、このシナリオでのif-elseやswitch-caseの条件ロジックを避けるのに役立ちました。Stateパターンは、Strategyパターンに非常に似ていますので、JavaにおけるStrategyパターンも確認してみてください。これでStateデザインパターンについての内容は以上です。お気に召されたかと思います。