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