与实体不直接相关的属性的最佳设计方法是什么?

What is the best design approach for attributes that are not directly related to an entity?

我想在 Java 中创建一个模拟图书馆的迷你应用程序。我创建了一个名为 Book 的 class,它具有以下属性:

public class Book {
    private final String ISBN;
    private String title;
    private String author;
    private String domain;
    private int numberOfPages;
}

我想再添加两个属性:stockprice。但是这些属性与真正的书没有直接关系(比如 ISBNtitle)所以我不知道在哪里添加它们:在Book 或另一个 class...

一个想法是创建一个名为 BookView 的新 class(不确定它是否是最佳名称)并添加如下属性:

public class BookView {
    private Book book;
    private short stock;
    private float price;
}

另一个想法是扩展 Book 并创建一个 BookWithDetails 子 class 来添加股票和价格,但我不确定继承是否派上用场对于这种情况:

public BookWithDetails extends Book {
    private short stock;
    private float price;
}

对于这种情况,最好的方法是什么?

在您的方案中,创建一个类似于 BookView 的 class 似乎是最佳选择:

,如您的 post 所示
public class BookManager {
    private short stock;
    private float price;
    private Book book;
}

这样,经理 class 将有关图书价格和数量的额外信息与实际图书本身分开。

因为字段声明为 private,您应该添加 setter 和 getter 方法来检索字段的值。作为一些 getter 方法的示例:

public short getStock() {
    return stock;
}

public float getPrice() {
    return price;
}

public Book getBook() {
    return book;
}

附加属性不属于 Book,原因有二:

  • 他们描述了其他东西 - 他们没有描述这本书,而是描述了 很多 以特定价格出售的书籍,并且
  • 一本书可能有多个这样的属性 - 理论上,您可能有五本书每本 10 美元,三本书每本 8 美元。

因此,您的 BookView class 是代表一批图书的不错选择,但我会重命名它:

public class BookLot {
    private Book book;
    private short stock;
    private float price;
}

同时考虑将 price 更改为 int,并理解它代表美分或以所需货币表示的任何形式。这是因为 floatdouble 不太擅长表示小数,而 BigDecimal 对于表示微小的小数可能太浪费了。

只是为了对这里的其他人有不同的看法:我认为你应该在 Book class 中同时拥有 stockprice。让我详细说明一下:

什么是真实的?你如何定义"real"?

有时人们说,在 OO 中我们建模 "real world"。这不完全正确。我们为业务建模,我们调用业务领域中存在的所有内容 "real"。并非所有这些东西 在传统意义上都是 实际上是真实的,而且大多数职业(即 "businesses")都有特殊的术语,可能会给他们 [=73= 中的单词分配不同的语义] 日常意义。

什么是"Book"?

我的母语不是英语,但我相信 "Book" 这个词有多重含义。 "Book" 一词可能指代一整组物理对象,或指代单个具体的物理对象。

例如:作者 X 有一本新书。或者:我可以借那本书吗?

图书馆

事情变得更加复杂,因为您的域是 "Library"。只需与图书管理员(即您域中的 "business" 人)交谈即可。

图书管理员会说:"My current stock of BookView is ..."吗?她大概不会这么说,她会说:"My current stock of Book X is ..."。或者类似的东西。

还有,她怎么称呼你可以查看的单个物理对象?她很可能会说:"Here is your copy of Book X." 或类似的话。

建模

现在,我们知道域中存在什么 "things",让我们看看我们如何对其建模。在 OO 中,我们不太关心数据,因此实际上 这些数据所在的位置并不那么重要。

重要的部分是行为,这些"things"可以为我们提供什么。我的第一次尝试是这样的:

public interface Book {
    Copy checkout();
}

public interface Copy {
    void return(); // I know, keyword
}

可能我需要 Book 中的 stockprice 来促进 checkout(),但根据 行为,这是次要的我分配给了Book。没有 行为 ,数据无关紧要。

基本上,答案就在您的问题中:对于与 实体没有直接关系的属性,最好的设计方法是什么?

如果您需要扩展 具有与对象无关的特征的对象,请考虑组合。如果扩展对象前一个对象,考虑继承。

没错,这个名字不是最好的,可以说是 BookProductBookCommodity(不太喜欢这个……)

public class BookProduct {
    private Book book;
    private short stock;
    private float price;
}