java 得到复合值的正确方法是什么

gmxoilav  于 2023-09-29  发布在  Java
关注(0)|答案(1)|浏览(107)

我在一个项目中工作,其中有3个类之间的关系:收藏,系列和卡片。
集合有ID和名称。序列具有ID和名称。一张卡有身份证和姓名。
一个集合是20个系列的化合物。一个系列是复合20卡。
所以,我有一个关系,我认为我可以用这种方式来解决:

class Collection {
    final String id;
    final String name;
    final List<Serie> series;

    public Collection(String id, String name, List<Serie> series) {
        this.id = id;
        this.name = name;
        this.series = series;
    }
}

class Serie {
    final String id;
    final String name;
    final List<Card> cards;

    public Serie(String id, String name, List<Card> cards) {
        this.id = id;
        this.name = name;
        this.cards = cards;
    }
}

class Card {
    final String id;
    final String name;

    public Card(String id, String name) {
        this.id = id;
        this.name = name;
    }
}

问题是,我必须显示一个布局,其中卡片必须显示名称和以这种方式形成的复合值:集合ID +系列名称+卡ID。
我是否应该为Card添加一个额外的属性来保存该值?或者你觉得怎样才是好的出路?

piztneat

piztneat1#

我是否应该为Card添加一个额外的属性来保存该值?或者你觉得怎样才是好的出路?
这里没有绝对的答案。背景很重要。
正如在评论中所指出的,通常最好将任意表示与内容(“模型”)分开。但如果所需的表示文本是数据模型所表示的实体所固有的,则不是这样。

  • 如果表示细节可能会因各种原因而发生合理的变化,那么您的数据模型(您向我们展示的三个类)不应该生成该特定值。表示文本应该由其他类生成,而不是您的数据模型类(CollectionSerieCard)。例如,在 java.time 类中,请参阅DateTimeFormatter类,它代表诸如LocalDate之类的日期-时间类生成任意或复杂文本。
  • 如果特定的表示文本(集合ID +系列名称+卡片ID)是规范的或标准化的正式/官方结构,那么您的数据模型类(CollectionSerieCard)* 应该 * 生成该文本。例如,java.time 类有一个toString类,它生成标准ISO 8601的文本,还有一个getDisplayName方法来生成格式化文本。

因此,我们无法真正回答您的特定问题,因为我们不了解您从中获得集合,系列和卡片实体的域。
顺便说一下,我们可以简化代码。
如果你的类主要是作为浅不可变数据的透明载体,那么在Java 16+中使用record。构造函数、getter、hashCode & equalstoString都是由编译器隐式创建的。
在Java 21+中,您可以使用更通用的接口SequencedCollection而不是List。请参见JEP 431: Sequenced Collections
如前所述,CollectionJava Collections Framework中类的超接口。如果可能的话,我会选择一个不同的名字。如果是您的域所固有的,则只需小心使用import语句。
您的问题代码将变为:

class Collection ( String id , String name , SequencedCollection < Serie > series ) {}
class Serie ( String id , String name , SequencedCollection < Card > cards ) {}
class Card ( String id , String name ) {}

可以向记录添加其他方法。如果您决定表示文本是模型固有的,则添加一个名为getDisplayName的方法。

class Collection ( String id , String name , SequencedCollection < Serie > series ) 
{
    public String getDisplayName() 
    { 
        StringBuilder stringBuilder = new StringBuilder() ;
        for ( Serie serie : this.series ) 
        { 
            for ( Card card : serie.cards )
            {
                stringBuilder
                    .append( this.id ) 
                    .append( " | " ) 
                    .append( serie.name ) 
                    .append( " | " ) 
                    .append( card.id ) 
                    .append( "\n" ) 
            }
        }
        return stringBuilder.toString() ;
    }
}

相关问题