ホームページ Java &#&チュートリアル Javaデザインパターンにおける戦略パターンと状態パターンの分析例

Javaデザインパターンにおける戦略パターンと状態パターンの分析例

Apr 17, 2023 pm 08:10 PM
java

利用シナリオ

ステートモード: オブジェクトの状態の変化に伴ってオブジェクトの動作が変化する場合、複数の判定条件を切り離し、動作の変化をカプセル化するため、オブジェクト動作インターフェイスを提供する抽象状態クラスを定義できます。特定の状態関連の動作は、そのサブクラスによって実装されます。

Strategy モード: 「戦略」という言葉はアルゴリズムに相当します。アルゴリズムを実際のシステムで動的に指定する必要があり、相互に置き換えることができる場合、アルゴリズムの呼び出しインターフェイスを抽象化できます。アルゴリズムは特定の戦略ロールによって実装されており、リスコフ置換原則に従って実装するには、親クラスが出現するあらゆる場所をそのサブクラスに置き換えることができ、これはビジネス ニーズを満たします。

比較

どちらも親クラスの標準呼び出しインターフェイスを抽象化していますが、特定の動作はサブクラスによって実装され、環境オブジェクトには親への参照も含まれています。クラスですが、これら 2 つのモードのアプリケーション シナリオはまったく異なります。例: ATM にお金を引き出しに行った場合、口座が凍結されている場合は、正常にお金を引き出すことができません。ここで、銀行口座には、凍結と凍結解除という少なくとも 2 つのステータスがあります。このようなビジネス ソリューションを解決するために戦略パターンを使用することは考えられないでしょう。もう 1 つの例は、ショッピング モールの割引です。さまざまな割引戦略があります。子供向けの商品は 30% オフ、高齢者の商品は 50% オフです。この問題は状態モードとは関係ありません。ここの商品には高齢者向けの商品があるとは言えません。状態と子状態です!

ATM 引き出しケース分析

設計された役割: レジ担当者、アカウント、ATM 機。

ユースケース図

わかりやすくするために、出金のユースケースを分析してみましょう。

Javaデザインパターンにおける戦略パターンと状態パターンの分析例

基本イベント パス

(1) 引き出し者は銀行カードを挿入し、パスワードを入力します;

(2) 引き出しを選択します操作して出金金額を入力します;

(3) お金を引き出すために現金の引き出しを待ちます。

この使用例では、引き出し者のアカウントが凍結されている場合、オプションのイベント パスが発生し、引き出しの使用例は終了します。

主要なビジネス要件は、ユーザーがお金を引き出すという事実であるため、ドメイン モデリングは、引き出し者と引き出し者を識別する 2 つのクラスから開始できます。引き出し者にはお金を引き出すというユースケースがあるだけではないことを考慮して、引き出しをトランザクションに一般化します。

モデリング

Javaデザインパターンにおける戦略パターンと状態パターンの分析例

ユースケースの実現

撤回: 基本的なイベント パスの実現。

Javaデザインパターンにおける戦略パターンと状態パターンの分析例

洗練されたドメイン モデル

ATMSystem 境界オブジェクトは、ユーザーとの対話を担当するコントローラー (ユーザーと対話するための ATM 操作インターフェイス) としてここで紹介されています。 ). Trade は、ユーザー トランザクションの処理を担当するクラスです。

引き出し者は銀行カードを挿入し、パスワードを入力します。ATMSystem は、口座情報を確認するメッセージを取引トランザクション クラスに渡す責任があります。取引は、渡された口座パスワードに基づいてユーザーが存在するかどうかを確認し、その後、処理完了メッセージを ATMSystem に渡し、境界オブジェクトがユーザーに反映されます。

分析モデルのいくつかのクラス

Javaデザインパターンにおける戦略パターンと状態パターンの分析例

##出金設計——申請ステータス モード

アカウントのステータスは凍結ステータスに分けられますおよびアクティベーションステータス。アカウントはアクティブ化されている場合は取引を行うことができますが、凍結されている場合は取引を行うことができません。アカウント認証時には現在のアカウントのステータスが返される必要がありますが、アカウントが凍結されている場合は、出金操作を実行すると直接エラー メッセージが返されます。状態図は次のように表されます:

Javaデザインパターンにおける戦略パターンと状態パターンの分析例

出金申請状態モード構造図:

Javaデザインパターンにおける戦略パターンと状態パターンの分析例

アカウント検証段階、アカウントが凍結状態の場合は、DeadAccount に直接戻ってすべてのトランザクションを拒否します。それ以外の場合は、ActiveAccount に戻って後続のトランザクションを処理します。

回路図コード:

実装を簡単にするため、境界オブジェクト ATMSystem はここでは省略されています。

ユーザーアカウント情報抽象クラス

/// <summary> /// 用户账号信息 /// </summary> public abstract class Account {     /// <summary>     /// 账号     /// </summary>     private string account;     /// <summary>     /// 密码     /// </summary>     private string pwd;     public abstract decimal getBalance(decimal d); }
ログイン後にコピー
##アカウントクラスの凍結
/// <summary> /// 冻结账户类 /// </summary> public class DeadAccount:Account {       public override decimal getBalance(decimal d)     {         return 0;     } }
ログイン後にコピー

#

激活账户类

/// <summary> /// 激活账户类 /// </summary> public class ActiveAccount:Account {     public override decimal getBalance(decimal d)     {         return d;     } }
ログイン後にコピー

交易类

/// <summary> /// 交易类 负责用户交易处理的类 /// </summary> public class Trade {     /// <summary>     /// 保存用户账号信息     /// </summary>     private Account account;     public Account VolidateLogin(Account a)     {                    //query the database to validate the user exists         //For Example         this.account = new DeadAccount();         return this.account;     }       /// <summary>     /// 商业逻辑 取款     /// </summary>     /// <param name="d"></param>     /// <returns></returns>     public decimal GetBalance(decimal d)     {         return this.account.getBalance(d);     }  }
ログイン後にコピー

用户类

/// <summary> /// 取款人 /// </summary> public class User {     /// <summary>     /// 用户账号信息     /// </summary>     private Account account;     /// <summary>     /// 交易处理类     /// </summary>     private Trade trade;       public User(Account a, Trade t)     {         this.account = a;         tthis.trade = t;     }     /// <summary>     /// 用户登录类     /// </summary>     public void Login()     {         trade.VolidateLogin(account);     }       /// <summary>     /// 取款     /// </summary>     /// <param name="d"></param>     /// <returns></returns>     public decimal GetBalance(decimal d)     {         return trade.GetBalance(d);     } }
ログイン後にコピー

客户端代码

class Client     {         static void Main(string[] args)         {             //开始用户取款,默认是激活账户             ActiveAccount aa = new ActiveAccount();             Trade t = new Trade();             User u = new User(aa,t);             //先登录,后取款             u.Login();             Console.WriteLine(u.GetBalance(100));             Console.ReadLine();         }     }
ログイン後にコピー

用户必须先登录(插入银行卡,输入密码,点确定),才能选择取款业务(选择取款)。登录之后,返回的账号对象作为trade类成员,当进行取款业务的时候直接引用该账号成员获得取款信息。如果该账号属于冻结账号,则直接返回0。否则返回取款的值。

商品折扣案例

案例描述:某家超市国庆节为了促销,某些类商品打折,比如运动鞋打8折、秋装打9折等,张三去购物为了一双运动鞋、一件秋装、一瓶洗发水。。。,张三买完东西回家,心想今天自己总共“赚”了多少钱?

案例分析:商家对于商品打折可能有很多策略,这里使用策略模式,封装商品打折策略,这样以便以后扩展了打折策略,不用去修改原来的代码,具有很好的灵活性。

模式涉及的角色:

抽象策略角色:通常由一个接口或者抽象实现;

具体策略角色:包装了相关的算法和行为;

环境角色:包含抽象策略角色的引用,最终供用户使用。

商品折扣案例设计图

Javaデザインパターンにおける戦略パターンと状態パターンの分析例

顾客购物涉及到的角色有:购物车、商品、收银台、抽象策略角色和具体策略角色。

购物车:是摆放商品的容器,提供添加和删除操作;

商品:商品实体,有类型,商品名、价格等属性;

收银台:负责收钱,主要是计算顾客购买所有商品的价格和折扣总额;

抽象策略角色:提供折扣策略接口。

具体策略角色:实现具体折扣算法。

商品折扣示意代码:

/// <summary> /// 具体商品类 /// </summary> public class goods {     /// <summary>     /// 商品类型     /// </summary>     public string Type     {         set;         get;     }       /// <summary>     /// 商品名称     /// </summary>     public string Name     {         get;         set;     }         /// <summary>     /// 商品价格     /// </summary>     public decimal Price     {         get;         set;     }   }
ログイン後にコピー

抽象策略角色

/// <summary> /// 抽象策略接口 /// </summary> public interface IDiscountStrategy {     decimal GetDiscount(goods g); }
ログイン後にコピー

具体策略角色

/// <summary> /// 秋装打折策略 /// </summary> public class AutumnDressDiscountStrategy:IDiscountStrategy {     #region IDiscountStrategy Members       public decimal GetDiscount(goods g)     {         return (decimal)0.9 * g.Price;     }       #endregion }     /// <summary> /// 运动鞋打折策略 /// </summary> public class SportShoesDiscountStrategy:IDiscountStrategy {     #region IDiscountStrategy Members       public decimal GetDiscount(goods g)     {         return g.Price * (decimal)0.8;     }       #endregion }
ログイン後にコピー

购物车

 

/// <summary> /// 购物车类 负责商品的维护 /// </summary> public class ShoppingCar {     private List<goods> goodsList=new List<goods>();       /// <summary>     /// 将商品加入到购物车     /// </summary>     /// <param name="g"></param>     public void AddGoods(goods g)     {         goodsList.Add(g);     }       /// <summary>     /// 将商品从购物车当中移除     /// </summary>     /// <param name="g"></param>     public void RemoveGoods(goods g)     {         goodsList.Remove(g);     }       public List<goods> GoodsList     {         get         {             return goodsList;         }     }   }
ログイン後にコピー

收银台角色

/// <summary> /// 收银台 /// </summary> public class CashierDesk {     /// <summary>     /// 购物车     /// </summary>     private ShoppingCar shoppingCar;     /// <summary>     /// 策略字典     /// </summary>     private Dictionary<string, IDiscountStrategy> strategies;       public CashierDesk(ShoppingCar sc, Dictionary<string, IDiscountStrategy> s)     {         this.shoppingCar = sc;         this.strategies = s;     }       /// <summary>     /// 获得所有商品的价格     /// </summary>     /// <returns></returns>     public decimal GetTotalPrice()     {         return shoppingCar.GoodsList.Sum(p => p.Price);     }       /// <summary>     /// 获得所有商品的总的折扣     /// </summary>     /// <returns></returns>     public decimal GetTotalDiscount()     {         decimal sum = 0;         IDiscountStrategy idiscountStrategy;         foreach (goods g in shoppingCar.GoodsList)         {             idiscountStrategy=strategies.SingleOrDefault(p => p.Key == g.Type).Value;             if (idiscountStrategy != null)             {                 sum += idiscountStrategy.GetDiscount(g);             }         }         return sum;     } }
ログイン後にコピー

客户端代码

class Client     {         static void Main(string[] args)         {             ShoppingCar sc = new ShoppingCar();             Dictionary<string, IDiscountStrategy> discountD = new Dictionary<string, IDiscountStrategy>();             //向购物车中加入商品             sc.AddGoods(new goods {Name="NIKE鞋 ",Price=100,Type="运动鞋" });             sc.AddGoods(new goods { Name = "秋装", Price = 200, Type = "秋装" });             sc.AddGoods(new goods { Name = "苹果", Price = 300, Type = "水果" });             //配置折扣策略             discountD.Add("运动鞋", new SportShoesDiscountStrategy());             discountD.Add("秋装", new AutumnDressDiscountStrategy());             CashierDesk cd = new CashierDesk(sc, discountD);             //得到所有商品总价             Console.WriteLine(cd.GetTotalPrice());             //得到所有商品折扣价             Console.WriteLine(cd.GetTotalDiscount());               Console.ReadLine();         }     }
ログイン後にコピー

策略模式优点与缺点:

优点

封装了算法不稳定性,易于以后业务策略的扩展。

缺点

每种策略对应于一个具体策略角色类,会增加系统需要维护的类的数量。

以上がJavaデザインパターンにおける戦略パターンと状態パターンの分析例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Javaの平方根 Javaの平方根 Aug 30, 2024 pm 04:26 PM

Java の平方根のガイド。ここでは、Java で平方根がどのように機能するかを、例とそのコード実装をそれぞれ示して説明します。

Javaの完全数 Javaの完全数 Aug 30, 2024 pm 04:28 PM

Java における完全数のガイド。ここでは、定義、Java で完全数を確認する方法、コード実装の例について説明します。

Java の乱数ジェネレーター Java の乱数ジェネレーター Aug 30, 2024 pm 04:27 PM

Java の乱数ジェネレーターのガイド。ここでは、Java の関数について例を挙げて説明し、2 つの異なるジェネレーターについて例を挙げて説明します。

ジャワのウェカ ジャワのウェカ Aug 30, 2024 pm 04:28 PM

Java の Weka へのガイド。ここでは、weka java の概要、使い方、プラットフォームの種類、利点について例を交えて説明します。

Javaのアームストロング数 Javaのアームストロング数 Aug 30, 2024 pm 04:26 PM

Java のアームストロング番号に関するガイド。ここでは、Java でのアームストロング数の概要とコードの一部について説明します。

Javaのスミス番号 Javaのスミス番号 Aug 30, 2024 pm 04:28 PM

Java のスミス番号のガイド。ここでは定義、Java でスミス番号を確認する方法について説明します。コード実装の例。

Java Springのインタビューの質問 Java Springのインタビューの質問 Aug 30, 2024 pm 04:29 PM

この記事では、Java Spring の面接で最もよく聞かれる質問とその詳細な回答をまとめました。面接を突破できるように。

Java 8 Stream Foreachから休憩または戻ってきますか? Java 8 Stream Foreachから休憩または戻ってきますか? Feb 07, 2025 pm 12:09 PM

Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです

See all articles