Go和Java实现策略模式

Go和Java实现策略模式

模拟多种营销类型优惠券,折扣⾦额计算策略场景。

1、策略模式

在策略模式中一个类的行为或其算法可以在运行时更改,这种类型的设计模式属于行为型模式。

在策略模式定义了一系列算法或策略,并将每个算法封装在独立的类中,使得它们可以互相替换。通过使用策略模

式,可以在运行时根据需要选择不同的算法,而不需要修改客户端代码。

在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象,策略对象改变

context 对象的执行算法。

  • 意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

  • 主要解决:在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。

  • 何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。

  • 如何解决:将这些算法封装成一个一个的类,任意地替换。

  • 关键代码:实现同一个接口。

  • 应用实例:1、诸葛亮的锦囊妙计,每一个锦囊就是一个策略。 2、旅行的出游方式,选择骑自行车、坐汽

    车,每一种旅行方式都是一个策略。 3、JAVA AWT 中的 LayoutManager。

  • 优点:1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。

  • 缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。

  • 使用场景:1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动

    态地让一个对象在许多行为中选择一种行为。 2、一个系统需要动态地在几种算法中选择一种。 3、如果一个

    对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。

  • 注意事项:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。

  • 策略模式包含以下几个核心角色:

    环境(Context):维护一个对策略对象的引用,负责将客户端请求委派给具体的策略对象执行。环境类可以

    通过依赖注入、简单工厂等方式来获取具体策略对象。

    抽象策略(Abstract Strategy):定义了策略对象的公共接口或抽象类,规定了具体策略类必须实现的方法。

    具体策略(Concrete Strategy):实现了抽象策略定义的接口或抽象类,包含了具体的算法实现。

  • 适用性:

    许多相关的类仅仅是行为有异,策略提供了一种用多个行为中的一个行为来配置一个类的方法。

    需要使用一个算法的不同变体。

    算法使用客户不应该知道的数据,可使用策略模式以避免暴露复杂的、与算法相关的数据结构。

    一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,将相关的条件分支移入

    它们各自的 Strategy 类中以代替这些条件语句。

策略模式通过将算法与使用算法的代码解耦,提供了一种动态选择不同算法的方法。客户端代码不需要知道具体的

算法细节,而是通过调用环境类来使用所选择的策略。

2、Go实现策略模式

package strategy

// 这里模拟多种营销类型优惠券,折扣⾦额计算
// 计算接口
type ICouponDiscount interface {
   // 参数1为正常支付、直减、满减、折扣、N元购
   // 参数2为金额
   // 返回为优惠后金额
   DiscountAmount(interface{}, float64) float64
}
package strategy

import (
   "reflect"
)

// ==========满减==========
type MJCouponDiscount struct {
}

// 这里参数为map,couponInfo["full"]=300,couponInfo["reduction"]=50
// 满多少钱减多少钱
func (mjCouponDiscount *MJCouponDiscount) DiscountAmount(couponInfo interface{}, price float64) float64 {
   var full float64
   var reduction float64
   if reflect.ValueOf(couponInfo).Kind() == reflect.Map {
      valueMap := reflect.ValueOf(couponInfo)
      full = valueMap.MapIndex(reflect.ValueOf("full")).Float()
      reduction = valueMap.MapIndex(reflect.ValueOf("reduction")).Float()
   }
   if price < full {
      return price
   } else {
      return price - reduction
   }
}
package strategy

// ==========正常支付,不进行任何优惠==========
type NormalCouponDiscount struct {

}

// 正常支付
func (normalCouponDiscount *NormalCouponDiscount) DiscountAmount(couponInfo interface{}, price float64) float64 {
   return price
}
package strategy

// ==========N元购买==========
type NYGCouponDiscount struct {
}

// 打折
func (nygCouponDiscount *NYGCouponDiscount) DiscountAmount(couponInfo interface{}, price float64) float64 {
   return couponInfo.(float64)
}
package strategy

// ==========直减====================
type ZJCouponDiscount struct {
}

// 直接减多少钱
func (zjCouponDiscount *ZJCouponDiscount) DiscountAmount(couponInfo interface{}, price float64) float64 {
   return price - couponInfo.(float64)
}
package strategy

// ==========折扣==========
type ZKCouponDiscount struct {
}

// 打折
func (zkCouponDiscount *ZKCouponDiscount) DiscountAmount(couponInfo interface{}, price float64) float64 {
   return price * couponInfo.(float64)
}
package strategy

// context
type CouponDiscountContext struct {
	ICouponDiscount
}

func (couponDiscountContext *CouponDiscountContext) DoMethod(couponInfo interface{}, price float64) float64 {
	return couponDiscountContext.ICouponDiscount.DiscountAmount(couponInfo, price)
}
package main

import (
   "fmt"
   . "proj/strategy"
)

func main() {

   var fullPrice float64 = 400
   var context CouponDiscountContext
   var price float64

   // ==========满减==========
   var couponInfo map[string]float64
   couponInfo = make(map[string]float64)
   couponInfo["full"] = 300
   couponInfo["reduction"] = 50
   context = CouponDiscountContext{ICouponDiscount: &MJCouponDiscount{}}
   price = context.DiscountAmount(couponInfo, fullPrice)
   fmt.Println("满减 price: ", price)

   // ==========直减==========
   var reduction float64 = 100
   context = CouponDiscountContext{ICouponDiscount: &ZJCouponDiscount{}}
   price = context.DiscountAmount(reduction, fullPrice)
   fmt.Println("直减 price: ", price)

   // ==========打折==========
   var discounts float64 = 0.8
   context = CouponDiscountContext{ICouponDiscount: &ZKCouponDiscount{}}
   price = context.DiscountAmount(discounts, fullPrice)
   fmt.Println("打折 price: ", price)

   // ==========N元购==========
   var ny float64 = 9.9
   context = CouponDiscountContext{ICouponDiscount: &NYGCouponDiscount{}}
   price = context.DiscountAmount(ny, fullPrice)
   fmt.Println("N元购 price: ", price)

   // ==========正常支付==========
   var normal float64 = 0
   context = CouponDiscountContext{ICouponDiscount: &NormalCouponDiscount{}}
   price = context.DiscountAmount(normal, fullPrice)
   fmt.Println("正常支付 price: ", price)
}
# 程序输出
满减 price:  350
直减 price:  300
打折 price:  320
N元购 price:  9.9
正常支付 price:  400

3、Java实现策略模式

package com.strategy;

// 这里模拟多种营销类型优惠券,折扣⾦额计算
// 计算接口
public interface ICouponDiscount<T> {
    // 参数1为正常支付、直减、满减、折扣、N元购
    // 参数2为金额
    // 返回为优惠后金额
    double discountAmount(T couponInfo, Double price);
}
package com.strategy;

import java.util.Map;

// ==========满减==========
public class MJCouponDiscount implements ICouponDiscount<Map<String, Double>> {

    // 这里参数为map,couponInfo["full"]=300,couponInfo["reduction"]=50
    // 满多少钱减多少钱
    @Override
    public double discountAmount(Map<String, Double> couponInfo, Double price) {
        double full = couponInfo.get("full");
        double reduction = couponInfo.get("reduction");
        if (price > full) {
            return price - reduction;
        } else {
            return price;
        }
    }
}
package com.strategy;

// ==========正常支付,不进行任何优惠==========
public class NormalCouponDiscount implements ICouponDiscount<Double> {

    // 正常支付
    @Override
    public double discountAmount(Double couponInfo, Double price) {
        return price;
    }
}
package com.strategy;

// ==========N元购买==========
public class NYGCouponDiscount implements ICouponDiscount<Double>{

    // 打折
    @Override
    public double discountAmount(Double couponInfo, Double price) {
        return couponInfo;
    }
}
package com.strategy;

// ==========直减====================
public class ZJCouponDiscount implements ICouponDiscount<Double> {

    // 直接减多少钱
    @Override
    public double discountAmount(Double couponInfo, Double price) {
        return price - couponInfo;
    }
}
package com.strategy;

// ==========折扣==========
public class ZKCouponDiscount implements ICouponDiscount<Double> {

    // 打折
    @Override
    public double discountAmount(Double couponInfo, Double price) {
        return price * couponInfo;
    }
}
package com.strategy;

// context
public class CouponDiscountContext<T> {

    private ICouponDiscount<T> iCouponDiscount;

    public CouponDiscountContext(ICouponDiscount<T> iCouponDiscount) {
        this.iCouponDiscount = iCouponDiscount;
    }

    public double discountAmount(T couponInfo, Double price) {
        return this.iCouponDiscount.discountAmount(couponInfo, price);
    }
}
package com.strategy;

import java.util.HashMap;
import java.util.Map;

public class Test {

    public static void main(String[] args) {

        Double fullPrice = new Double(400);
        Double price = new Double(0);

        // ==========满减==========
        Map<String, Double> couponInfo = new HashMap<>();
        couponInfo.put("full", new Double(300));
        couponInfo.put("reduction", new Double(50));
        CouponDiscountContext<Map<String, Double>> couponDiscountContext = new CouponDiscountContext<>(new MJCouponDiscount());
        price = couponDiscountContext.discountAmount(couponInfo, fullPrice);
        System.out.println("满减 price: " + price);

        // ==========直减==========
        Double reduction = new Double(100);
        CouponDiscountContext<Double> couponDiscountContext1 = new CouponDiscountContext<>(new ZJCouponDiscount());
        price = couponDiscountContext1.discountAmount(reduction, fullPrice);
        System.out.println("直减 price: " + price);

        // ==========打折==========
        Double discounts = new Double(0.8);
        CouponDiscountContext<Double> couponDiscountContext2 = new CouponDiscountContext<>(new ZKCouponDiscount());
        price = couponDiscountContext2.discountAmount(discounts, fullPrice);
        System.out.println("打折 price: " + price);

        // ==========N元购==========
        Double ny = new Double(9.9);
        CouponDiscountContext<Double> couponDiscountContext3 = new CouponDiscountContext<>(new NYGCouponDiscount());
        price = couponDiscountContext3.discountAmount(ny, fullPrice);
        System.out.println("N元购 price: " + price);

        // ==========正常支付==========
        Double normal = new Double(0);
        CouponDiscountContext<Double> couponDiscountContext4 = new CouponDiscountContext<>(new NormalCouponDiscount());
        price = couponDiscountContext4.discountAmount(normal, fullPrice);
        System.out.println("正常支付 price: " + price);
    }
}
# 程序输出
满减 price: 350.0
直减 price: 300.0
打折 price: 320.0
N元购 price: 9.9
正常支付 price: 400.0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值