前端多端逻辑解耦应通过接口契约与工厂函数实现运行时装配,而非条件编译或组件内平台判断;组件只依赖抽象接口,由上层按环境注入具体实现,从而隔离平台差异、提升可测性与可维护性。

直接结论:前端多端逻辑解耦,靠的不是条件编译或运行时判断平台,而是把“用哪个实现”这件事从组件内部移出去——让组件只声明依赖接口,由上层按环境注入对应实现。
为什么 if (isH5) { new H5Payment() } else { new PCPayment() } 是坏味道
这种写法表面解决了分支问题,实际埋下三处隐患:
- 组件被迫感知平台细节,
H5Payment和PCPayment的构造参数、生命周期、错误处理差异会不断扩散到调用处 - 单元测试必须 mock 平台检测逻辑(
isH5),且无法单独验证 PC 支付流程 - 新增小程序端时,得改所有含该判断的组件,漏一处就白屏或降级失败
用接口 + 工厂函数做运行时装配
核心动作只有两步:定义契约、按需创建。不引入容器,不加装饰器,纯手动但足够收敛。
前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。前端设计与 UI/UX 全方位优化专家。覆盖视觉层次、排版系统、色彩理论、响应式布局、交互体验、动画动效、无障碍访问、性能优化八大维度,帮助开发者将普通页面升级为高品质产品级界面。
- 先写统一接口:
interface PaymentAdapter { pay(order: Order): Promise<void> }</void> - 再写两个工厂:
createH5Payment()和createPCPayment(),各自封装 SDK 初始化、事件监听、回调桥接等端特有逻辑 - 在应用入口(如
main.ts或根Provider)根据location.hostname或构建变量决定调用哪个工厂,并把结果注入到业务组件
示例(简化):
const payment = isH5 ? createH5Payment() : createPCPayment();
const orderProcessor = new OrderProcessor({ payment });
如何让组件完全不感知平台切换?
关键在注入时机和层级——不能在组件内部做判断,也不能让组件自己去 import 端实现。
- 所有端适配逻辑收口在工厂函数内,比如
createH5Payment()里自动注册 WebView JSBridge 回调,createPCPayment()里自动绑定支付宝 SDK 的window.alipay - 组件只接收
PaymentAdapter类型参数,类型系统会阻止你传错实现 - 构建时若需静态分离(如 H5 包不打包 PC SDK),用 Webpack 的
resolve.alias或 Vite 的define控制工厂函数返回值,而非在组件里import()动态加载
容易被忽略的边界点
真正卡住落地的往往不是架构设计,而是这些细节:
-
PaymentAdapter接口必须包含所有端共性行为,但不要强行抽象“不存在的公共方法”,比如 H5 用 URL 跳转、PC 用弹窗,那就定义launch(): void,而不是openPopup(): void+redirectTo(): void - 端特有配置(如 H5 的
redirectUrl、PC 的appId)应由工厂函数从全局配置中心(如window.__CONFIG__)读取,不通过组件 props 透传 - 如果某组件既用于 H5 又用于 PC,但内部逻辑确实需要平台判断(如样式类名),请用 CSS 媒体查询或 class name 工具函数,而非在 JS 里写
if (isH5)
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










