Javaアプリケーションで状態およびポリシーパターンを正しく使用するには、開発者は2つのパターンの違いを明確に知る必要があります。状態モードとポリシーモードの構造は非常に類似していますが、それらは開閉の原則に従って、固体設計の原則の「O」を表しますが、それらの意図は完全に異なります。 Javaのポリシーパターンは、関連するアルゴリズムのセットをカプセル化し、ランタイムの柔軟性を発信者に提供することです。発信者は、ポリシーを使用してコンテキストクラスを変更することなく、実行時に異なるアルゴリズムを選択できます。ポリシーパターンの使用の古典的な例には、暗号化アルゴリズムの実装、圧縮アルゴリズム、およびソートアルゴリズムが含まれます。一方、状態モードはオブジェクトを使用して、異なる状態で異なる動作を表示します。現実の世界のオブジェクトには状態もあり、それらは彼らの州に従って異なる行動をとるでしょう。たとえば、自動販売機はハスコイン状態でのみアイテムのみを販売できます。コインを詰めないと、商品を販売しません。これで、ポリシーモードと状態モードの違いをはっきりと見ることができます。その目的は異なります。状態モードは、オブジェクトが状態を管理するのに役立ちますが、ポリシーモードではクライアントが異なる動作を選択できます。見るのが簡単ではない別の違いは、誰が行動の変化を促進するかです。ポリシーモードでは、クライアント駆動型であり、コンテキスト情報にさまざまなポリシーを提供します。状態モードでは、状態移行はコンテキストまたは状態オブジェクト自体によって管理されます。同様に、状態オブジェクトの状態を変更する場合、コンテキストへの参照を保持する必要があります。つまり、自動販売機の場合、SetStateメソッドを呼び出して現在のコンテキスト状態を変更できます。一方、ポリシーオブジェクトはコンテキストへの参照を保持せず、そのクライアントは選択したポリシーをコンテキストに渡します。戦略と状態のパターンは、Javaのデザインパターンに関する最も簡単なインタビューの質問です。 Javaのデザインパターンに関するこの記事では、これを詳細に紹介します。 2つのモード間の類似点と相違点を調査します。これにより、2つのモードの理解が向上します。
状態モードとポリシーモードの類似点:
ポリシーパターンと状態パターンのUMLグラフを見ると、それらは非常によく似ています。状態モードでは、状態オブジェクトを使用して動作を変更するオブジェクトは、コンテキストオブジェクトと呼ばれます。同様に、戦略モードでは、戦略オブジェクトを使用して動作を変更するオブジェクトもコンテキストオブジェクトです。クライアントはコンテキストオブジェクトと対話することを忘れないでください。状態モードでは、コンテキストは状態オブジェクトのメソッドコールをプロキシにプロキシします。コンテキスト内の現在のオブジェクトは、特定の状態オブジェクトです。ポリシーモードでは、コンテキストはポリシーオブジェクトも動作します。このオブジェクトは、パラメーターとして渡されるか、コンテキストオブジェクトを作成するときに提供されます。
これら2つのコアJavaデザインパターンの類似点を見てみましょう。
状態モードとポリシーモードの両方は、それらの使用に影響を与えることなく新しい状態またはポリシーを簡単に追加できます。どちらも開閉の設計原則に従います。つまり、設計は拡張に開かれ、修正に閉じられています。これらの2つのモードでは、変更のためにコンテキストが閉じられており、新しい状態またはポリシーを追加します。他の状態のコンテキストオブジェクトを変更する必要はなく、小さな変更のみが必要です。状態モードのコンテキストオブジェクトが初期状態を持つように、ポリシーモードのコンテキストには通常、デフォルトのポリシーもあります。
状態モードは、異なる状態オブジェクトの方法で異なる動作をカプセル化しますが、ポリシーモードは異なるポリシーオブジェクトの方法で異なる動作をカプセル化します。
両方のパターンは、特定の動作を実現するために特定のサブクラスに依存しています。各特定のポリシーは、抽象的なポリシークラスから拡張され、各状態は、抽象クラスの状態またはサブクラスを表すために使用されるインターフェイスでもあります。
状態モードインスタンス
パブリッククラスWindowState {private string statevalue; public Windowstate(String StateValue){this.stateValue = stateValue; } public string getStateValue(){return statevalue; } public void setStateValue(string statevalue){this.statevalue = statevalue; } public void handle(){ /**異なる状態に従って異なる操作を実行し、状態を切り替えます* / if( "window" .equals(statevalue)){switchwindow(); this.statevalue = "full screen"; } else if( "fullscreen" .equals(statevalue)){switchfullscreen(); this.statevalue = "window"; }} private void switchwindow(){system.out.println( "ウィンドウ状態への切り替え"); } private void switchfullscreen(){system.out.println( "フルスクリーン状態への切り替え"); }} / ***状態の使用*/ public class windowcontext {private windowstate state; public windowcontext(window -state state){this.state = state; } public Windowstate getState(){return state; } public void setState(windowstate state){this.state = state; } public void switchState(){this.state.handle(); }} /**州(状態)動作モード*オブジェクトの状態とオブジェクトの動作の両方を変更*状態によると、動作を変更します*/ public class test {public static void main(String [] args){/**この例には2つの状態値しかありません。 context.switchstate(); context.switchstate(); context.switchstate(); context.switchstate(); context.switchstate(); context.switchstate(); }}印刷
ウィンドウ状態からフルスクリーン状態に切り替えます。
ポリシーモードの例
/ ***製品プロモーション*このカテゴリは次のとおりです。キャッシュコレクション*/パブリックインターフェイスicashsuper {double acceptcash(double money); } / ** *通常のキャッシュコレクション * @Author Stone * */ public class Cashnormal Implestion icashsuper {@override public double acceptcash(double money){return money; }} / ** *現金は割引で徴収されます * @author stone * */ public class cashrebate Implements icashsuper {private double rebate; // Public CashRebate(double Rebate){this.rebate = Rebate; } @Override public double Acceptcash(double money){return new BigDecimal(Money * Rebate / 10).Setscale(2、BigDecimal.Round_Half_up).DoubleValue(); }} / ** *現金付きの現金リベート * @Author Stone * */ Public Class Cashreturn Implements icashsuper {private double moneycondition; //キャッシュバック最小金額プライベートダブルリターンマネー。 //返品金額public Cashreturn(double Moneycondition、double returnmoney){this.moneycondition = moneycondition; this.returnmoney = returnmoney; } @Override public double Acceptcash(double money){//複数のリベートif(money> = moneycondition){return money -math.floor(money/moneycondition) * returnmoney; } else {return money; }}} / ***パスされたポリシークラスに基づいて対応する動作を実行*/ publicクラスCashContext {private icashsuperキャッシャー。 public CashContext(){} public CashContext(icashsuperキャッシャー){this.casher = casher; } public void setCasher(icashsuperキャッシャー){this.casher = casher; } //特定のポリシーオブジェクトによると、それを公開ダブルAcceptcash(double money)と呼ぶアルゴリズムの動作{return this.casher.acceptcash(money); }}パブリッククラステスト{public static void main(string [] args){double money = 998; //元の価格CashContext CashContext = new CashContext(new CashNormal()); System.out.println( "元の価格:" + cashContext.acceptcash(Money)); //一般戦略CashContext.setCasher(新しいCashRebate(8.5)); System.out.println( "85%オフ:" + CashContext.AcceptCash(Money)); //割引戦略85%CashContext.setCasher(新しいCashreturn(300、50)); system.out.println( "300を超える場合は50を返します:" + cashContext.acceptcash(money)); // 300を超える場合のキャッシュバック戦略50}}印刷
元の価格:998.0 85%オフ:848.3 50:848.0以上のリベート300以上
ポリシーモードと状態モードの違い
2つのパターンの構造は非常に似ていることがわかりましたが、まだ異なる部分を持っています。それらの間の重要な違いのいくつかを見てみましょう。
これは、Javaのポリシーパターンと状態パターンのすべての違いです。私が言ったように、それらはUMLダイアグラムで非常に似ているように見えますが、どちらも開閉とカプセルの行動の原則に従います。ポリシーモードは、アルゴリズムまたはポリシーをカプセル化するために使用されます。状態モードは、状態移行を管理するために使用されますが、実行時にパラメーターまたはコンビネーションオブジェクトとしてコンテキストオブジェクトに提供されます。