在封装类的过程中,会将类分为实体类和功能实现类。这样会将一个问题中需要用到的属性放到实体类中,需要实现的功能放到功能类中。
实体类主要是用来存放属性的,实例类中的方法主要是构造方法,获取设置属性的get、set方法,toString()方法这种获取属性和设置属性的方法。实体类在命名的时候一般会在类名之后加上实体类后缀(Entity、Model、Bean、Pojo、VO)
功能实现类里则是一些实现我们需要的功能的代码,比如对实体类中的属性进行统计、计算等功能。
在封装过程中的重点是找实体类,找实体类的简单规则是在分析问题的过程中寻找名词。
下面是我在练习类的封装时做的几个练习题
练习题一:图书馆管理
题目要求:描述一个图书馆
- 进书、借书卡管理
- 借书、还书
- 查询某书的借出记录
- 查询借书卡的借出记录
- 显示图书列表(按借出次数排序)
首先提取实体类,找问题中的名词——书、卡、记录,记录是很容易被漏掉的一个实体类
然后开始思考每个实体类中包括的属性:
- 书的实体类(BookModel):书的编号、书名、借阅次数
- 卡的实体类(CardModel):借阅卡的id、密码
- 记录的实体类(RecordModel):借阅卡的id、书的编号、是否归还
PS:在设置记录的实体类的时候,我还加了书名这个变量,在记录中加书名这个变量在这个题目中没有什么问题,其实已经有了唯一的标识——书的编号,完全可以在书的实体类对象中找到其对应的书名,没必要再在记录中设置这样一个变量了。另外如果需要更改书名这个操作,那么需要更改书的对象中的书名,还要更改记录中对应的书的名字。如果记录中只有书的编号,只需要修改书实体类的对象中的书名,记录中需要用到书名再去根据书的编号去查找就好了,在代码之后的修改、增加功能方面更容易。在实体类中尽量不要定义多余的变量,不然会增加修改代码的工作量
功能类
- 进书; 2. 借阅卡注册; 3. 借书; 4. 还书; 5. 查询记录; 6. 显示图书
练习题二:停车场管理
题目要求:
- 一个停车场,内有多个车位,可停入各种车辆
- 只有具备车牌并高度低于3米的车辆可停入
- 停入时开始计费,按每小时2元
- 查询全部停车位的状态
- 按车牌及停车位号取车,取车时收取停车费
- 查询统计全部的收费记录
实体类:车位、车、记录
PS:这个题车这个实体类不用也很容易实现,但是像这种原始数据(不是计算统计得来的数据)最好要存起来,以便以后增加功能时比较容易,比如增加一个车型不同收费价格不同的功能,如果你不保存车的数据,那么之前的数据因为没有保存车的数据,就没什么利用价值。
- 停车位:停车位序号、停车位状态
- 车:车牌、车高
- 记录:停车位序号、停放车牌号、停放时间、离开时间(车费)
功能类:
- 停车; 2. 取车、计算停车费; 3. 查询停车位状态; 4. 查询全部记录
训练题三:水果销售管理
- 有一个水果销售摊位,销售3种水果,重量和单价各不相同,实现多次的销售业务
- 销售时如果为顾客为女性销售金额打8折
- 显示当前各种水果的库存数
- 查询全部销售记录信息
- 加入其它水果品种
- 添加进货单
- 查询指定日期间隔的销售纯利润
- 每日17:00之后为5折特价
- 按销售数量排序显示前三名
- 显示当前各种水果的库存数,成本单价,单价,累计销售数量/金额,累计进货数量/金额
实体类:水果、进货记录、销售记录
- 水果:水果名、库存、售价、进价
PS:在这个问题中有个累计销售金额和累计进货金额的问题,这两个变量如果定义在水果类中会很好记录,但是不推荐写在水果实体类中,因为这就不是水果的共性,只是为了功能而增加的。 - 进货记录:水果名、进价、进货量
PS:这里像进货的花费之类的可计算的、可统计的数据不必添加到实体类中,实体类中存放那些用于计算、统计的原始数据。 - 销售记录:水果名、售价、销售量、销售时间、销售折扣
PS:这里折扣最好是要存起来的,折扣就是一个用于计算的原始数据,如果不存折扣,这样的数据不完整,只是一次性的,没有什么价值。
功能类:进货、销售、查询
思考:这里在实现的时候我将进货价格设置为每次进货价格是不变的,但是实际过程中并不能保证每次进货都是一样的价格,那要怎么实现呢?
方法1:每次进货的时候计算平均值,将平均值保存到进货价中
方法2:每次进货都当做新水果,这种情况下就不能用水果名区分了,而是应该引入唯一的id来标记水果。
推荐使用第二种方法,第一种方法有局限性,比如有水果坏了就没法算了