1.戦略モードの概要
ストラテジーモードの定義:個別にカプセル化されたアルゴリズムファミリーの定義を指し、相互に置き換えることができます。このモードでは、アルゴリズムの変更がアルゴリズムのユーザーに影響を与えません。
ストラテジーモードの利点:if ... else ...およびswitchステートメントの複数の分岐を回避できます
戦略モードのシナリオを使用する:
- システムに多くのクラスがあり、それらの違いがそれらの動作にある場合。
- システムは、いくつかのアルゴリズムの1つを動的に選択する必要があります。
戦略モードの場合:
JDKのComparatorインターフェースのintcompare(T o1、T o2);メソッド。照合ルールは配列とTreeMapでカスタマイズできます。
Arrays.class
TreeMap.class
- Springのリソースインターフェイス
- SpringのInstantiationStrategyインターフェースは、主にクラスのストラテジーを初期化します。2つのストラテジー実装クラスがあり、等しくはありませんが継承されます(ストラテジーモードの異なるストラテジーも継承できます)。
CglibSubclassingInstantiationStrategy:
Cglib SimpleInstantiationStrategyの最初の方法:JDKの最初の方法
クラス図
2つの単純なコードケース
事例:何かを購入する活動がある場合、バウチャー、キャッシュバック、グループ参加などの量を減らすための戦略があります。
優先戦略抽象インターフェース
public interface PromotionStrategy {
/**
* 执行优惠
*/
void doPromotion();
}
値下げなし
public class EmptyStrategy implements PromotionStrategy{
@Override
public void doPromotion() {
System.out.println("无促销活动");
}
}
バウチャー
public class CouponStrategy implements PromotionStrategy {
@Override
public void doPromotion() {
System.out.println("领取优惠券,课程的价格直接减去优惠券面值抵扣");
}
}
キャッシュバック
public class CashbackStrategy implements PromotionStrategy {
@Override
public void doPromotion() {
System.out.println("返现促销,返回的金额转到支付宝账号");
}
}
グループに参加する
public class GroupBuyStrategy implements PromotionStrategy{
@Override
public void doPromotion() {
System.out.println("拼团,满20人成团,全团享受团购价格");
}
}
プロモーション
public class PromotionActivity {
PromotionStrategy promotionStrategy;
public PromotionActivity(PromotionStrategy promotionStrategy){
this.promotionStrategy = promotionStrategy;
}
/**
* 执行优惠活动
*/
public void execute(){
this.promotionStrategy.doPromotion();
}
}
1つテストする
public static void main(String[] args) {
// 618优惠券活动
PromotionActivity activity618 = new PromotionActivity(new CouponStrategy());
activity618.execute();
// 双11返现活动
PromotionActivity activity1111 = new PromotionActivity(new CashbackStrategy());
activity1111.execute();
}
2つテストする
public static void main(String[] args) {
PromotionActivity promotionActivity = null;
String promotionKey = "COUPON";
if (StringUtils.equals(promotionKey,"COUPON")){
promotionActivity = new PromotionActivity(new CouponStrategy());
}else if (StringUtils.equals(promotionKey,"CASHBACK")){
promotionActivity = new PromotionActivity(new CashbackStrategy());
} // .......
promotionActivity.execute();
}
検出を実装するだけで、シングルトンモード+シンプルファクトリモードを使用してコードを簡略化し、一意の記号を使用して戦略を選択することもできます。
ファクトリクラス
public class PromotionStrategyFactory {
private static final Map<String,PromotionStrategy> PROMOTION_STRATEGY_MAP = new ConcurrentHashMap<String,PromotionStrategy>();
private static final PromotionStrategy NON_PROMOTION = new EmptyStrategy();
static {
PROMOTION_STRATEGY_MAP.put(PromotionKey.COUPON,new CouponStrategy());
PROMOTION_STRATEGY_MAP.put(PromotionKey.CASHBACK,new CashbackStrategy());
PROMOTION_STRATEGY_MAP.put(PromotionKey.GROUPBUY,new GroupBuyStrategy());
}
private PromotionStrategyFactory(){
}
public static PromotionStrategy getPromotionStrategy(String promotionKey){
PromotionStrategy promotionStrategy = PROMOTION_STRATEGY_MAP.get(promotionKey);
return promotionStrategy == null ? NON_PROMOTION : promotionStrategy;
}
private interface PromotionKey{
String COUPON = "COUPON";
String CASHBACK = "CASHBACK";
String GROUPBUY = "GROUPBUY";
}
}
テスト
public static void main(String[] args) {
String promotionKey = "GROUPBUY";
PromotionActivity promotionActivity = new PromotionActivity(PromotionStrategyFactory.getPromotionStrategy(promotionKey));
promotionActivity.execute();
}
クラス構造図を添付する
3つの単純なコード2つのケース
ケース:ユーザーは注文時に複数の支払いチャネルを選択できます
支払い抽象クラス
public abstract class Payment {
/**
* 支付信息
* @return
*/
public abstract String getName();
/**
* 余额
* @param uid
* @return
*/
protected abstract double queryBalance(String uid);
/**
* 支付
* @param uid
* @param amount
* @return
*/
public MsgResult pay(String uid,double amount){
if (queryBalance(uid) < amount){
return new MsgResult(500,"支付失败","余额不足");
}else {
return new MsgResult(200,"支付成功","支付金额: " + amount);
}
}
}
Ali-Payで支払う
public class AliPay extends Payment{
@Override
public String getName() {
return "支付宝";
}
@Override
protected double queryBalance(String uid) {
return 900;
}
}
Jingdong Baitiao
public class JDPay extends Payment{
@Override
public String getName() {
return "京东白条";
}
@Override
protected double queryBalance(String uid) {
return 500;
}
}
銀聯の支払い
public class UnionPay extends Payment {
@Override
public String getName() {
return "银联支付";
}
@Override
protected double queryBalance(String uid) {
return 120;
}
}
WeChat Pay
public class WechatPay extends Payment {
@Override
public String getName() {
return "微信支付";
}
@Override
protected double queryBalance(String uid) {
return 256;
}
}
返信メッセージ
public class MsgResult {
private int code;
private Object data;
private String msg;
public MsgResult(int code, Object data, String msg) {
this.code = code;
this.data = data;
this.msg = msg;
}
@Override
public String toString() {
return "MsgResult{" +
"code=" + code +
", data=" + data +
", msg='" + msg + '\'' +
'}';
}
}
注文クラス
public class Order {
private String uid;
private String orderId;
private double amount;
public Order(String uid, String orderId, double amount) {
this.uid = uid;
this.orderId = orderId;
this.amount = amount;
}
public MsgResult pay(String payKey){
Payment payment = PayStrategy.get(payKey);
System.out.println("欢迎使用" + payment.getName());
System.out.println("本次交易金额为:" + amount + ",开始扣款...");
return payment.pay(uid,amount);
}
@Override
public String toString() {
return "Order{" +
"uid='" + uid + '\'' +
", orderId='" + orderId + '\'' +
", amount=" + amount +
'}';
}
}
決済戦略ファクトリー
public class PayStrategy {
public static final String ALI_PAY = "AliPay";
public static final String JD_PAY = "JDPay";
public static final String WECHAT_PAY = "WchatPay";
public static final String UNION_PAY = "UnionPay";
public static final String DEFAULT_PAY = "AliPay";
private static Map<String,Payment> payStrategy = new HashMap<String,Payment>();
static {
payStrategy.put(ALI_PAY,new AliPay());
payStrategy.put(JD_PAY,new JDPay());
payStrategy.put(WECHAT_PAY,new WechatPay());
payStrategy.put(UNION_PAY,new UnionPay());
payStrategy.put(DEFAULT_PAY,new AliPay());
}
public static Payment get(String payKey){
if (!payStrategy.containsKey(payKey)){
return payStrategy.get(DEFAULT_PAY);
}
return payStrategy.get(payKey);
}
}
テスト
public class PayStrategyTest {
public static void main(String[] args) {
Order order = new Order("1", "2021110", 1342.45);
MsgResult result = order.pay(PayStrategy.ALI_PAY);
System.out.println(result);
}
}
クラス構造図を添付します。
4、まとめ
戦略モードの利点:
- ストラテジーモードは、開閉の原則に準拠しています。
- if ... else ...ステートメント、switchステートメントなど、複数の条件付き転送ステートメントの使用は避けてください。
- 戦略モードを使用すると、アルゴリズムの機密性とセキュリティを向上させることができます。
戦略モードのデメリット:
- クライアントはすべての戦略を知っている必要があり、ユーザーは使用する戦略クラスを決定します。
- コードには多くの戦略クラスがあり、メンテナンスが難しくなります。
何を待っていますか?linuxC / C ++言語交換グループをお勧めします:[ 1106675687 ]グループファイルで共有したほうがよいと思う学習本とビデオ資料をいくつかまとめました。必要に応じて追加できます。トップ100がグループに入り、C / C ++の追加コピー、199に相当するLinux資料(ビデオチュートリアル、電子書籍、実際の戦闘プロジェクトおよびコード)が含まれ、次の部分が表示されます。