是一个在课堂上使用内部类的好设计吗?

时间:2015-07-23 04:44:04

标签: java oop design-patterns

我有一个名为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;

2 个答案:

答案 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类,那么您应该将类​​分开,以便它们可以重用。除了嵌套类的最后一段代码之外,您的设计也很完美。