web-dev-qa-db-ja.com

フラグに基づいてオン/オフする機能を実装するより良い方法

フラグに基づいてオン/オフを切り替えるオプションを備えた機能を実装しようとしています。私は次のようにしてやりすぎています。

public interface Feature {

    public interface EnableState {
        void execute();
    }
    public interface DisableState {
        void execute();
    }
}

プロジェクトの各機能がそれを利用して、機能を有効化または無効化する独自の方法を定義できるように、インターフェースを公開しました。

public class PlaySound implements Feature.DisableState, Feature.EnableState {

    //Feature is turned off by default
    boolean status = false;
    private static final PlaySound playSound = new PlaySound();

    public static PlaySound getInstance() {
        return playSound;
    }

    private PlaySound() {
        //Compute and update the feature status
    }


    Feature.DisableState disabledState = new Feature.DisableState() {

        @Override
        public void execute() {

        }
    };

    Feature.EnableState enabledState = new Feature.EnableState() {

        @Override
        public void execute() {

        }
    };

    @Override
    public void execute() {
        if(status) enabledState.execute();
        else disabledState.execute();
    }
}

やりすぎだと思います。コードの臭いは悪いですか?

代わりに、私はこのように実装すべきだったのですが、


if(featureEnabled) {
   //do something
} else {
   //do nothing
}

2
Tom Taylor

そのような機能が1つしかない場合は、選択肢があり、最も単純な方が適しています。

ただし、長持ちする機能フラグの問題は、機能の進化に伴って増加する傾向があることです。条件文を使用すると、次のようにエラーが発生しやすくなります。

if (featureAEnabled || feabtureBEnabled) {
    ...
    if (featureBEnable && !featureCEnabled) {
        ...
    } else 
        ...
}
... 

これが、より慎重に設計することが理にかなっている理由です。

  • これを行う1つの方法は、動作を提供するオブジェクトに戦略を注入することによる 戦略パターン です。
  • 別の方法では、あなたのケースで使用されているように見える状態パターン。

もちろん、単純なケースではやり過ぎかもしれません。しかし、利点は、条件式で複数の(場合によっては相互に依存する)フラグの組み合わせ効果を回避できることです。

最後に、この問題の調査に多くの時間を費やし、 機能の切り替え の概念を思いついた人もいます。彼らのアドバイスはまた、条件を回避し、フラグを照会するのではなく機能を注入することによってコントロールを反転させることです。

4
Christophe