Java言語で学ぶリファクタリング入門 (結城 浩 著)の第9章<State/Strategeによるタイプコードの置き換え>について質問させていただきます。
以下にリファクタリング前後のコードと動作用のMainクラスを記載します。
Java
1 2//リファクタリング前 3public class Logger { 4 public static final int STATE_STOPPED = 0; 5 public static final int STATE_LOGGING = 1; 6 private int _state; 7 public Logger() { 8 _state = STATE_STOPPED; 9 } 10 public void start() { 11 switch (_state) { 12 case STATE_STOPPED: 13 System.out.println("** START LOGGING **"); 14 _state = STATE_LOGGING; 15 break; 16 case STATE_LOGGING: 17 /* Do nothing */ 18 break; 19 default: 20 System.out.println("Invalid state: " + _state); 21 } 22 } 23 public void stop() { 24 switch (_state) { 25 case STATE_STOPPED: 26 /* Do nothing */ 27 break; 28 case STATE_LOGGING: 29 System.out.println("** STOP LOGGING **"); 30 _state = STATE_STOPPED; 31 break; 32 default: 33 System.out.println("Invalid state: " + _state); 34 } 35 } 36 public void log(String info) { 37 switch (_state) { 38 case STATE_STOPPED: 39 System.out.println("Ignoring: " + info); 40 break; 41 case STATE_LOGGING: 42 System.out.println("Logging: " + info); 43 break; 44 default: 45 System.out.println("Invalid state: " + _state); 46 } 47 } 48} 49
Java
1//リファクタリング後 2public class Logger { 3 private enum State { 4 STOPPED { 5 @Override public void start() { 6 System.out.println("** START LOGGING **"); 7 } 8 @Override public void stop() { 9 /* Do nothing */ 10 } 11 @Override public void log(String info) { 12 System.out.println("Ignoring: " + info); 13 } 14 }, 15 16 LOGGING { 17 @Override public void start() { 18 /* Do nothing */ 19 } 20 @Override public void stop() { 21 System.out.println("** STOP LOGGING **"); 22 } 23 @Override public void log(String info) { 24 System.out.println("Logging: " + info); 25 } 26 }; 27 28 public abstract void start(); 29 public abstract void stop(); 30 public abstract void log(String info); 31 } 32 33 private State _state; 34 public Logger() { 35 setState(State.STOPPED); 36 } 37 public void setState(State state) { 38 _state = state; 39 } 40 public void start() { 41 _state.start(); 42 setState(State.LOGGING); 43 } 44 public void stop() { 45 _state.stop(); 46 setState(State.STOPPED); 47 } 48 public void log(String info) { 49 _state.log(info); 50 } 51} 52
Java
1//動作用Mainクラスはリファクタリング前後で変化せず 2 3public class Main { 4 public static void main(String[] args) { 5 Logger logger = new Logger(); 6 logger.log("information #1"); 7 8 logger.start(); 9 logger.log("information #2"); 10 11 logger.start(); 12 logger.log("information #3"); 13 14 logger.stop(); 15 logger.log("information #4"); 16 17 logger.stop(); 18 logger.log("information #5"); 19 } 20}
疑問点は以下になります。
①余分なインスタンスが作成されていい理由は?
リファクタリング前のコードは、メソッドが呼び出された時に、Stateが該当する状態だったら何もしないとなっています。
(STATE_LOGGINGならばstart()を呼び出した時、STATE_STOPPEDならばstop()を呼び出した時)
しかし、リファクタリング後のコードでは、setState(State.~)を実行して新たにインスタンスを作成してしまいます。
実行結果はリファクタリング前と変化はありませんが、余分なインスタンスが作成されてしまっていいのでしょうか?
②自己流でダメな点は?
以下は自分でリファクタリングを行ったコードです。
こちらもメソッドが呼び出される度に新たなインスタンスを作成していますが、①が問題ないのでしたら、このコードも問題ないのでしょうか?
Java
1 2//自己流リファクタリング後 3public class Logger { 4 private State _state; 5 public Logger() { 6 State state = new StateStopped(); 7 setState(state); 8 } 9 public void setState(State state) { 10 this._state = state; 11 } 12 public void start() { 13 _state.start(); 14 setState(new StateLogging()); 15 } 16 public void stop() { 17 _state.stop(); 18 setState(new StateStopped()); 19 } 20 public void log(String info) { 21 _state.log(info); 22 } 23} 24 25public abstract class State { 26 public abstract void start(); 27 public abstract void stop(); 28 public abstract void log(String info); 29} 30 31public class StateLogging extends State { 32 @Override public void start() { 33 System.out.println(); 34 } 35 @Override public void stop() { 36 System.out.println("** STOP LOGGING **"); 37 } 38 @Override public void log(String info) { 39 System.out.println("Logging: " + info); 40 } 41} 42 43public class StateStopped extends State { 44 @Override public void start() { 45 System.out.println("** START LOGGING **"); 46 } 47 @Override public void stop() { 48 System.out.println(); 49 } 50 @Override public void log(String info) { 51 System.out.println("Ignoring: " + info); 52 } 53}
以上になります。どなたかご教示お願い致します。
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。