漫画系统中发行版与副本的对象结构设计方案咨询
解决方案:漫画发行版与副本的设计实现
核心问题拆解
你需要的是副本复用发行版的属性但不重复存储,继承模式虽然能实现属性复用,但每个副本实例会冗余存储发行版的属性值,不符合“不存储”的要求。更合适的是采用组合+委托模式,或结合共享实例的方式来实现。
方案1:组合+委托模式(推荐)
这种模式下,副本不继承发行版,而是持有一个发行版的引用,通过委托的方式获取发行版的属性,完全避免属性冗余存储。
示例代码(以Java为例):
// 发行版类:封装所有发行级属性 public class Release { private String isbn; private String title; private String author; private LocalDate publishDate; private BigDecimal price; // 构造器、getter方法 public String getIsbn() { return isbn; } public String getTitle() { return title; } // 其他属性的getter方法... } // 副本类:持有发行版引用,仅存储自身独有的属性 public class Copy { private String copyId; private LocalDate stockDate; private String status; // 例如 "IN_STOCK", "BORROWED", "DAMAGED" private String currentHolder; private Release release; // 持有发行版的引用 // 构造器 public Copy(String copyId, LocalDate stockDate, String status, Release release) { this.copyId = copyId; this.stockDate = stockDate; this.status = status; this.release = release; } // 副本自身属性的getter/setter public String getCopyId() { return copyId; } public void setStatus(String status) { this.status = status; } // ... // 委托获取发行版的属性 public String getReleaseIsbn() { return release.getIsbn(); } public String getReleaseTitle() { return release.getTitle(); } // 其他发行版属性的委托方法... }
这种方式的优势:
- 副本完全不存储发行版的属性,仅通过引用获取,节省存储空间
- 发行版属性修改后,所有关联的副本都会实时获取到最新值
- 避免了继承带来的耦合问题,后续扩展更灵活(比如副本可以关联其他类型的发行实体)
方案2:调整继承模式(满足你最初的想法,但有局限性)
如果坚持要用继承,需通过共享属性实例的方式避免重复存储。将发行版的属性封装为不可变对象,让同一发行版的所有副本共享该对象的引用:
// 封装发行版属性的不可变类 public record ReleaseAttributes(String isbn, String title, String author, LocalDate publishDate, BigDecimal price) {} public class Release { private final ReleaseAttributes attributes; public Release(ReleaseAttributes attributes) { this.attributes = attributes; } public ReleaseAttributes getAttributes() { return attributes; } } public class Copy extends Release { private String copyId; private LocalDate stockDate; private String status; public Copy(ReleaseAttributes attributes, String copyId, LocalDate stockDate, String status) { super(attributes); this.copyId = copyId; this.stockDate = stockDate; this.status = status; } // 副本自身属性的getter/setter... }
这里同一发行版的所有副本共享同一个ReleaseAttributes实例,避免了属性值的重复存储,同时保留了继承的结构。
方案3:数据库层面的配合设计(若涉及持久化)
如果系统需要持久化到数据库,可通过表结构设计避免属性冗余:
releases表:存储发行版的所有属性,主键为release_idcopies表:仅存储副本独有的属性,加上release_id外键关联到releases表- 查询副本时,通过JOIN操作关联
releases表获取发行版属性,不在copies表中冗余存储发行版字段
这种设计和组合模式完全对应,从数据层面保证了属性不重复存储。
内容的提问来源于stack exchange,提问作者Notorjus
相关产品推荐
相关产品推荐

