策略模式:消灭优惠券 if-else,加新券就是新增一个类老代码一行不动
作者鱼宵 「Java 后端实战精通营」设计模式系列・第 5 篇一、真实场景老板每次加一种券你就得回来加一个 else-if还记得第 1 篇那份故意写烂的外卖订单代码吗里面算优惠那段是这么写的doublefinalAmountorder.amount;if(满减.equals(order.couponType)){if(order.amount100){finalAmountorder.amount-20;}}elseif(折扣.equals(order.couponType)){finalAmountorder.amount*0.8;}当时我在第 1 篇末尾埋了个钩子这段 if-else 留着等第 5 课用策略模式收拾。今天兑现。痛点你一定熟老板下周加个无门槛券你在优惠 if 链里再补一个else if下下周加会员券又补一个。一个月后优惠方法里躺了五六个分支改满减门槛从 100 涨到 150时你得翻遍整个方法找那行 100——漏改一处线上就有人薅羊毛。这一课开药策略模式。后半节顺手讲模板方法。代码全在lesson-05clone 下来跑一遍加新券是不是真的只加一个类控制台当场演。二、核心原理把算法一个个装进小盒子随插随换2.1 策略模式是什么出门选地铁还是打车策略模式Strategy定义一族算法把它们一个个封装起来让它们可以互相替换。算法的变化被独立出来不影响用它的客户。类比出门选地铁、打车、骑车——三个是出行算法族目的地一样、算法不同随时能换。满减、折扣、无优惠就是算优惠这一族的三个算法。2.2 三个角色一句话各管什么角色本课对应类干什么抽象策略 StrategyDiscountStrategy接口定义统一入口discount(金额)具体策略 ConcreteStrategyFullReductionStrategy/PercentDiscountStrategy/NoDiscountStrategy各算各的满减、8 折、原价上下文 ContextOrderDiscountCalculator持有当前策略、对外统一入口、运行时可换面试常被追问直接new FullReductionStrategy().discount(150)不行吗行但用哪种券就写死在调用方了。上下文存在的意义就三件事持有策略 运行时切换 统一入口。用户中途换券就是setStrategy(新券)一行。2.3 错误写法 vs 正确写法摆在一起看差距// ❌ 错误写法算法挤在一个方法里加券就要回来改老代码doublecalculateBad(StringcouponType,doubleamount){if(满减.equals(couponType)){if(amount100)returnamount-20;returnamount;}elseif(折扣.equals(couponType)){returnamount*0.8;}elseif(无门槛.equals(couponType)){// 加券 改老方法returnamount-5;}returnamount;}// ✅ 正确写法每种券一个类加券 加新类老方法一行不动doublecalculateGood(DiscountStrategystrategy,doubleamount){returnstrategy.discount(amount);// 调谁由外面传进来}差别在哪错误写法里加新券是回头改一个已经上线、跑了半年的老方法——违反开闭原则OCP对扩展开放对修改关闭。正确写法里加新券是新增一个类实现DiscountStrategy老代码碰都不碰。那什么时候 if-else 反而更好分支只有两三个、几乎不会再加的地方硬上策略就是过度设计。策略买的是可维护性不是运行速度。分支会涨、算法会换才值得上策略。2.4 后半节模板方法——父类定骨架子类填空讲完策略再上一个姊妹模式。模板方法Template Method父类定好算法的骨架步骤顺序固定某些步骤的实现推迟到子类。子类不改流程结构只填细节。类比做菜。菜谱流程固定洗菜→切菜→下锅→调味放什么料由这道菜自己定。订单处理永远是这四步校验 → 算价 → 扣库存 → 通知。普通单和预售单差异只在算价和扣库存两步校验和通知完全一样。每个订单类型都把四步抄一遍改通知格式要改 N 处——这就是模板方法要干掉的重复。它有三个命门骨架方法process()必须final子类不能重写它、不能调换顺序。骨架被改了固定流程就名存实亡。抽象方法abstract父类知道要算价但不知道怎么算留空让子类填——必须实现。钩子方法Hook父类给默认实现子类可选覆盖。和抽象方法的区别抽象是必须交作业钩子是默认交了、你想改再重写。2.5 两对高频混淆题一张表背下来策略 vs 状态模式面试高频陷阱答反就挂策略是客户端主动选算法用户选了满减券平级独立状态是对象内部状态自己切自己订单从待支付变已支付行为自动变。模板方法 vs 策略模板方法策略复用手段继承子类填步骤组合换一个策略对象改流程要新写一个子类换个策略对象就行粒度一整套流程的骨架单个可互换的算法一句话模板方法用继承白箱复用策略用组合黑箱复用。三、关键代码完整可运行版含 package import 主类本课工程在lesson-05/src/main/java/com/dp/lesson05/。先看抽象策略接口——它只约定能算优惠不管怎么算packagecom.dp.lesson05;/** * 优惠策略接口策略模式的抽象策略角色。 * 把怎么算优惠抽象成一个方法每种优惠券 一个实现类。 * 策略应该无状态一个实例可被所有订单共用因为算优惠只跟入参有关。 */publicinterfaceDiscountStrategy{/** * 计算优惠后的实付金额。 * param originalAmount 订单原始金额 * return 优惠后应付金额 */doublediscount(doubleoriginalAmount);/** 策略名演示时打印出来让大家看到当前用的是哪种算法 */Stringname();}三个具体策略各算各的满减的门槛判断收在自己类内部packagecom.dp.lesson05;/** 满减策略满 100 减 20 */publicclassFullReductionStrategyimplementsDiscountStrategy{Overridepublicdoublediscount(doubleoriginalAmount){// 门槛是满减算法自己的事封在策略内部if(originalAmount100){returnoriginalAmount-20;}returnoriginalAmount;}OverridepublicStringname(){return满减券满100减20;}}packagecom.dp.lesson05;/** 折扣策略折扣率做成构造参数一个类覆盖任意折扣率 */publicclassPercentDiscountStrategyimplementsDiscountStrategy{privatefinaldoublerate;// 0.8 八折publicPercentDiscountStrategy(doublerate){this.raterate;}Overridepublicdoublediscount(doubleoriginalAmount){returnoriginalAmount*rate;}OverridepublicStringname(){return折扣券(int)(rate*10)折;}}packagecom.dp.lesson05;/** * 无优惠策略原价返回。 * 什么都不做也是一种算法显式做成策略调用方再也不用判空—— * 这就是空对象模式Null Object的味道。 */publicclassNoDiscountStrategyimplementsDiscountStrategy{Overridepublicdoublediscount(doubleoriginalAmount){returnoriginalAmount;}OverridepublicStringname(){return无优惠原价;}}接下来是上下文——三行核心持有策略、可切换、委托packagecom.dp.lesson05;/** * 优惠计算器上下文 Context。 * 持有当前策略真正算钱的活儿委托给策略去做自己只做编排。 */publicclassOrderDiscountCalculator{privateDiscountStrategystrategy;// 当前生效的策略publicOrderDiscountCalculator(DiscountStrategystrategy){this.strategystrategy;}/** 运行时切换策略电商里用户换了一张券就是这一行 */publicvoidsetStrategy(DiscountStrategystrategy){this.strategystrategy;System.out.println( [计算器] 切换优惠策略 - strategy.name());}/** 统一入口把活儿全部委托给当前策略自己不算钱 */publicdoublecalculate(doubleoriginalAmount){returnstrategy.discount(originalAmount);}publicStringcurrentStrategyName(){returnstrategy.name();}}模板方法部分。父类把四步骨架用final锁死两个抽象步骤留空通知是钩子packagecom.dp.lesson05;/** * 订单处理流程模板模板方法的抽象类角色。 * 骨架校验 - 算价 - 扣库存 - 通知顺序由 final 锁死。 */publicabstractclassAbstractOrderProcessTemplate{/** 骨架方法final 锁死子类不能改流程顺序 */publicfinalvoidprocess(Orderorder){validate(order);// 步骤1通用父类实现doublepricecalcPrice(order);// 步骤2抽象子类填deductStock(order);// 步骤3抽象子类填notify(order,price);// 步骤4钩子父类给默认}/** 步骤1所有订单通用的校验写死在父类 */protectedvoidvalidate(Orderorder){if(order.getOrderId()null||order.getOrderId().isEmpty()){thrownewIllegalArgumentException(订单号不能为空);}System.out.println( [流程] 校验通过订单 order.getOrderId());}/** 步骤2抽象方法子类必须实现 */protectedabstractdoublecalcPrice(Orderorder);/** 步骤3抽象方法子类必须实现 */protectedabstractvoiddeductStock(Orderorder);/** * 步骤4钩子方法Hook。 * 不是 abstract父类给了默认实现子类想改才重写。 * 分清 abstract 还是 Hook 的口诀子类不改行不行行 钩子。 */protectedvoidnotify(Orderorder,doubleprice){System.out.println(String.format( [流程] 通知用户订单 %s 实付 %.2f 元,order.getOrderId(),price));}}两个子类只填差异。普通单算价走策略计算器这里是模板方法 策略两个模式配合预售单算活动价packagecom.dp.lesson05;/** 普通单算价走策略计算器扣库存立即扣 */publicclassNormalOrderProcessextendsAbstractOrderProcessTemplate{privatefinalOrderDiscountCalculatorcalculator;publicNormalOrderProcess(OrderDiscountCalculatorcalculator){this.calculatorcalculator;}OverrideprotecteddoublecalcPrice(Orderorder){doublepricecalculator.calculate(order.getAmount());System.out.println(String.format( [流程] 普通单算价原价 %.2f - 实付 %.2f%s,order.getAmount(),price,calculator.currentStrategyName()));returnprice;}OverrideprotectedvoiddeductStock(Orderorder){System.out.println( [流程] 普通单立即扣减库存);}// notify 没重写吃父类默认实现这就是钩子可选覆盖的演示}packagecom.dp.lesson05;/** 预售单算活动价不用券只锁库存不扣 */publicclassPresaleOrderProcessextendsAbstractOrderProcessTemplate{OverrideprotecteddoublecalcPrice(Orderorder){doublepriceorder.getAmount()*0.9;// 预售 9 折System.out.println(String.format( [流程] 预售单算价活动价 %.2f原价 %.2f不用券,price,order.getAmount()));returnprice;}OverrideprotectedvoiddeductStock(Orderorder){System.out.println( [流程] 预售单只锁库存不扣减发货日才扣);}}最后是入口 Main把策略切换和模板流程各跑一遍packagecom.dp.lesson05;publicclassMain{publicstaticvoidmain(String[]args){System.out.println( 第 5 课策略模式——优惠计算 if-else 的末日 );// 1. 初始策略 无优惠没券就是没券不用 if 判断OrderDiscountCalculatorcalculatornewOrderDiscountCalculator(newNoDiscountStrategy());payOnce(calculator,150);payOnce(calculator,88);// 2. 用户换了满减券运行时切换订单服务一行不改calculator.setStrategy(newFullReductionStrategy());payOnce(calculator,150);// 满100减20payOnce(calculator,80);// 不满100不减// 3. 又换成 8 折券calculator.setStrategy(newPercentDiscountStrategy(0.8));payOnce(calculator,88);System.out.println();System.out.println( 第 5 课模板方法——订单处理流程骨架 );// 4. 普通单流程四步骨架跑一遍此刻计算器里装的是 8 折策略OrdernormalnewOrder(A2001,NORMAL,150);AbstractOrderProcessTemplatenormalProcessnewNormalOrderProcess(calculator);System.out.println(-- 跑普通单流程 --);normalProcess.process(normal);System.out.println();// 5. 预售单流程四步顺序一模一样算价/扣库存做法完全不同OrderpresalenewOrder(A2002,PRESALE,200);AbstractOrderProcessTemplatepresaleProcessnewPresaleOrderProcess();System.out.println(-- 跑预售单流程 --);presaleProcess.process(presale);System.out.println();System.out.println( 结束加新券新增策略类新订单类型新增子类老代码一行不动 );}/** 小工具按当前策略算一单并打印 */privatestaticvoidpayOnce(OrderDiscountCalculatorcalculator,doubleamount){doublepaycalculator.calculate(amount);System.out.println(String.format( 金额 %.2f 用[%s] - 实付 %.2f,amount,calculator.currentStrategyName(),pay));}}这段代码讲了什么前半段同一个计算器被中途换了三次策略无优惠→满减→8 折调用方一行没改后半段普通单和预售单严格走四步差异只在算价和扣库存。四、完整演示 实测输出clone 下来后在lesson-05目录执行Windows PowerShellcd C:\Users\haoji\Desktop\课程\design-patterns-journey\lesson-05$env:JAVA_HOMEC:\jdk\jdk-17.0.12mvn clean install-DskipTests看到BUILD SUCCESS后运行中文乱码先设 936 编码[Console]::OutputEncoding[System.Text.Encoding]::GetEncoding(936)C:\jdk\jdk-17.0.12\bin\java.exe-cp.\target\classescom.dp.lesson05.Main实测输出 第 5 课策略模式——优惠计算 if-else 的末日 金额 150.00 用[无优惠原价] - 实付 150.00 金额 88.00 用[无优惠原价] - 实付 88.00 [计算器] 切换优惠策略 - 满减券满100减20 金额 150.00 用[满减券满100减20] - 实付 130.00 金额 80.00 用[满减券满100减20] - 实付 80.00 [计算器] 切换优惠策略 - 折扣券8折 金额 88.00 用[折扣券8折] - 实付 70.40 第 5 课模板方法——订单处理流程骨架 -- 跑普通单流程 -- [流程] 校验通过订单 A2001 [流程] 普通单算价原价 150.00 - 实付 120.00折扣券8折 [流程] 普通单立即扣减库存 [流程] 通知用户订单 A2001 实付 120.00 元 -- 跑预售单流程 -- [流程] 校验通过订单 A2002 [流程] 预售单算价活动价 180.00原价 200.00不用券 [流程] 预售单只锁库存不扣减发货日才扣 [流程] 通知用户订单 A2002 实付 180.00 元 结束加新券新增策略类新订单类型新增子类老代码一行不动 输出解读三个细节前半段策略同一个计算器先无优惠150→150切满减150→130、80→80 不满门槛再切 8 折88→70.4——算法在运行中途被换掉调用方一行没改。后半段模板方法普通单和预售单严格走四步差异只在算价和扣库存两行。普通单那行括号里是折扣券8折因为计算器里此刻装的还是 8 折策略——模板方法的算价步骤内部又委托给了策略。五、挑战题改参数会怎样答案在源码里⭐ 把Main里new PercentDiscountStrategy(0.8)改成(0.7)再跑一遍——88 那单实付多少注意name()里那行(int)(rate*10)打印是7折还是8折⭐⭐ 把AbstractOrderProcessTemplate.process()的final去掉让PresaleOrderProcess重写一个process()故意把顺序倒过来先通知再算价——编译报不报错跑出来和父类流程差在哪⭐⭐ 给抽象模板加钩子protected boolean needNotify() { return true; }在notify()开头加if (!needNotify()) return;让PresaleOrderProcess覆盖它返回false——重跑预售单最后那行通知用户还在不在三题改完跑一遍现象都在lesson-05源码里。跑出来和你想的不一样评论区贴出来。六、生产环境进阶Spring 里你天天用只是没意识到手写一个接口 三个实现 一个上下文是为了看清本质。真实项目里这两个模式早就被框架包好了1. Spring 注入MapString, DiscountStrategy——生产最常用的策略分发ServicepublicclassCouponService{// Spring 自动把所有 DiscountStrategy 类型的 Bean 按名字灌进来AutowiredprivateMapString,DiscountStrategystrategyMap;publicdoublepay(StringcouponType,doubleamount){// 加新券 新写一个 Bean 实现接口这里一行 if 都不用加returnstrategyMap.get(couponType).discount(amount);}}你写过的Autowired MapString, SomeStrategy就是策略的 Spring 落地——框架帮你把接口→多实现→按名取全干了。2. JDK 里你已经用过几百次策略——Comparator和拒绝策略ListOrderorders...;orders.sort((a,b)-Double.compare(b.getAmount(),a.getAmount()));// lambda 就是排序策略newThreadPoolExecutor(1,1,0L,TimeUnit.MILLISECONDS,newLinkedBlockingQueue(100),newThreadPoolExecutor.CallerRunsPolicy());// 拒绝策略Comparator是策略接口JDK 的sort()是固定算法怎么比由你传的 lambda 决定。RejectedExecutionHandler四个内置实现AbortPolicy 抛异常、CallerRunsPolicy 调用者跑、DiscardPolicy 丢、DiscardOldestPolicy 丢最老的也是策略。3. 模板方法的天花板——Spring 的JdbcTemplate它把拿连接 → 建 Statement → 执行 SQL → 关资源 → 异常翻译这套固定流程全锁在父类里你只写 SQL 那段。拿连接、关资源、把SQLException翻译成DataAccessException——这些脏活全是固定的是父类骨架action.doInStatement(stmt)是你写的 SQL是子类填的步骤。你用 JdbcTemplate 时传的那个 lambda就是模板方法里留空的那一步。## 七、面试回答模板Q1策略模式怎么消灭 if-else为什么说新增优惠券 新增一个类一句话结论把分支搬进多态——每种算法封装成一个实现类上下文持有策略并委托新增行为 新增实现类不改老代码。展开坏代码里if (满减) / else if (折扣)把三种算法挤在一个方法里策略模式把每个分支抽成DiscountStrategy的一个实现加无门槛券就是新写一个类老代码一行不动这就是开闭原则。指向本文第二节。Q2策略模式里 Context 是干什么的一句话结论上下文 策略的持有者 请求的转发者它自己不算算法只做编排。展开上下文三个价值——持有当前策略、统一入口calculate()、运行时setStrategy()切换电商里用户中途换券就是这一行。指向本文第三节。Q3模板方法和策略模式什么区别Spring 里哪里是这俩一句话结论模板方法用继承白箱、父类定骨架子类填步骤策略用组合黑箱、换个策略对象就行。展开JdbcTemplate / RestTemplate 是模板方法MapString, XxxStrategy注入、Comparator、拒绝策略是策略。指向本文第二、六节。八、总结表坑原因解法加一种优惠券就要回来加else if算法挤在一个方法里违反开闭原则每种券 一个策略类上下文持有切换本文第二节直接在调用方new FullReductionStrategy()用哪种券写死丢了运行时切换能力加一层 ContextsetStrategy()运行时换模板方法骨架忘了加final编译不报错但子类重写process()把流程打乱骨架方法必须final这是命门把可选步骤声明成abstract每个子类被迫实现一堆用不到的方法分不清 abstract 还是 Hook 就问子类不改行不行行 钩子九、关于这个系列本文是「Java 后端实战精通营」设计模式系列第 5 篇。这个系列不按 23 种模式教科书式罗列只打三张牌面试高频模式 Spring/JDK 源码真实落点 第 1 篇那份外卖烂代码逐节开药。完整可运行工程https://gitee.com/j67mk2/design-patterns本课源码在lesson-05/主类com.dp.lesson05.Main下一篇预告《观察者模式下单成功订单服务一个 if 都不加所有关心它的模块自动收到消息》。第 1 篇里发通知的三个ifneedSms / needEmail / needAppPush就是下一课手术对象——手写一个极简事件总线下单成功发布事件短信、邮件、App 推送各自订阅加微信通知 新增一个监听器。互动提问你项目里有没有一段加一种分支就要回来改老方法的代码是优惠券支付渠道通知方式评论区说说我帮你判断该上策略、观察者还是责任链。本文部分内容由 AI 辅助生成

相关新闻

PyTorch与TensorFlow卷积层底层实现解析:padding、stride、dilation与groups的实操真相

PyTorch与TensorFlow卷积层底层实现解析:padding、stride、dilation与groups的实操真相

1. 这不是“读文档”,而是拆解CNN底层运转逻辑的实操现场你点开过PyTorch或TensorFlow的torch.nn.Conv2d或tf.keras.layers.Conv2D官方文档吗?大概率是——扫了一眼参数列表,抄了段示例代码,调通了模型,就关掉了页面。…

2026/10/16 23:04:30 阅读更多 →
代理IP总被风控?先搞懂“IP纯净度”到底怎么回事

代理IP总被风控?先搞懂“IP纯净度”到底怎么回事

一个让无数人踩坑的概念 做跨境运营、数据采集或者多账号管理的人,大概率都遇到过这种场景:花了不少钱买了一堆代理IP,兴冲冲地跑起任务,结果目标网站该弹验证码还是弹,账号该被封还是被封。找客服理论,对方…

2026/10/16 23:04:30 阅读更多 →
训练结束自动发邮件:基于SMTP的深度学习任务通知实践

训练结束自动发邮件:基于SMTP的深度学习任务通知实践

凌晨两点半,训练还在跑。屏幕上的 loss 曲线已经压得很低,但距离收敛少说还得一两个钟头。睡吧不踏实,不睡吧又确实在熬时间。这种感受,凡是正经训练过深度学习模型的人应该都不陌生。后来我花了大概二十分钟写了个脚本&#xff0…

2026/10/16 23:04:30 阅读更多 →

最新新闻

IMS计费标准3GPP TS 32.260详解:离线在线计费与ICID机制

IMS计费标准3GPP TS 32.260详解:离线在线计费与ICID机制

简介:本资源为3GPP TS 32.260 IMS计费技术规范的中文版PDF文档,面向从事移动通信核心网计费系统研发、测试与运维的工程师,以及需要理解IMS计费机制的通信专业学生与研究人员。文档系统梳理了IMS离线计费、在线计费与融合计费三种架构&#x…

2026/10/16 23:53:18 阅读更多 →
VoLTE掉话治理:信令时序与资源生命周期协同优化

VoLTE掉话治理:信令时序与资源生命周期协同优化

简介:本资源是一份聚焦VoLTE掉话根因分析与实战优化的深度技术文档,面向4G/5G无线网络优化工程师、核心网运维人员及通信专业高年级学生,解决VoLTE业务中高频掉话、重建立失败、信令异常等现网典型问题。文档基于广州ATU网格真实测试数据&…

2026/10/16 23:53:18 阅读更多 →
思科校园网课程设计实战:VLAN规划、协议抓包与排错避坑

思科校园网课程设计实战:VLAN规划、协议抓包与排错避坑

简介:基于思科的校园网搭建及网络协议分析课程设计文档,适合计算机网络课程设计、毕业设计或实验报告撰写参考。内容从应用场景和需求分析入手,设计了校园网整体拓扑,重点介绍服务器配置、无线网络部署、各部门路由器与交换机的VL…

2026/10/16 23:52:17 阅读更多 →
贝叶斯网络、HMM与CRF:结构化预测的选型决策图谱

贝叶斯网络、HMM与CRF:结构化预测的选型决策图谱

1. 这不是概念堆砌,而是三条技术路径的“血缘图谱”你翻过不少资料,可能见过这样的描述:“贝叶斯网络是概率图模型的一种”“马尔可夫模型强调无记忆性”“条件随机场擅长序列标注”。但这些定义像贴在玻璃上的标签——看得见,摸不…

2026/10/16 23:51:16 阅读更多 →
动态环境下的视觉SLAM与SfM:干扰源分类与处理策略

动态环境下的视觉SLAM与SfM:干扰源分类与处理策略

动态环境四个字出现在综述标题里,听起来像一句套话,但真正跑过一版视觉SLAM的人都知道,一个在走廊里来回走动的人,就足以让原本稳定的位姿估计在十几秒内现出原形。运动恢复结构(Structure from Motion)也一…

2026/10/16 23:51:16 阅读更多 →
关联规则实战:从Apriori到FP-树频集算法的选型与落地

关联规则实战:从Apriori到FP-树频集算法的选型与落地

有没有遇到过这种情况:业务方丢给你一份几十万行的订单流水,开口就问“哪些商品经常被一起买?能不能挖出点搭配销售的规律?”你如果用Excel透视表硬扛,可能折腾一整天只得到一堆没什么解释力的数字。这时候&#xff0c…

2026/10/16 23:51:16 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →