Lab3-实现计划项app辅助类实现

面向复用的设计:R

这个任务中我们需要实现不同的资源类型。由于不同的资源之间类型差异比较大,因此我们面向不同的类单独设计资源即可。
航班应用中的资源是“飞机”,属性包括飞机编号、机型号(A350、B787、C919 等)、座位数、机龄(例如 2.5 年)。因此这个类需要有4个属性,它们的表示不变性为:

private final String flightNum;
	private final String modelNum;
	private final int seatNum;
	private final float year;
	
	// Abstraction function:
	//   以飞机编号、型号、座位数、机龄来映射一个飞机
	// Representation invariant:
	//   
	// Safety from rep exposure:
	//   所有属性都定义成private和final保护属性引用不变
	//   对于返回可变类型的对象,使用防御式拷贝的方式进行保护,避免表示泄露

同时在这个类中我们还重写了equals函数用来判断资源的相同,它的具体描述为:

	@Override
	public boolean equals(Object obj) {
		if(this == obj) {
			return true;
		}
		if(obj instanceof FlightR) {
			FlightR a = (FlightR) obj;
			if(a.getFlightNum().equals(this.getFlightNum())) {
				if(a.getModelNum().equals(this.getModelNum())) {
					if(a.getSeatNum() == this.getSeatNum()){
						if(Math.abs(a.getYear() - this.getYear()) < 0.001) {
							return true;
						}
					}
				}
			}
		}
		return false;
	}

同时还为飞机资源提供了几个get方法以及重写了toString方法。
高铁应用中的资源是“车厢”,属性包括车厢唯一编号、类型(商务、一等、二等、软卧、硬卧、硬座、行李车、餐车)、定员数(例如100人)、出厂年份。为了实现这个资源类,我们同样设置了4个属性,它们的表示不变性为:

	private final int carNum;
	private final String type;
	private final int personNum;
	private final int year;
	
	// Abstraction function:
	//   以火车车厢编号、类型、容量、生产年份来映射一个火车车厢
	// Representation invariant:
	//   
	// Safety from rep exposure:
	//   所有属性都定义成private和final保护属性引用不变
	//   对于返回可变类型的对象,使用防御式拷贝的方式进行保护,避免表示泄露

和前面的描述一致,我们同样重写了equals方法,这个类中同时也设置了get方法以及重写了toString方法用于辅助执行功能。
课表应用中的资源为“教师”,属性包括身份证号、姓名、性别、职称。因此我们设计了4个属性,它们的表示不变性如下:

	private final String idNum;
	private final String name;
	private final String gender;
	private final String title;
	
	// Abstraction function:
	//   以教师编号、名字、性别、职称来映射一个教师
	// Representation invariant:
	//   
	// Safety from rep exposure:
	//   所有属性都定义成private和final保护属性引用不变
	//   对于返回可变类型的对象,使用防御式拷贝的方式进行保护,避免表示泄露

这个类中的重写equals方法与前面提到的类似,因此不做重复。同样,为了更好完成后续功能,我们也设计了get方法以及重写了toString方法。
在这个类中,为了辅助后面实验的书写,我们还设置了多个资源类和单个资源类,这样的设计能够极大提高程序复用性。此处我们以单个资源设计,涉及到泛型的设计举例,如下:

    private R sre;
	
	// Abstraction function:
	//   保存单个资源来展示资源情况
	// Representation invariant:
	//   
	// Safety from rep exposure:
	//   所有属性都定义成private和final保护属性引用不变
	//   对于返回可变类型的对象,使用防御式拷贝的方式进行保护,避免表示泄露
    
	/**
	 * 得到资源信息
	 * @return 返回单个资源
	 */
	public R getResource(){
		return this.sre;
	}
	
	/**
	 * 增加资源
	 * @param resource 输入资源
	 * @return 返回true
	 */
	public boolean addResource(R resource) {
		this.sre = resource;
		return true;
	}

面向复用的设计:Location

这个任务需要完成位置类的设计。一个“位置”对象的属性包括:经度、纬度、名称、是否可共享使用。因此和前面提到的设计思路一致,我们需要设置4个属性,它们的表示不变性如下:

	private final float longitude;
	private final float latitude;
	private final String name;
	private final int share;
	
	// Abstraction function:
	//   以经度、纬度、名称、是否可共享来表示一个位置
	// Representation invariant:
	//   share只能是0或者1
	// Safety from rep exposure:
	//   所有属性都定义成private和final保护属性引用不变
	//   对于返回可变类型的对象,使用防御式拷贝的方式进行保护,避免表示泄露

这个类中因为设计过程中根据地址的名称来对地址进行判断,所以需要提供得到地址信息方法,具体如下:

	/**
	 * 得到位置信息
	 * @return 返回位置名称
	 */
	public String getLoc() {
		return this.name;
	}

同样这个类也重写了toString方法用来返回位置信息。
位置类和资源类一样,为了辅助后续功能的实现,我们必须设置接口和具体实现,方便方案5的设计,即利用委托机制,这部分内容在后面会详细描述。这里我们以两个位置为例进行描述:

	private Location start;
	private Location end;
	
	// Abstraction function:
	//   以start、end保存位置信息
	// Representation invariant:
	//   
	// Safety from rep exposure:
	//   所有属性都定义成private防止属性直接泄露
	//   对于返回可变类型的对象,使用防御式拷贝的方式进行保护,避免表示泄露
	
	@Override
	public boolean setLocations(Location start,Location end) {
		this.start = start;
		this.end = end;
		return true;
	}
	
	@Override
	public Location getStart() {
		return this.start;
	}
	
	@Override
	public Location getEnd() {
		return this.end;
	}

面向复用的设计:Timeslot

这个任务主要是为了实现构建一个时间对。一个单独的“起止时间对”设计Timeslot类,它是一个带有起始时间和结束时间的ADT,应包含日期(年/月/日)和时间(时/分),符合yyyy-MM-dd HH:mm的语法规则。
因此这个类设计过程中需要将输入的字符串转化为时间进行存储。具体还需要满足格式的需求。具体的属性和表示不变性如下:

	private final Calendar start = Calendar.getInstance();
	private final Calendar end = Calendar.getInstance();
	
	SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
	
	// Abstraction function:
	//   以两个时间点来表示一个时间对
	//   其中start是开始时间,end是结束时间
	// Representation invariant:
	//   start和end是Calendar的实例,同时限制了格式
	//   start的时间小于end的时间
	// Safety from rep exposure:
	//   所有属性都定义成private和final保护属性引用不变
	//   对于返回可变类型的对象,使用防御式拷贝的方式进行保护,避免表示泄露

为了展示具体的转化过程,这里提供构造函数进行分析:

	/**
	 * 构造函数,输入两个字符串,转化为一个时间对
	 * @param start 开始时间的字符串表示
	 * @param end 结束时间的字符串表示
	 * @throws ParseException 解析格式不符合抛出异常
	 */
	public Timeslot(String start,String end) throws ParseException {
		
		this.start.setTime((Date) format.parse(start));

		this.end.setTime((Date) format.parse(end));
		
		checkRep();

	}

同样这个类也需要get方法和toString方法对信息进行展示。
这个类在设计完成之后还需要配合位置类进行设计。因为设计过程中我们在火车计划项输入的时间数和位置项一样的,而飞机和课程时间数都是一个时间对,因此我们需要设计一个单个时间对类和多个时间对类。此处我们以多个时间对为例:

	private List<Timeslot> times = new ArrayList<>();
	
	// Abstraction function:
	//   表示资源有多个时间对
	// Representation invariant:
	//   时间对的列表不能为空
	// Safety from rep exposure:
	//   所有属性都定义成private保护属性不直接对外泄露
	//   对于返回可变类型的对象,使用防御式拷贝的方式进行保护,避免表示泄露
	
	@Override
	public boolean setTime(List<Timeslot> times) {
		this.times = times;	//指向同一个引用
		return true;
		
//		this.times.addAll(times);	//复制所有的值
	}
	
	/**
	 * 得到多个时间对列表
	 * @return 返回时间对的列表
	 */
	public List<Timeslot> getTime(){
		return this.times; 
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值