题目重点:从状态边界和可替换接口解释三特征,区分继承与组合,避免把私有命名当安全隔离。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 讨论Python 3对象模型与业务设计,不承诺所有实现底层布局相同。
- 用支付测试适配器作虚构练习案例,不代表指定框架。
解题路线
- 封装是让对象维护自身不变量并通过明确接口修改状态,例如Payment的金额、币种和状态转换不能任意改写;仅把字段放进class并不自动保证业务约束。
- Python单下划线是非公共命名约定,双下划线触发名称改写以减少子类冲突;都不是阻止恶意访问的安全权限。敏感凭证访问仍需真实授权与隔离。
- 继承表达子类型关系:子对象应在父接口的预期合同下可替换。若子类加强输入前提或悄悄改变返回/异常语义,调用方测试会被破坏,不能只检查isinstance。
- 多态可以通过同名协议实现,不必共享父类。两个适配器都有charge/refund接口,测试服务只依赖协议;duck typing要配合接口合同、类型检查或契约测试,避免误把同名当同义。
- 组合适合“使用某能力”:支付服务持有gateway而非继承某云支付客户端,能注入fake并单测状态机。继承用于稳定可替换层级,避免多层层级牵动所有测试。
- 回答时连接测试风险:验证对象边界、覆盖子类型相同合同、用依赖注入控制外部副作用;不要仅背三词而没有实际设计判断。
手动走一遍
Dog.speak返回woof,Robot.speak返回beep;列表中的对象均可调用speak,展示协议多态。业务上同理,fake gateway与真实gateway应遵守相同成功/失败合同,fake不能总成功而遮住异常路径。
规模与取舍
设计原则没有统一运行复杂度;协议分派成本不是测试总耗时主因,外部IO与数据规模另测。组合可缩小单测依赖,不保证必然减少运行时间。
易错点与追问
容易失分的边界
- 把双下划线当访问权限。
- 为复用几行代码建立不满足可替换性的继承。
- fake只覆盖成功路径。
继续深挖
- 抽象基类与结构协议怎样选?
- 子类改变异常类型如何发现?
- 测试对象不变量应放在哪层?
技术参考
- Python Data Model:技术语义参考,具体题目按本文约定。
