我有一个名为SalesOrder
(SO)的课程,允许用户在一个订单中购买多个项目。 SO有一个订单号。
class SalesOrder {
public String orderNumber;
}
每个SO都有很多项目,因此我创建了一个新的类OrderItem
,其中包含项目名称和价格。
class OrderItem {
public String name;
public double price;
}
每个SO都有一个订单标题,包括用户名和地址。它还有一个名为总价的字段,它保存所有商品价格的总和
class OrderHeader {
public String username;
public String address;
public double totalPrice;
}
之后,我在SO中添加了两个字段:
class SalesOrder {
...
public List<OrderItem> items;
public OrderHeader header;
}
因为OrderItem和OrderHeader总是与SalesOrder一起使用,并且标题应该返回所有商品价格,我将它们转换为SalesOrder的内部类。
class SalesOrder {
...
public SalesOrder() {
this.items = new ArrayList<>();
this.header = new OrderHeader();
}
public class OrderItem {
...
}
public class OrderHeader {
...
public double getTotalPrice() {
double total = 0.0;
// loop SalesOrder.items
total += items[i].price;
return total;
}
}
}
我的问题是,使用这样的内部类是否是良好的OOP设计?如果没有,它们应该如何设计?
=======更新一些信息=======
我很抱歉我没有提供更多的信息。
Header和Item使得他们将方法解释为私有,其他对象无法在没有SalesOrder的情况下创建它们。
SalesOrder有一个工厂方法
class SalesOrder {
...
public SalesOrder parseOrder(Xml xml) {
//init header and items from xml
this.header = new OrderHeader(valueFromXml, valueFromXml);
}
public class OrderHeader {
....
private OrderHeader(username, address) { ... }
}
public Class OrderItem {
...
private OrderItem(name, price) { ... }
}
}
其他对象就像这样使用它们
Xml xml = orderXmlData;
SalesOrder order = SalesOrder.parseOrder(orderXmlData);
OrderItem item = order.item;
OrderHeader header = order.header;
答案 0 :(得分:1)
有一些建议可能会改善您的设计。首先,我似乎不太可能totalPrice
应该是标题的一部分。它似乎更有可能来自订单项而不是标题的组成部分。其次,除非您希望类的客户创建独立于订单的订单项,否则似乎不需要将它们定义为类。最好转换为从订单返回的interface
。第三,没有理由Header
不能成为接口 - 这允许客户端使用他们想要的任何类作为标题,只要它具有名称和地址。
所以我的建议是这样的:
class Order {
interface Item {
String getName();
double getPrice();
}
interface Header {
String getName();
Address getAddress();
}
public Order(Header header) {
...
}
public double getTotalPrice() {
return streamItems().mapToDouble(Item::getPrice).sum();
}
public void addItem(String name, double price) {
...
}
public Stream<Item> streamItems() {
...
}
}
答案 1 :(得分:0)
嵌套类的使用取决于要求。我认为不需要在代码中使用嵌套类。如果它是Java Beans类,那么您应该将类分开,以便它们可以重用。除了嵌套类的最后一段代码之外,您的设计也很完美。