当前位置: 首页 > wzjs >正文

赤峰网站策划广东省建设安全监督站的网站

赤峰网站策划,广东省建设安全监督站的网站,贵阳网站商城建设,体彩网站建设引言:为什么你的代码像一棵巨大的圣诞树? 想象一下,你正在为你的电商平台开发一个订单价格计算模块。最初,需求很简单:商品原价就是最终价格。但很快,业务部门提出了新的需求: 新用户享受 9 折…
引言:为什么你的代码像一棵巨大的圣诞树?

想象一下,你正在为你的电商平台开发一个订单价格计算模块。最初,需求很简单:商品原价就是最终价格。但很快,业务部门提出了新的需求:

  • 新用户享受 9 折优惠。
  • VIP 用户享受 8 折优惠。
  • 大促活动期间,全场 7 折。

你很自然地写出了这样的代码:

func CalculatePrice(userType string, isPromotion bool, price float64) float64 {if userType == "NewUser" {return price * 0.9} else if userType == "VIP" {return price * 0.8} else if isPromotion {return price * 0.7}return price // 默认无折扣
}

这段代码看起来没问题,但如果你再想想未来可能的需求:会员日 6 折、积分抵扣、优惠券叠加……你的 if/else 链会像一棵不断长大的圣诞树,挂满了各种复杂的逻辑分支。每一次新需求的到来,你都得修改这个函数,代码变得越来越臃肿、难以阅读和维护。

这就是所谓的 if/else hell。它违反了软件设计中的重要原则——开闭原则(Open-Closed Principle)对扩展开放,对修改封闭。我们如何才能优雅地解决这个问题呢?答案就是——策略模式


什么是策略模式?

策略模式是一种行为型设计模式,它定义了一系列算法(或者说策略),将每一个算法都封装起来,并使它们可以互相替换。

简单来说,它的核心思想是:将算法的实现与使用算法的客户端代码分离开来。客户端不关心具体的算法是如何实现的,它只知道通过一个统一的接口来调用它。这样,你就可以在运行时根据需要动态地选择和切换不同的算法。

想象一下你的手机支付:你可以选择微信支付、支付宝支付或银行卡支付。每种支付方式都是一种策略,它们都实现了“支付”这个功能,但具体流程不同。你作为用户,只需要选择其中一个,点击支付按钮,而不需要关心每种支付方式背后的具体代码逻辑。


策略模式的三个核心组件

策略模式由三个关键角色组成:

  1. 策略接口(Strategy):定义了所有具体策略必须遵循的统一接口。在 Go 语言中,这通常是一个 interface
  2. 具体策略(Concrete Strategy):实现了策略接口的类。每一种具体策略都封装了一种独立的算法或行为。
  3. 上下文(Context):持有对策略接口的引用,并负责调用具体策略来执行任务。它充当了客户端和具体策略之间的桥梁。

Go 语言实现:重构你的订单计算器

现在,让我们使用策略模式来重构上面的订单价格计算代码。

步骤1:定义策略接口

首先,我们定义一个名为 PricingStrategy 的接口,它有一个 Calculate 方法,用来计算最终价格。

// 1. 定义策略接口(Strategy)
// PricingStrategy 定义了所有折扣策略必须实现的接口
type PricingStrategy interface {Calculate(originalPrice float64) float64
}
步骤2:创建具体策略

接下来,为每种折扣类型创建独立的结构体,并让它们实现 PricingStrategy 接口。

// 2. 创建具体策略(Concrete Strategy)
// NewUserDiscount 实现了新用户折扣策略
type NewUserDiscount struct{}func (s *NewUserDiscount) Calculate(originalPrice float64) float64 {// 关键点:每种策略只负责自己的计算逻辑return originalPrice * 0.9
}// VIPDiscount 实现了 VIP 用户折扣策略
type VIPDiscount struct{}func (s *VIPDiscount) Calculate(originalPrice float64) float64 {return originalPrice * 0.8
}// PromotionDiscount 实现了大促折扣策略
type PromotionDiscount struct{}func (s *PromotionDiscount) Calculate(originalPrice float64) float64 {return originalPrice * 0.7
}
步骤3:创建上下文

最后,我们创建一个 PricingContext 结构体,它负责管理和执行策略。

// 3. 创建上下文(Context)
// PricingContext 持有并执行策略
type PricingContext struct {strategy PricingStrategy
}// SetStrategy 动态设置当前使用的策略
func (c *PricingContext) SetStrategy(strategy PricingStrategy) {c.strategy = strategy
}// GetFinalPrice 调用当前策略来计算最终价格
func (c *PricingContext) GetFinalPrice(originalPrice float64) float64 {if c.strategy == nil {return originalPrice // 如果没有设置策略,返回原价}// 关键点:上下文不关心是哪种策略,只调用接口方法return c.strategy.Calculate(originalPrice)
}

代码使用

现在,我们的代码变得非常灵活和清晰。你可以像搭乐高积木一样,根据需要选择和组合不同的策略。

package mainimport "fmt"func main() {// 假设商品原价为 100originalPrice := 100.0// 实例化上下文context := &PricingContext{}// 场景一:新用户下单,应用新用户折扣策略fmt.Println("--- 场景一:新用户下单 ---")context.SetStrategy(&NewUserDiscount{}) // 切换策略finalPrice1 := context.GetFinalPrice(originalPrice)fmt.Printf("原价: %.2f, 最终价格: %.2f\n", originalPrice, finalPrice1)// 输出:原价: 100.00, 最终价格: 90.00// 场景二:VIP 用户下单,切换到 VIP 策略fmt.Println("\n--- 场景二:VIP 用户下单 ---")context.SetStrategy(&VIPDiscount{}) // 轻松切换策略finalPrice2 := context.GetFinalPrice(originalPrice)fmt.Printf("原价: %.2f, 最终价格: %.2f\n", originalPrice, finalPrice2)// 输出:原价: 100.00, 最终价格: 80.00// 场景三:大促期间,VIP 用户下单,但平台规定大促折扣优先fmt.Println("\n--- 场景三:大促期间下单 ---")context.SetStrategy(&PromotionDiscount{}) // 再次切换策略finalPrice3 := context.GetFinalPrice(originalPrice)fmt.Printf("原价: %.2f, 最终价格: %.2f\n", originalPrice, finalPrice3)// 输出:原价: 100.00, 最终价格: 70.00// 场景四:如果未来新增了“会员日 6 折”策略,你只需要新增一个 struct,无需修改任何旧代码!// type MemberDayDiscount struct{}...
}

在这里插入图片描述


优缺点分析

优点缺点
符合开闭原则:新增策略时,无需修改已有代码。增加了类的数量:每种策略都需要一个独立的结构体,可能导致类文件增多。
易于扩展:添加新算法只需创建新类型并实现接口。客户端需要了解所有策略:调用方(如 main 函数)需要知道所有可用的具体策略类。
代码解耦:算法的实现与使用完全分离,职责单一。如果策略非常简单,过度设计可能带来不必要的复杂性。
运行时切换:可以根据不同条件动态选择和切换算法。

总结

策略模式是一种优雅而强大的设计模式,它帮助我们摆脱了复杂的 if/else 嵌套,使得代码结构更清晰、更易于扩展和维护。在 Go 语言中,利用接口的特性可以轻松实现这一模式。

下次当你遇到需要根据不同条件执行不同行为的场景时,不妨停下来思考一下:这里是不是可以用策略模式来重构呢?用接口和具体的实现来替代一长串的 if/else 分支,让你的代码更具弹性,为未来的扩展做好准备。


文章转载自:

http://11JsnXbI.sLfym.cn
http://n7FORsI3.sLfym.cn
http://XsuW8s9o.sLfym.cn
http://JObsgjiI.sLfym.cn
http://IUz6r7Z5.sLfym.cn
http://n9w1KSvy.sLfym.cn
http://X3BU2tuM.sLfym.cn
http://Bdr5sL3z.sLfym.cn
http://q0d26324.sLfym.cn
http://O3p96ysL.sLfym.cn
http://DbYaNexI.sLfym.cn
http://eT1ZBdW2.sLfym.cn
http://q5lGQGOt.sLfym.cn
http://41WnxeFk.sLfym.cn
http://zGcNmLnY.sLfym.cn
http://QG0QoTwM.sLfym.cn
http://hyTCHyJs.sLfym.cn
http://xuogMt4f.sLfym.cn
http://9P7Q3rbc.sLfym.cn
http://gJ7Dol1x.sLfym.cn
http://Xwq5nO9F.sLfym.cn
http://OGEA5hHY.sLfym.cn
http://iqS9ZFmR.sLfym.cn
http://DemVdjZz.sLfym.cn
http://LKgA5vyI.sLfym.cn
http://DpCe7p58.sLfym.cn
http://tBQ2QFvS.sLfym.cn
http://55aO1mvg.sLfym.cn
http://ZjUwYeV8.sLfym.cn
http://aTMmsJYH.sLfym.cn
http://www.dtcms.com/wzjs/718078.html

相关文章:

  • 网站制作专业的公司叫什么网站运营建设的培训班
  • 千元低价网站建设wordpress 支付方式
  • 东莞地产网站建设linux 做网站
  • 微信网站备案装修公司口碑好的公司
  • fr后缀网站石家庄企业网站建设公司
  • 做ppt用的音效网站同城信息发布平台
  • 中国石油建设工程协会网站短网址生成设计
  • 前端网站开发实例建筑公司的名字怎么取才好
  • 龙游网站建设的公司wordpress身份认证
  • 开封做网站睿艺美网站备案 个人 单位
  • 网站用的什么字体中国电子科技集团有限公司
  • 项目建设备案网站免费建立教育网站
  • 三维家在线设计官网苏州seo推广优化
  • 建设工程协会网站网络管理员考试
  • 系部网站建设58网站自己做
  • 中牟高端网站建设企业网站 建设 流程
  • wordpress子目录建站网站站长需要具备什么素质
  • 浙江网站建设制作我要免费建立一个网站吗
  • 免费网站建设平台哪个好编程在线培训
  • 宜昌市住房城乡建设网站wordpress做论坛
  • 江苏省建设工程注册中心网站毕业答辩为什么做网站
  • 微信如何做微商城网站建设店铺在百度免费定位
  • 上海网站建设推建筑公司企业理念
  • 石家庄网站外包金网科技
  • 织梦网站文章发布模板下载优质网站建设制作
  • vi设计网站大全网站怎么做弹框
  • 和政网站建设购物网站 怎么做
  • 网站建设流行技术wordpress瓶颈
  • 芍药居做网站公司建网站一般用什么工具
  • 斗鱼类的直播网站开发惠来做网站