31天学习重构(java)---1.封装集合

本文探讨了在Java中封装集合的重要性,以确保类的使用者无法直接修改集合内容,从而避免预期行为的破坏。通过一个订单系统的例子展示了未封装集合导致的问题,重构方案是将`getOrderItems`方法的返回类型从`List<OrderItem>`改为`Iterator<OrderItem>`,以限制对集合的增删操作。

31天学习重构(java)---1.封装集合

点击进入->31天学习重构(java)目录


本例子介绍了集合的封装方法,当某些类需要向类的使用者提供类中的集合时,而且该集合的addXXXXX方法是经过了一些特别处理的时候,如果这时类的使用者通过get方法获得集合的时候,再使用集合本身的add方法的时候,就会绕过类的addXXXXX方法,就不能达到预期的目的。本节将介绍一种方法:既能让类的使用者使用集合,又能防止使用者向集合中添加数据、删除数据等修改操作
下面举个例子:一个订单的例子

public class Order {//订单类
	private double orderTotal;//订单总金额
	private List<OrderItem>  orderItems;//订单的所有订单项
	public Order(){
		orderTotal = 0 ;
		orderItems = new ArrayList<OrderItem>();
	}
	
	public double getOrderTotal() {//获取总金额
		return orderTotal;
	}
	public List<OrderItem> getOrderItems() {//获取订单项列表
		return orderItems;
	}
	
	public void addOrderItem(OrderItem orderItem ){//添加新的订单项
		orderItems.add(orderItem);
		orderTotal += orderItem.getPrice() ;
	}
	
}

public class OrderItem {//订单项类
	private double price;//订单项的价格
	//...一个简单的订单项类,就不添加其他的细节了

	public OrderItem(  double price){
		this.price = price ;//初始化价格
	}
	public double getPrice() {//获取价格
		return price;
	}
	public void setPrice(double price) {//设置价格
		this.price = price;
	}
	
	
}

public static void main(String[] args) {
		Order order = new Order();
		List<OrderItem> orderItems = order.getOrderItems();
		order.addOrderItem(new OrderItem(50));
		order.addOrderItem(new OrderItem(100));
		orderItems.add(new OrderItem(40));
		
		for( int i = 0 ; i < orderItems.size() ; ++i ){
			System.out.println(
				String.format("第%d个商品的价格为:%.2f", 
						i + 1 ,orderItems.get(i).getPrice()));
		}
		System.out.println(String.format("总金额为:%.2f" , order.getOrderTotal()));
	}

输出:
第1个商品的价格为:50.00
第2个商品的价格为:100.00
第3个商品的价格为:40.00
总金额为:150.00

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

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


public class Order {//订单类
	//...省略没有修改的代码
	public Iterator<OrderItem> getOrderItems() {//获取订单项列表
		return orderItems.iterator();
	}
	
}

	public static void main(String[] args) {
		Order order = new Order();
		order.addOrderItem(new OrderItem(50));
		order.addOrderItem(new OrderItem(100));
		//orderItems.add(new OrderItem(40));此时这句代码已经无法通过编译
		order.addOrderItem(new OrderItem(40));
		Iterator<OrderItem> orderItems = order.getOrderItems();
		
		int i = 1 ;
		while( orderItems.hasNext() )
		{
			System.out.println(
					String.format("第%d个商品的价格为:%.2f", 
							i++ ,orderItems.next().getPrice()));
		}
		System.out.println(String.format("总金额为:%.2f" , order.getOrderTotal()));
	}
输出:
第1个商品的价格为:50.00
第2个商品的价格为:100.00
第3个商品的价格为:40.00
总金额为:190.00

输出的结果已经正常了。

总结:在不需要向类的使用者提供的方法,应该隐藏起来, 让类的使用者只显示能够操作的功能,不能操作的功能应该屏蔽起来


点击进入->31天学习重构(java)目录



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值