类设计应先确认概念是否为业务中独立有边界的实体,避免Helper/Util等职责不清命名;优先用领域名词建类、动词作方法,拒绝Manager/Handler泛滥;修改频繁则检查职责是否单一;继承需满足“是一种”语义,否则用组合;接口应聚焦同一组能力,命名体现契约而非实现;封装重在控制可变性而非仅设private。
面向对象不是一上来就建类,而是先问:这个概念在业务里是不是一个独立的、有明确边界的实体?比如 Order 可以,但 OrderHelper 或 OrderUtil 往往是设计信号不良——说明职责还没收敛到合适的类里。
常见错误是把过程式逻辑硬塞进类:写个 OrderProcessor,里面堆满 validate()、calculate()、sendNotification(),却让 Order 只剩几个 getXXX()。结果是行为和数据分离,修改一个校验规则要跳 3 个类。
实操建议:
User、Payment、Inventory),动词优先落在对应类的方法里(user.activate()、payment.refund())InventoryService 里extends 的滥用是 Java 项目里最典型的 OOP 误用。看到两个类有相似字段和方法,第一反应不是拉个父类,而是先问:子类在语义上真的是父类的一种吗?Dog extends Animal 合理,ReportExporter extends DatabaseConnection 就荒谬——后者只是用了连接,不是“是一种连接”。
容易踩的坑:
DatabaseConnection.close() 被 ReportExporter 继承后根本不用,还可能被误调)更稳妥的做法是组合:ReportExporter 持有 DatabaseConnection 实例,需要时调用;复用靠接口 + 委托,而不是靠 extends。
接口名别叫 OrderServiceImpl,那是实现类的名字;应该叫 OrderRepository 或 OrderValidator——前者声明“能查订单”,后者声明“能验订单”,不暴露实现细节。
关键判断点:
save() 又有 sendEmail(),大概率职责混杂OrderService 里塞了太多外部依赖(HTTP 调用、文件读写),单元测试就难写,说明它抽象层次错了create(OrderRequest request) 比 create(String orderId, BigDecimal amount, String userId) 更易维护、更可读一个简单验证法:把接口所有方法列出来,用自然语言连成一句话。如果说不通(比如“一个订单服务能保存、能发邮件、能生成 PDF、能连 Redis”),那就该拆。
给每个字段配 getXXX()/setXXX() 是最省事的封装,也是最无效的封装。真正重要的不是“能不能访问”,而是“能不能随意改”。比如 Order.status 如果允许任意设为 "PAID"、"SHIPPED"、"CANCELLED",却不校验状态流转规则(不能从 "SHIPPED" 直接回退到 "PAID"),那 private 和 public 没本质区别。
实操要点:
final,构造时赋值;必须可变的,通过受控方法修改(order.cancel() 内部校验再改状态)getItems() 返回 Collections.unmodifiableList(items),而不是直接返回原始 List

order.hasOverduePayments() 比 order.getPayments().stream().anyMatch(...) 更安全)面向对象的落地难点不在语法,而在每次写 class、extends、interface 时,多停半秒想清楚:这个结构是否真实反映了问题域里的关系?还是仅仅让编译通过了?