设计模式原则,请针对具体代码说明

张开发
2026/4/15 8:31:28 15 分钟阅读

分享文章

设计模式原则,请针对具体代码说明
设计原则总结结合支付模块代码的具体说明一、六大设计原则概览原则英文核心含义开闭原则Open-Closed Principle对扩展开放对修改关闭里氏替换Liskov Substitution子类型必须能替换父类型接口隔离Interface Segregation接口应该小而专一单一职责Single Responsibility一个类只有一个变化原因依赖倒置Dependency Inversion依赖抽象不依赖具体迪米特法则Law of Demeter最少知识原则二、开闭原则OCP定义对扩展开放对修改关闭。新增功能时不应修改现有代码。代码体现java// ❌ 错误做法每次新增支付渠道都要修改这个类 public class BadPayService { public PrePayResult pay(String payType, PayBizParam param) { if (WECHAT.equals(payType)) { return wechatPay(param); } else if (ALIPAY.equals(payType)) { return alipayPay(param); } else if (SIMULATE.equals(payType)) { return simulatePay(param); } // 新增渠道 → 需要修改这个方法 → 违反开闭原则 } } // ✅ 正确做法通过策略模式 工厂模式 Component public class PayHandlerFactory { private final MapPayTypes, PayHandler handlerMap; public PayHandlerFactory(ListPayHandler handlers) { // Spring 自动注入所有 PayHandler 实现类 this.handlerMap handlers.stream() .collect(Collectors.toMap(PayHandler::payTypes, Function.identity())); } public PayHandler getHandler(PayTypes payType) { return handlerMap.get(payType); } } // 新增支付渠道只需添加新类无需修改任何现有代码 Component public class NewPayHandler extends AbstractPayHandler { Override public PayTypes payTypes() { return PayTypes.NEW_PAY; // 新渠道 } Override public PrePayResult doPrePay(PrePayParam param) { // 新渠道的实现 } }原则体现新增支付渠道时只新增NewPayHandler类PayHandlerFactory、PayService、AbstractPayHandler等现有代码一行都不用改。三、里氏替换原则LSP定义子类可以扩展父类的功能但不能改变父类原有的功能。任何使用父类的地方都可以透明地替换为子类。代码体现java// 抽象父类 public abstract class AbstractPayHandler implements PayHandler { public PrePayParam buildPrePayParam(PayTypes payType, PayBizParam payBizParam) { PrePayParam param new PrePayParam(); param.setTradeNo(buildTradeNo(TRADE)); param.setAmount(payBizParam.getAmount()); return param; } protected String buildTradeNo(String codeType) { return redisSerialGenerator.generateIncrNo(codeType); } } // 子类1微信支付 - 保持父类行为契约 public class WechatPayHandler extends AbstractPayHandler { Override public PrePayParam buildPrePayParam(PayTypes payType, PayBizParam payBizParam) { // 调用父类方法保证基础行为不变 PrePayParam param super.buildPrePayParam(payType, payBizParam); // 扩展添加微信特有字段不破坏原有功能 param.setOpenId(payBizParam.getOpenId()); return param; } } // 子类2模拟支付 - 也保持父类行为契约 public class SimulatePayHandler extends AbstractPayHandler { Override public PrePayParam buildPrePayParam(PayTypes payType, PayBizParam payBizParam) { PrePayParam param super.buildPrePayParam(payType, payBizParam); param.setNotifyUrl(buildNotifyUrl()); // 扩展不破坏 return param; } } // 使用方任何子类都可以替换父类位置 Service public class PayService { private PayHandlerFactory factory; public PrePayResult pay(PayTypes payType, PayBizParam param) { PayHandler handler factory.getHandler(payType); // 无论 handler 是 WechatPayHandler 还是 SimulatePayHandler // 都能正常工作 → 里氏替换原则 PrePayParam prePayParam handler.buildPrePayParam(payType, param); return handler.doPrePay(prePayParam); } }原则体现PayService只依赖PayHandler接口不需要知道具体是哪个子类。所有子类都能正确替换父类位置。四、接口隔离原则ISP定义客户端不应该被迫依赖它不使用的方法。接口应该小而专一。代码体现java// ❌ 错误做法大而全的接口 public interface BadPayHandler { PayTypes payTypes(); PrePayResult doPrePay(PrePayParam param); PrePayResult doPrePayWithCoupon(PrePayParam param, Coupon coupon); // 不一定需要 PrePayResult doPrePayWithPoints(PrePayParam param, Integer points); // 不一定需要 RefundResult doRefund(RefundParam param); RefundResult doPartialRefund(RefundParam param, BigDecimal amount); // 不一定需要 PayNotifyResult doPayNotify(PayNotifyParam param); PayNotifyResult doPayNotifyWithRetry(PayNotifyParam param); // 不一定需要 // ... 很多方法 } // ✅ 正确做法接口按职责拆分 public interface PayHandler { // 核心方法所有实现都需要 PayTypes payTypes(); PrePayResult doPrePay(PrePayParam param); RefundResult doRefund(RefundParam param); PayNotifyResult doPayNotify(PayNotifyParam param); } // 扩展接口需要优惠券功能的才实现 public interface CouponPayHandler extends PayHandler { PrePayResult doPrePayWithCoupon(PrePayParam param, Coupon coupon); } // 扩展接口需要积分功能的才实现 public interface PointsPayHandler extends PayHandler { PrePayResult doPrePayWithPoints(PrePayParam param, Integer points); } // 微信支付只实现核心接口不强迫实现不需要的方法 public class WechatPayHandler extends AbstractPayHandler { // 只需实现核心方法不需要实现优惠券、积分等方法 Override public PrePayResult doPrePay(PrePayParam param) { ... } } // 支付宝支付需要优惠券功能可以实现扩展接口 public class AlipayHandler extends AbstractPayHandler implements CouponPayHandler { Override public PrePayResult doPrePay(PrePayParam param) { ... } Override public PrePayResult doPrePayWithCoupon(PrePayParam param, Coupon coupon) { ... } }原则体现接口只包含必要的方法实现类不会被迫实现不需要的方法。五、单一职责原则SRP定义一个类只有一个引起它变化的原因。一个类只负责一项职责。代码体现java// ❌ 错误做法一个类做太多事情 public class BadPayService { public PrePayResult pay(PayBizParam param) { ... } // 支付 public RefundResult refund(RefundBizParam param) { ... } // 退款 public PayNotifyResult handleNotify(String data) { ... } // 回调 public void generateReport() { ... } // 报表 public void sendEmail(String to, String content) { ... } // 邮件 // 太多职责支付、退款、回调、报表、邮件... } // ✅ 正确做法职责分离 // 职责1支付处理 public interface PayHandler { PrePayResult doPrePay(PrePayParam param); } // 职责2退款处理 public interface RefundHandler { RefundResult doRefund(RefundParam param); } // 职责3回调处理 public interface NotifyHandler { PayNotifyResult doPayNotify(PayNotifyParam param); } // 职责4流水号生成独立组件 Component public class TradeNoGenerator { public String generateTradeNo() { ... } public String generateRefundNo() { ... } } // 职责5参数构建独立组件 Component public class PrePayParamBuilder { public PrePayParam build(PrePayContext context) { ... } } // 一个类只负责一件事 public class WechatPayHandler extends AbstractPayHandler { // 只负责微信支付的支付逻辑 Override public PrePayResult doPrePay(PrePayParam param) { // 调用微信API } }原则体现TradeNoGenerator只负责生成流水号WechatPayHandler只负责微信支付逻辑AlipayHandler只负责支付宝支付逻辑每个类只有一个修改理由六、依赖倒置原则DIP定义高层模块不应依赖低层模块两者都应依赖抽象。抽象不应依赖细节细节应依赖抽象。代码体现java// ❌ 错误做法高层模块依赖具体实现 public class BadPayService { private WechatPayHandler wechatHandler; // 依赖具体类 private AlipayHandler alipayHandler; // 依赖具体类 public void pay(String type, PayBizParam param) { if (WECHAT.equals(type)) { wechatHandler.doPrePay(param); } else if (ALIPAY.equals(type)) { alipayHandler.doPrePay(param); } } } // ✅ 正确做法依赖抽象接口 Service public class PayService { private final PayHandlerFactory factory; // 依赖工厂接口 public PayService(PayHandlerFactory factory) { this.factory factory; } public PrePayResult pay(PayTypes payType, PayBizParam param) { // 依赖 PayHandler 接口不依赖具体实现 PayHandler handler factory.getHandler(payType); PrePayParam prePayParam handler.buildPrePayParam(payType, param); return handler.doPrePay(prePayParam); } } // 抽象定义接口 public interface PayHandler { PrePayResult doPrePay(PrePayParam param); } // 具体实现依赖抽象 public class WechatPayHandler extends AbstractPayHandler { // 实现抽象接口 Override public PrePayResult doPrePay(PrePayParam param) { ... } } // 依赖注入将具体实现注入到抽象引用 Configuration public class PayConfig { Bean public PayService payService(ListPayHandler handlers) { PayHandlerFactory factory new PayHandlerFactory(handlers); return new PayService(factory); // 注入依赖 } }原则体现PayService高层依赖PayHandler接口抽象WechatPayHandler低层也依赖PayHandler接口抽象高层和低层都依赖抽象而不是相互依赖七、迪米特法则LoD定义一个对象应该对其他对象有最少的了解。只与直接的朋友通信。代码体现java// ❌ 错误做法跨越层级调用 public class BadPayService { public void pay(PayBizParam param) { WechatPayHandler handler new WechatPayHandler(); // 直接操作 handler 内部的组件 String tradeNo handler.getTradeNoGenerator().generate(); // 违反迪米特 handler.getHttpClient().post(url, data); // 违反迪米特 handler.getRedisTemplate().set(key, value); // 违反迪米特 } } // ✅ 正确做法只与直接朋友通信 public class WechatPayHandler extends AbstractPayHandler { // 封装内部细节不对外暴露 private final TradeNoGenerator tradeNoGenerator; private final HttpClient httpClient; private final RedisTemplate redisTemplate; Override public PrePayResult doPrePay(PrePayParam param) { // 内部使用不暴露给外部 String tradeNo tradeNoGenerator.generate(); String result httpClient.post(buildUrl(), buildBody(param)); redisTemplate.set(pay: tradeNo, result); return parseResult(result); } } // 使用方只与 PayHandler 交互不关心内部实现 Service public class PayService { private final PayHandlerFactory factory; public PrePayResult pay(PayTypes payType, PayBizParam param) { PayHandler handler factory.getHandler(payType); // 只调用 handler 的方法不调用其内部组件 PrePayParam prePayParam handler.buildPrePayParam(payType, param); return handler.doPrePay(prePayParam); // ✅ 只与直接朋友通信 } }原则体现PayService只与PayHandler交互不直接访问PayHandler内部的TradeNoGenerator、HttpClient等内部细节被封装在PayHandler实现类中八、总结对照表原则代码中的具体体现违反的后果开闭原则新增支付渠道只需加类不改现有代码每加一个渠道要改多处代码易出错里氏替换任何子类都能替换父类位置正常工作多态失效类型判断代码到处都是接口隔离PayHandler只有核心方法扩展接口分离实现类被迫实现不需要的方法单一职责TradeNoGenerator只负责生成流水号一个类改了影响多个不相关功能依赖倒置PayService依赖PayHandler接口高层依赖具体类换实现要改代码迪米特法则PayService只调用PayHandler方法类之间耦合过深难以维护九、一个完整的例子新增支付渠道java// 步骤1新增枚举值开闭原则 - 扩展 public enum PayTypes { WECHAT, ALIPAY, SIMULATE, CRYPTO_PAY // 新增加密货币支付 } // 步骤2新增实现类开闭原则 - 扩展 Component public class CryptoPayHandler extends AbstractPayHandler { // 里氏替换 - 正确实现父类契约 Override public PayTypes payTypes() { return PayTypes.CRYPTO_PAY; } Override public PrePayResult doPrePay(PrePayParam param) { // 单一职责 - 只负责加密货币支付逻辑 return cryptoApi.pay(param); } // 依赖倒置 - 依赖抽象接口不依赖具体实现 Autowired private CryptoApiClient cryptoApi; // 抽象接口 } // 步骤3使用方代码完全不需要修改开闭原则 Service public class PayService { public PrePayResult pay(PayTypes payType, PayBizParam param) { PayHandler handler factory.getHandler(payType); // 自动获取新渠道 return handler.doPrePay(handler.buildPrePayParam(payType, param)); } }六条原则在这个流程中的体现开闭新增类不改现有代码里氏CryptoPayHandler能替换PayHandler使用接口隔离只实现PayHandler必需方法单一职责CryptoPayHandler只负责加密支付依赖倒置依赖CryptoApiClient接口迪米特外部只调用doPrePay不关心内部实现里氏替换和依赖倒置感觉比较类似都是只依赖接口不依赖具体实现// 依赖倒置关注依赖的方向是否正确 // 里氏替换问的是 // 用 SimulatePayHandler 替换 AbstractPayHandler 后程序还能正常运行吗 // 依赖倒置问的是 // PayService 是依赖了 PayHandler 接口好还是依赖了 WechatPayHandler 具体类坏三、详细对比维度里氏替换原则LSP依赖倒置原则DIP核心问题继承后的行为契约依赖的方向和粒度作用对象父子类之间的关系模块/类之间的依赖关系关注时机编写子类时设计架构时违反后果多态失效运行时异常代码耦合难以修改解决手段正确继承不改变父类行为面向接口编程四、代码示例对比场景支付系统java// 依赖倒置DIP示例 // 关注依赖关系是否正确 // ❌ 违反依赖倒置高层依赖低层 public class PayService { private WechatPayHandler wechatHandler; // 依赖具体类 private AlipayHandler alipayHandler; // 依赖具体类 // 问题换支付方式要改代码 } // ✅ 符合依赖倒置依赖抽象 public class PayService { private PayHandler handler; // 依赖接口抽象 // 好处换任何支付方式都不改代码 } // 里氏替换LSP示例 // 关注继承后行为是否正确 // 父类定义 public abstract class AbstractPayHandler { // 约定返回的金额必须大于0 public PrePayParam buildPrePayParam(PayBizParam bizParam) { PrePayParam param new PrePayParam(); param.setAmount(bizParam.getAmount()); // 原样设置 return param; } } // ❌ 违反里氏替换子类改变了父类行为 public class BadSimulateHandler extends AbstractPayHandler { Override public PrePayParam buildPrePayParam(PayBizParam bizParam) { PrePayParam param super.buildPrePayParam(bizParam); // 恶意修改金额强制设为0违反父类金额0的约定 param.setAmount(BigDecimal.ZERO); return param; } } // 使用方符合依赖倒置但会被里氏替换坑 public class PayService { private PayHandler handler; // ✅ 依赖倒置正确 public void pay(PayBizParam param) { PrePayParam prePayParam handler.buildPrePayParam(param); // 如果 handler 是 BadSimulateHandler金额变成了0 // 程序可能异常 → 违反了里氏替换 } }五、两个原则的关系java// 依赖倒置是骨架里氏替换是血肉 // 依赖倒置定义架构都依赖接口 public interface PayHandler { PrePayParam buildPrePayParam(PayBizParam param); } // 里氏替换保证实现子类不能破坏父类约定 public abstract class AbstractPayHandler implements PayHandler { // 约定1tradeNo 不能为空 // 约定2amount 必须大于0 // 约定3返回的 notifyUrl 必须是 https public PrePayParam buildPrePayParam(PayBizParam bizParam) { PrePayParam param new PrePayParam(); param.setTradeNo(buildTradeNo()); // 约定1 param.setAmount(bizParam.getAmount()); // 约定2必须0 param.setNotifyUrl(buildHttpsUrl()); // 约定3 return param; } } // 子类遵守里氏替换不破坏父类约定 public class WechatPayHandler extends AbstractPayHandler { Override public PrePayParam buildPrePayParam(PayBizParam bizParam) { PrePayParam param super.buildPrePayParam(bizParam); // 遵守约定 param.setOpenId(bizParam.getOpenId()); // 只扩展不破坏 return param; } }六、违反时的错误信息对比java// 违反依赖倒置编译期就能发现 PayService service new PayService(); service.setHandler(new WechatPayHandler()); // OK service.setHandler(string); // ❌ 编译错误类型不匹配 // 违反里氏替换运行时才能发现 AbstractPayHandler handler new BadSimulateHandler(); PrePayParam param handler.buildPrePayParam(bizParam); if (param.getAmount().compareTo(BigDecimal.ZERO) 0) { throw new RuntimeException(金额必须大于0); // 运行时才炸 }七、记忆口诀原则记忆口诀思考问题依赖倒置面向接口不面向实现依赖的是抽象还是具体里氏替换子类替父行为不变子类替换父类后程序还能跑吗八、总结java// 依赖倒置定义用什么 PayHandler handler factory.getHandler(payType); // 用接口不用具体类 // 里氏替换保证怎么用 handler.doPrePay(param); // 无论 handler 是什么子类都能正常工作 // 两者配合 // 依赖倒置让你面向接口编程架构层面 // 里氏替换让你放心使用多态实现层面一句话总结依赖倒置告诉你依赖什么依赖抽象不依赖具体里氏替换保证你依赖的东西没问题子类替换后还能正常工作两者不是类似而是互补的关系。依赖倒置是设计时的选择里氏替换是实现时的约束。所有原则就上面种吗不止这6种这只是面向对象设计中最经典的6大原则SOLID 迪米特。完整的设计原则体系更丰富让我帮你梳理。一、设计原则体系总览分类原则核心思想核心原则单一职责、开闭、里氏替换、接口隔离、依赖倒置OO设计的基石包/组件原则复用发布等价、共同封闭、共同复用、无环依赖、稳定依赖、稳定抽象包/模块级别的设计其他重要原则迪米特、组合优于继承、好莱坞原则、最少惊讶补充性的最佳实践二、六大核心原则SOLID 迪米特你已经了解的这6个缩写原则英文S单一职责Single ResponsibilityO开闭原则Open-ClosedL里氏替换Liskov SubstitutionI接口隔离Interface SegregationD依赖倒置Dependency InversionLoD迪米特法则Law of Demeter三、包/组件级别原则6个这些原则来自《敏捷软件开发》一书用于指导模块/包/组件的设计。1. 复用发布等价原则REP定义复用的粒度就是发布的粒度。java// ❌ 违反一个包既有支付工具类又有日志工具类 // 想要复用支付工具却不得不带上日志类 // ✅ 符合按功能拆分成独立包 com.cloud.pay.utils // 支付相关工具独立发布 com.cloud.log.utils // 日志相关工具独立发布2. 共同封闭原则CCP定义应该一起修改的类应该放在同一个包里。java// ✅ 符合支付相关的类放在一起 com.cloud.pay.handler // 支付处理器 com.cloud.pay.model // 支付模型 com.cloud.pay.exception // 支付异常 // 修改支付逻辑时只影响这个包 // ❌ 违反支付类和订单类混在一起 com.cloud.common // 什么都往里放3. 共同复用原则CRP定义不应该强迫用户依赖他们不需要的类。java// ❌ 违反想要用支付功能却被迫依赖退款、对账功能 public interface PayHandler { void pay(); void refund(); // 不需要退款功能的用户也得依赖 void reconcile(); // 不需要对账功能的用户也得依赖 } // ✅ 符合接口按功能拆分 public interface PayHandler { void pay(); } public interface RefundHandler { void refund(); } public interface ReconcileHandler { void reconcile(); }4. 无环依赖原则ADP定义包的依赖关系图中不允许出现环。java// ❌ 违反循环依赖 // pay包 依赖 notify包 // notify包 依赖 pay包 → 循环依赖 // ✅ 符合引入抽象包打破循环 // pay包 依赖 common包 // notify包 依赖 common包 // common包 不依赖任何包5. 稳定依赖原则SDP定义依赖必须指向更稳定的方向。java// ❌ 违反不稳定的包依赖稳定的包方向反了 // 经常变化的 pay-handler 包 依赖 稳定的 pay-model 包 ✅ 正确 // 稳定的 pay-model 包 依赖 变化的 pay-handler 包 ❌ 错误 // ✅ 符合稳定的包被依赖不依赖别人 // pay-model稳定← pay-handler不稳定6. 稳定抽象原则SAP定义稳定的包应该是抽象的不稳定的包应该是具体的。java// ✅ 符合 // pay-model稳定→ 定义为接口抽象 public interface Payment { ... } // pay-handler不稳定→ 具体实现类 public class WechatPayment implements Payment { ... }四、其他重要设计原则1. 组合优于继承原则Composition over Inheritance定义优先使用对象组合而不是类继承。java// ❌ 继承过度使用 public class Animal { ... } public class Dog extends Animal { ... } public class Cat extends Animal { ... } // 问题继承层次过深难以维护 // ✅ 组合 public class Animal { private MoveStrategy moveStrategy; // 组合移动策略 private SoundStrategy soundStrategy; // 组合发声策略 } public class Dog { private Animal animal new Animal(new RunStrategy(), new BarkStrategy()); }在你的支付代码中java// 组合优于继承的应用 Component public class WechatPayHandler extends AbstractPayHandler { // 组合注入其他组件而不是继承 Autowired private TradeNoGenerator tradeNoGenerator; // ✅ 组合 Autowired private HttpClient httpClient; // ✅ 组合 // 而不是 // public class WechatPayHandler extends TradeNoGenerator ❌ 继承 }2. 好莱坞原则Hollywood Principle定义别打电话给我们我们会打给你。控制反转IoC的思想。java// 好莱坞原则的体现 // ❌ 违反子类主动调用父类依赖具体时机 public class BadSimulateHandler extends AbstractPayHandler { public void pay() { if (needRetry()) { // 子类决定是否重试 retry(); } super.pay(); } } // ✅ 符合父类控制流程子类只实现钩子 public abstract class AbstractPayHandler { public final void process() { beforePay(); // 钩子 doPay(); // 抽象方法 afterPay(); // 钩子 } protected void beforePay() {} // 子类可重写但不决定调用时机 } public class SimulatePayHandler extends AbstractPayHandler { Override protected void beforePay() { // 只管实现不管何时调用父类决定 } }3. 最少惊讶原则Principle of Least Astonishment定义代码的行为应该符合用户的预期不要让人惊讶。java// ❌ 违反行为出乎意料 public class Calculator { public int add(int a, int b) { return a - b; // 惊讶叫add却是减法 } } // ✅ 符合名实相符 public class Calculator { public int add(int a, int b) { return a b; // 符合预期 } } // 在你的支付代码中 public class SimulatePayHandler extends AbstractPayHandler { // ✅ 方法名和实际行为一致 Override public PrePayResult doPrePay(PrePayParam param) { log.info(模拟支付); // 模拟支付不真实调用接口 return PrePayResult.success(); } }4. 不要重复自己原则DRY - Dont Repeat Yourself定义每一项知识在系统中都应该有单一、明确、权威的表示。java// ❌ 违反重复代码 public class WechatPayHandler { public PrePayParam buildParam() { String tradeNo generateTradeNo(); // 重复 BigDecimal amount getAmount(); // 重复 // ... } } public class AlipayHandler { public PrePayParam buildParam() { String tradeNo generateTradeNo(); // 重复 BigDecimal amount getAmount(); // 重复 // ... } } // ✅ 符合提取公共逻辑 public abstract class AbstractPayHandler { public PrePayParam buildParam() { String tradeNo generateTradeNo(); // 只写一次 BigDecimal amount getAmount(); // 只写一次 // ... } }5. 高内聚低耦合原则High Cohesion Low Coupling定义模块内部紧密相关模块之间松散依赖。java// 你的代码完美体现了这个原则 // 高内聚每个类职责单一 public class TradeNoGenerator { ... } // 只负责生成流水号 public class SignUtil { ... } // 只负责签名 public class WechatPayHandler { ... } // 只负责微信支付 // 低耦合通过接口依赖 public class PayService { private PayHandler handler; // 依赖接口不依赖具体类 }6. YAGNI 原则You Aint Gonna Need It定义不要添加你当前不需要的功能。java// ❌ 违反过度设计 public interface PayHandler { void pay(); void refund(); void query(); void cancel(); void notify(); void retry(); // 当前不需要 void backup(); // 当前不需要 void report(); // 当前不需要 } // ✅ 符合只实现需要的功能 public interface PayHandler { void pay(); // 当前需要 void refund(); // 当前需要 // 其他功能等需要时再加 }7. 契约式设计Design by Contract定义通过前置条件、后置条件、不变量来定义接口契约。javapublic abstract class AbstractPayHandler { // 契约定义 public PrePayParam buildPrePayParam(PayBizParam bizParam) { // 前置条件参数不能为空 assert bizParam ! null : bizParam不能为空; assert bizParam.getAmount() ! null : 金额不能为空; assert bizParam.getAmount().compareTo(BigDecimal.ZERO) 0 : 金额必须大于0; PrePayParam param new PrePayParam(); param.setTradeNo(buildTradeNo()); param.setAmount(bizParam.getAmount()); // 后置条件返回结果不能为空tradeNo不能为空 assert param ! null : 返回结果不能为空; assert StringUtils.isNotBlank(param.getTradeNo()) : tradeNo不能为空; return param; } }五、完整原则清单序号原则英文关注层次1单一职责SRP类级别2开闭原则OCP类/模块级别3里氏替换LSP继承关系4接口隔离ISP接口设计5依赖倒置DIP架构级别6迪米特法则LoD方法调用7复用发布等价REP包级别8共同封闭CCP包级别9共同复用CRP包级别10无环依赖ADP包级别11稳定依赖SDP包级别12稳定抽象SAP包级别13组合优于继承-类设计14好莱坞原则-控制反转15最少惊讶-API设计16DRY-代码复用17高内聚低耦合-模块设计18YAGNI-功能规划19契约式设计DbC接口契约六、优先级建议对于日常开发按重要性排序优先级原则必须掌握程度⭐⭐⭐⭐⭐单一职责、开闭原则、依赖倒置必须熟练运用⭐⭐⭐⭐里氏替换、接口隔离、DRY必须理解⭐⭐⭐迪米特、组合优于继承、高内聚低耦合尽量遵守⭐⭐好莱坞、最少惊讶、YAGNI了解即可⭐REP、CCP、ADP等包级原则架构师需掌握对于你当前的学习阶段先把SOLID 迪米特 DRY这8个掌握好就足够了。包级别原则通常是在设计大型系统时才需要考虑。本回答由 AI 生成内容仅供参考请仔细甄别。

更多文章