1.封装集合

资料参考:https://blog.csdn.net/a138520844a/article/details/24313513,https://blog.csdn.net/knightswarrior/article/details/9447815

概念:本文所讲的封装集合就是把集合进行封装,只提供调用端需要的接口。

正文:在很多时候,我们都不希望把一些不必要的操作暴露给调用端,只需要给它所需要的操作或数据就行,那么做法就是封装。本例子介绍了集合的封装方法,当某些类需要向类的使用者提供类中的集合时,而且该集合的addXXXXX方法是经过了一些特别处理的时候,如果这时类的使用者通过get方法获得集合的时候,再使用集合本身的add方法的时候,就会绕过类的addXXXXX方法,就不能达到预期的目的。本节将介绍一种方法:既能让类的使用者使用集合,又能防止使用者向集合中添加数据、删除数据等修改操作。

下面举个例子:一个订单的例子

 1 /**
 2  * 订单管理类
 3  */
 4 public class Order {
 5     private double orderTotal;
 6 
 7     private List<OrderItem> orderItems = new ArrayList<>();
 8 
 9     /**
10      * 获取订单列表
11      *
12      * @return 订单列表
13      */
14     public List<OrderItem> getOrderItems() {
15         return orderItems;
16     }
17 
18     /**
19      * 添加订单
20      *
21      * @param orderItem 订单
22      */
23     public void addOrderItem(OrderItem orderItem) {
24         if (orderItem == null) {
25             return;
26         }
27         orderItems.add(orderItem);
28         orderTotal += orderItem.getPrice();
29     }
30 
31     /**
32      * 删除订单
33      *
34      * @param orderItem 订单
35      */
36     public void removeOrderItem(OrderItem orderItem) {
37         if (orderItem == null) {
38             return;
39         }
40         if (orderItems.contains(orderItem)) {
41             orderItems.remove(orderItem);
42             orderTotal -= orderItem.getPrice();
43         }
44     }
45 
46     /**
47      * 获取订单总额
48      *
49      * @return 订单总额
50      */
51     public double getOrderTotal() {
52         return orderTotal;
53     }
54 }
 1 /**
 2  * 订单
 3  */
 4 public class OrderItem {
 5     private double price;
 6 
 7     public OrderItem(double price) {
 8         this.price = price;
 9     }
10 
11     /**
12      * 获取订单价格
13      *
14      * @return 价格
15      */
16     public double getPrice() {
17         return price;
18     }
19 }
 1 public class Test {
 2     public static void main(String[] args) {
 3         Order order = new Order();
 4         order.addOrderItem(new OrderItem(50));
 5         order.addOrderItem(new OrderItem(100));
 6         List<OrderItem> orderItems = order.getOrderItems();
 7         // 调用了list自身的方法,而不是Order提供的添加订单方法,导致了最后总额出错
 8         orderItems.add(new OrderItem(40));
 9 
10         int index = 1;
11         for (OrderItem orderItem : orderItems) {
12             System.out.println("订单" + index + "价格: " + orderItem.getPrice());
13         }
14         System.out.println("订单总额:" + order.getOrderTotal());
15     }
16 }

测试结果:

1 订单1价格: 50.0
2 订单1价格: 100.0
3 订单1价格: 40.0
4 订单总额:150.0

最后一行总金额本应 输出190.00 ,但是却输出了150.00。这里就演示了类的使用者通过使用集合本身的add方法向集合中添加元素,而没有使用addOrderItem方法,最后导致了订单中总金额出现了错误。因此我们需要对此代码进行重构:让使用者只能遍历集合,而不能对集合进行任何的修改的操作。

重构方案:把Order类中的getOrderItems方法的返回值由原来的List<OrderItem>更改为Iterable<OrderItem>,Android Studio可使用ChangeMethodSignature进行重构。
下面贴出修改后的代码,没有改变的代码将不会被贴出。

 1 /**
 2  * 订单管理类
 3  */
 4 public class Order {
 5     // ...省略未修改的代码
 6 
 7     /**
 8      * 获取订单列表
 9      *
10      * @return 订单列表
11      */
12     public Iterable<OrderItem> getOrderItems() {
13         return orderItems;
14     }
15 }
 1 public class Test {
 2     public static void main(String[] args) {
 3         Order order = new Order();
 4         order.addOrderItem(new OrderItem(50));
 5         order.addOrderItem(new OrderItem(100));
 6         Iterable<OrderItem> orderItems = order.getOrderItems();
 7         // orderItems.add(new OrderItem(40)); 此行以及无法编译通过
 8         order.addOrderItem(new OrderItem(40));
 9 
10         int index = 1;
11         for (OrderItem orderItem : orderItems) {
12             System.out.println("订单" + index + "价格: " + orderItem.getPrice());
13         }
14         System.out.println("订单总额:" + order.getOrderTotal());
15     }
16 }

测试结果

1 订单1价格: 50.0
2 订单1价格: 100.0
3 订单1价格: 40.0
4 订单总额:190.0
posted @ 2020-12-27 14:50  ysyouaremyall  阅读(151)  评论(0编辑  收藏  举报