资讯动态

面向对象怎么找实体?六步拆解法

发布时间:2026/10/17 10:42:33 来源:尧图企业网站定制
刚学面向对象时有个困惑需求一来不知道该怎么建类。要么只建一个Student类塞满所有字段要么凭感觉随便建几个后面一改需求就全乱。其实实体抽象不是靠灵感而是有一套可以反复用的拆解流程。下面以学生档案系统为例完整走一遍。第一步把需求说成完整句子不能只盯着学生档案系统这六个字。可以先在脑子里编几个真实的使用场景把需求展开成完整的句子新生入学要录入基本信息然后分到某个班级老师要给某门课录入成绩学生可以申请转专业档案信息要跟着改学生毕业时档案要归档后续可能调档管理员、教师、学生登录后看到的权限不同每句话里出现的主语、宾语、涉及的东西基本都是候选实体。这一步看似简单但很因为需求只有一句话脑子里容易没有场景需要经常联想第二步圈名词然后逐个筛把上面场景里的名词圈出来学生、班级、专业、学院、老师、课程、成绩、档案、账号、角色、学期。然后可以关联问题它有没有自己的数据要存有 → 可能是实体它有没有独立的生命周期能单独创建、修改、删除 → 可能是实体它会不会被多个地方引用会 → 值得单独建类比如手机号它只是学生的一个属性不会单独被管理就不建类。成绩看着像学生的属性但它同时关联学生和课程还有学期、补考记录需要独立存在所以要拆成单独的Score类。第三步圈动词找职责归属动词有录入、分班、录成绩、算平均分、转专业、归档、调档、登录、鉴权。对每个动词问干这件事需要谁的数据谁最该负责改手机号 → 只涉及学生自己的数据放Student身上写成changePhone()分班 → 涉及班级和学生放Clazz或ClassService算平均分 → 要一堆成绩数据放ScoreService登录鉴权 → 跟学生本身没关系放AuthService别塞进Student这一步能避免书自己卖自己那种职责放错的问题。第四步看关系反推缺失实体把实体之间的关系画一下很容易发现漏掉的学生和课程是多对多 → 中间必然要有一个Score或Enrollment选课记录老师和课程是一对多 → 需要Course来承载专业属于学院 → 需要Department档案有调阅历史 → 可能需要ArchiveRecord调档记录多对多关系几乎必然隐含一个中间实体第五步区分实体、服务、工具有数据、有生命周期 → 实体类Student、Course、Clazz是一串流程、要协调多个对象 → ServiceScoreService、ArchiveService跟业务无关的通用操作 → 工具类日期处理、字符串处理只是打包数据传过来传过去 → DTO / VO不要把登录逻辑塞进Student也不要把成绩计算塞进Course各司其职才容易维护。第六步用改需求验证假装客户改需求看你的抽象会不会崩以后一个学生可以辅修第二个专业 → 说明学生里直接存专业字段不行要抽Major和关联关系以后还有教师档案 → 说明可以把人和档案抽象出通用结构不同学院毕业要求不一样 → 说明毕业判断适合用策略模式而不是 if-else 堆一坨流程概览从场景找名词 → 逐个筛实体 → 从动词找职责 → 从关系找漏掉的 → 区分实体和服务 → 用改需求验证用书店卖书走一遍六步拆解法第一步把需求说成完整句子书店卖书四个字把真实场景展开顾客走进书店挑选一本书到收银台付款收银员扫描书的条码系统扣减库存打印小票书店有多种书每本书有书名、作者、定价、库存数量会员可以享受折扣不同会员等级折扣不同卖出去的书要记一笔交易记录方便后面查账库存不够时店员要补货第二步圈名词然后逐个筛圈出来的名词顾客、书、书店、收银员、会员、折扣、库存、小票、交易记录、补货单。逐个问三个问题书有书名、作者、ISBN、定价、库存 → 有数据、有生命周期 →建类顾客有姓名、手机号、会员等级 → 会被多处引用 →建类书店有名称、地址、库存清单、营业额 →建类会员本质是顾客的一种状态或类型可以用枚举或继承不一定单独建类折扣只是顾客的一个属性或计算规则不建类小票 / 交易记录每次交易产生一条有独立生命周期 →建类可以叫Order或Transaction补货单如果系统要管理补货流程就建类如果只是简单加库存可以不建收银员如果只是执行卖书动作的人可以归到Staff或干脆作为操作者参数不一定单独建类这一步筛完核心实体大概有Book、Customer、Bookstore、Order。第三步圈动词找职责归属动词有挑选、付款、扫描、扣库存、打印小票、计算折扣、补货、查账。逐个问谁该负责扣库存库存是书的属性但扣库存这个动作涉及交易放Book上写reduceStock()可以但更合理的是由Bookstore或OrderService来调用计算折扣跟会员等级有关但折扣规则可能变化适合单独抽一个DiscountStrategy而不是塞进Customer打印小票小票是Order生成的Order上可以有个generateReceipt()方法付款涉及钱、支付方式、订单放OrderService或PaymentService不要放Book上补货是书店的操作放Bookstore上写成restock(book, quantity)关键判断book.sell()是错的因为书不知道自己有没有库存、卖给谁、多少钱成交、要不要打折。卖书是一个涉及多方协作的流程应该由Bookstore或OrderService来协调。第四步看关系反推缺失实体画一下关系顾客和书是多对多一个顾客可以买多本书一本书可以被多个顾客买→ 中间必须有Order或OrderItem书店和书是一对多 →Bookstore里有ListBook库存顾客和订单是一对多 →Customer里有ListOrder订单和书是多对多 → 需要OrderItem订单项记录某笔订单里买了哪本书、买了几本、单价多少这里很容易漏掉OrderItem。如果直接在Order里存一个ListBook就没法记录买了两本同一本书或者当时成交价和标价不一样。第五步区分实体、服务、工具实体类Book、Customer、Bookstore、Order、OrderItem服务类OrderService下单、付款、InventoryService库存管理、DiscountService折扣计算枚举MemberLevel普通会员、银卡、金卡、PaymentMethod现金、微信、支付宝工具类PriceFormatter价格格式化、BarcodeScanner条码扫描如果要做硬件对接不要把计算总价应用折扣全塞进Order一旦折扣规则变复杂Order就会膨胀。第六步用改需求验证以后支持网购配送→ 说明Order里需要加收货地址、物流状态Bookstore可能拆成线上店和线下店抽象出一个Store接口书有精装版和平装版价格不同→ 说明Book可能需要子类或者加一个Edition实体书店有多个分店→ 说明Bookstore之上还需要一个ChainStore库存要按分店管理支持退货→ 说明Order要有状态流转已支付、已完成、已退货OrderService要处理退款逻辑Book — 书名、作者、ISBN、定价、当前库存 Customer — 姓名、手机号、会员等级 Bookstore — 名称、地址、库存列表、营业额 Order — 订单号、顾客、订单项列表、总价、状态、时间 OrderItem — 书、数量、成交单价 OrderService — 创建订单、付款、退货 DiscountService — 根据会员等级计算折扣

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑