与实体不直接相关的属性的最佳设计方法是什么?
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;
}
我想再添加两个属性:stock 和 price。但是这些属性与真正的书没有直接关系(比如 ISBN 或 title)所以我不知道在哪里添加它们:在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
,并理解它代表美分或以所需货币表示的任何形式。这是因为 float
和 double
不太擅长表示小数,而 BigDecimal
对于表示微小的小数可能太浪费了。
只是为了对这里的其他人有不同的看法:我认为你应该在 Book
class 中同时拥有 stock
和 price
。让我详细说明一下:
什么是真实的?你如何定义"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
中的 stock
和 price
来促进 checkout()
,但根据 行为,这是次要的我分配给了Book
。没有 行为 ,数据无关紧要。
基本上,答案就在您的问题中:对于与 实体没有直接关系的属性,最好的设计方法是什么?
如果您需要扩展 具有与对象无关的特征的对象,请考虑组合。如果扩展对象是前一个对象,考虑继承。
没错,这个名字不是最好的,可以说是 BookProduct
或 BookCommodity
(不太喜欢这个……)
public class BookProduct {
private Book book;
private short stock;
private float price;
}
我想在 Java 中创建一个模拟图书馆的迷你应用程序。我创建了一个名为 Book
的 class,它具有以下属性:
public class Book {
private final String ISBN;
private String title;
private String author;
private String domain;
private int numberOfPages;
}
我想再添加两个属性:stock 和 price。但是这些属性与真正的书没有直接关系(比如 ISBN 或 title)所以我不知道在哪里添加它们:在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 似乎是最佳选择:
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
,并理解它代表美分或以所需货币表示的任何形式。这是因为 float
和 double
不太擅长表示小数,而 BigDecimal
对于表示微小的小数可能太浪费了。
只是为了对这里的其他人有不同的看法:我认为你应该在 Book
class 中同时拥有 stock
和 price
。让我详细说明一下:
什么是真实的?你如何定义"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
中的 stock
和 price
来促进 checkout()
,但根据 行为,这是次要的我分配给了Book
。没有 行为 ,数据无关紧要。
基本上,答案就在您的问题中:对于与 实体没有直接关系的属性,最好的设计方法是什么?
如果您需要扩展 具有与对象无关的特征的对象,请考虑组合。如果扩展对象是前一个对象,考虑继承。
没错,这个名字不是最好的,可以说是 BookProduct
或 BookCommodity
(不太喜欢这个……)
public class BookProduct {
private Book book;
private short stock;
private float price;
}