You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

漫画系统中发行版与副本的对象结构设计方案咨询

解决方案:漫画发行版与副本的设计实现

核心问题拆解

你需要的是副本复用发行版的属性但不重复存储,继承模式虽然能实现属性复用,但每个副本实例会冗余存储发行版的属性值,不符合“不存储”的要求。更合适的是采用组合+委托模式,或结合共享实例的方式来实现。

方案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_id
  • copies表:仅存储副本独有的属性,加上release_id外键关联到releases表
  • 查询副本时,通过JOIN操作关联releases表获取发行版属性,不在copies表中冗余存储发行版字段

这种设计和组合模式完全对应,从数据层面保证了属性不重复存储。


内容的提问来源于stack exchange,提问作者Notorjus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 06:37:36