第10章 面向对象实现
识记
① 面向对象语言的优点及选择原则
优点:
- 封装性:隐藏实现细节,提高代码安全性和可维护性。
- 继承性:支持代码复用和层次化设计(如子类继承父类属性和方法)。
- 多态性:同一操作对不同对象产生不同行为(如
draw()
方法在“圆形”和“矩形”类中的不同实现)。 - 模块化:类与对象的划分使系统结构更清晰。
选择原则:
• 项目需求:实时系统选C++,Web应用选Java或Python。
• 团队熟悉度:优先选择团队擅长的语言。
• 生态支持:丰富的库和框架(如Java的Spring,Python的Django)。
• 性能要求:高性能场景选编译型语言(如C++),快速开发选解释型语言(如Python)。
领会
① 面向对象程序设计风格
• 命名规范:类名使用大驼峰(如OrderManager
),方法名使用小驼峰(如calculateTotal()
)。
• 封装原则:属性私有化(private
),通过公共方法(getter/setter
)访问。
• 继承使用:避免过度继承,优先使用组合(如将工具类作为成员变量而非继承)。
• 多态应用:通过接口(interface
)或抽象类(abstract class
)定义通用行为。
• 异常处理:自定义异常类(如InvalidInputException
)并规范捕获逻辑。
② 面向对象测试模型及面向对象各阶段的测试方法
测试模型:
• 单元测试:针对单个类或方法(如JUnit测试UserService.login()
)。
• 集成测试:验证类间交互(如订单模块调用支付接口)。
• 系统测试:整体验证功能和非功能需求(如并发性能测试)。
各阶段测试方法:
• 类内测试:覆盖所有方法分支(如if-else
逻辑)。
• 类间测试:模拟依赖(如使用Mock对象替代数据库调用)。
• 继承测试:验证子类是否满足Liskov替换原则(如父类方法在子类中的正确覆盖)。
③ 类内测试及类间测试用例的设计
类内测试用例设计:
• 等价类划分:输入有效/无效数据(如用户年龄为负数、0、1、120、121)。
• 路径覆盖:覆盖所有代码分支(如if
和switch
的所有条件)。
类间测试用例设计:
• 交互测试:验证消息传递是否正确(如订单创建后是否触发库存扣减)。
• 依赖模拟:使用Mock工具(如Mockito)模拟外部服务(如支付接口返回超时异常)。
应用
① 设计测试用例(类内测试示例)
场景:测试Calculator
类的add(int a, int b)
方法。
测试用例:
@Test
public void testAdd() {
Calculator calc = new Calculator();
assertEquals(5, calc.add(2, 3)); // 正数相加
assertEquals(-1, calc.add(2, -3)); // 正负相加
assertEquals(0, calc.add(0, 0)); // 边界值
}
② 设计测试用例(类间测试示例)
场景:测试OrderService
与PaymentService
的交互。
测试用例:
@Test
public void testOrderPayment() {
// 模拟PaymentService返回支付成功
PaymentService mockPayment = Mockito.mock(PaymentService.class);
Mockito.when(mockPayment.process(anyDouble())).thenReturn(true);
OrderService orderService = new OrderService(mockPayment);
boolean result = orderService.createOrder(100.0);
assertTrue(result);
// 验证是否调用了process方法
Mockito.verify(mockPayment).process(100.0);
}
③ 设计测试用例(继承与多态测试示例)
场景:测试Shape
类的子类Circle
和Rectangle
的area()
方法。
测试用例:
@Test
public void testCircleArea() {
Shape circle = new Circle(5.0);
assertEquals(78.54, circle.area(), 0.01); // 允许0.01的误差
}
@Test
public void testRectangleArea() {
Shape rectangle = new Rectangle(4.0, 6.0);
assertEquals(24.0, rectangle.area(), 0.0);
}