1. 面向对象编程的核心思想
面向对象编程(Object-Oriented Programming,简称OOP)是一种基于"对象"概念的编程范式。在Java中,一切皆对象,这与现实世界的思维方式高度吻合。想象一下,当你在描述一辆汽车时,你会自然地想到它的属性(颜色、品牌、型号)和行为(启动、加速、刹车)。OOP正是将这种思维方式映射到代码中。
1.1 类与对象的关系
类(Class)是对象的蓝图或模板,它定义了对象的结构和行为。而对象(Object)是类的具体实例。举个生活中的例子:
- 类:就像汽车的工程设计图纸
- 对象:按照图纸生产出来的具体汽车
在Java中定义一个简单的Person类:
java复制public class Person {
// 字段(属性)
String name;
int age;
// 方法(行为)
void introduce() {
System.out.println("你好,我叫" + name + ",今年" + age + "岁");
}
}
创建和使用这个类的实例:
java复制Person person1 = new Person();
person1.name = "张三";
person1.age = 25;
person1.introduce(); // 输出:你好,我叫张三,今年25岁
1.2 面向对象的三大特性
1.2.1 封装(Encapsulation)
封装是将数据和对数据的操作捆绑在一起,并对外隐藏实现细节。在Java中,我们通常:
- 将字段设为private
- 提供public的getter和setter方法
改进后的Person类:
java复制public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if(age >= 0) { // 添加验证逻辑
this.age = age;
}
}
}
提示:封装不是简单的"私有化字段+提供getter/setter",真正的封装应该根据业务需求决定暴露哪些操作,而不是简单地暴露所有字段。
1.2.2 继承(Inheritance)
继承允许我们基于现有类创建新类,实现代码复用。Java使用extends关键字实现继承:
java复制public class Student extends Person {
private String studentId;
public void study() {
System.out.println(getName() + "正在学习");
}
}
继承的特点:
- 子类拥有父类非private的属性和方法
- 子类可以添加自己的属性和方法
- Java只支持单继承(一个类只能有一个直接父类)
1.2.3 多态(Polymorphism)
多态指同一操作作用于不同对象,可以有不同的解释和执行结果。Java中主要通过以下方式实现多态:
- 方法重载(Overload):同一类中方法名相同但参数不同
- 方法重写(Override):子类重写父类方法
- 接口和抽象类
java复制// 方法重载示例
class Calculator {
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
}
// 方法重写示例
class Animal {
void makeSound() {
System.out.println("动物发出声音");
}
}
class Dog extends Animal {
@Override
void makeSound() {
System.out.println("汪汪汪");
}
}
2. 高级面向对象特性
2.1 抽象类与接口
2.1.1 抽象类(Abstract Class)
抽象类是不能被实例化的类,用于定义公共接口和部分实现:
java复制abstract class Shape {
abstract double area(); // 抽象方法
void printArea() { // 具体方法
System.out.println("面积是:" + area());
}
}
class Circle extends Shape {
double radius;
Circle(double r) {
radius = r;
}
@Override
double area() {
return Math.PI * radius * radius;
}
}
抽象类特点:
- 可以包含抽象方法和具体方法
- 子类必须实现所有抽象方法(除非子类也是抽象类)
- 可以有构造方法(虽然不能直接实例化)
2.1.2 接口(Interface)
接口是纯抽象的契约,Java 8之后接口可以有默认实现:
java复制interface Drawable {
void draw(); // 抽象方法
default void printInfo() { // 默认方法
System.out.println("这是一个可绘制对象");
}
}
class Rectangle implements Drawable {
@Override
public void draw() {
System.out.println("绘制矩形");
}
}
接口特点:
- Java 8前只能有抽象方法,现在可以有默认方法和静态方法
- 一个类可以实现多个接口
- 接口不能有实例字段(可以有静态常量)
- 接口没有构造方法
经验:当需要定义行为契约时用接口,当需要提供部分实现时用抽象类。随着Java发展,接口和抽象类的界限越来越模糊,设计时需要根据具体场景选择。
2.2 内部类
内部类是定义在另一个类内部的类,主要有四种类型:
2.2.1 成员内部类
java复制class Outer {
private int value = 10;
class Inner {
void printValue() {
System.out.println("外部类的value:" + value);
}
}
}
// 使用
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.printValue();
2.2.2 静态内部类
java复制class Outer {
static class StaticInner {
void printMessage() {
System.out.println("静态内部类");
}
}
}
// 使用
Outer.StaticInner inner = new Outer.StaticInner();
inner.printMessage();
2.2.3 方法局部内部类
java复制class Outer {
void method() {
class LocalInner {
void print() {
System.out.println("方法局部内部类");
}
}
LocalInner inner = new LocalInner();
inner.print();
}
}
2.2.4 匿名内部类
java复制interface Greeting {
void greet();
}
class Outer {
void method() {
Greeting greeting = new Greeting() {
@Override
public void greet() {
System.out.println("匿名内部类实现");
}
};
greeting.greet();
}
}
注意:内部类会持有外部类的引用(静态内部类除外),可能导致内存泄漏,在Android开发中尤其需要注意。
2.3 枚举类型
枚举是一种特殊的类,用于定义一组常量:
java复制enum Day {
MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
// 使用
Day today = Day.MONDAY;
if(today == Day.SATURDAY || today == Day.SUNDAY) {
System.out.println("周末愉快!");
}
枚举的高级用法:
java复制enum Operation {
ADD {
int apply(int a, int b) { return a + b; }
},
SUBTRACT {
int apply(int a, int b) { return a - b; }
};
abstract int apply(int a, int b);
}
// 使用
int result = Operation.ADD.apply(5, 3); // 8
枚举特点:
- 类型安全
- 可以有自己的方法和字段
- 可以实现接口
- 不能被继承(隐式final)
3. 面向对象设计原则
3.1 SOLID原则
3.1.1 单一职责原则(SRP)
一个类应该只有一个引起它变化的原因。换句话说,一个类应该只负责一项职责。
反例:
java复制class Employee {
void calculatePay() { /* 计算薪资 */ }
void saveToDatabase() { /* 保存到数据库 */ }
void generateReport() { /* 生成报表 */ }
}
正例:
java复制class Employee {
void calculatePay() { /* 计算薪资 */ }
}
class EmployeeRepository {
void save(Employee employee) { /* 保存到数据库 */ }
}
class ReportGenerator {
void generate(Employee employee) { /* 生成报表 */ }
}
3.1.2 开闭原则(OCP)
软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。
java复制interface Shape {
double area();
}
class Rectangle implements Shape {
double width, height;
// 实现area方法
}
class Circle implements Shape {
double radius;
// 实现area方法
}
class AreaCalculator {
double calculateTotalArea(List<Shape> shapes) {
double total = 0;
for(Shape shape : shapes) {
total += shape.area();
}
return total;
}
}
这样当需要添加新的形状时,只需实现Shape接口,而不需要修改AreaCalculator。
3.1.3 里氏替换原则(LSP)
子类型必须能够替换它们的基类型。也就是说,任何父类出现的地方,子类都可以出现。
反例:
java复制class Rectangle {
int width, height;
void setWidth(int w) { width = w; }
void setHeight(int h) { height = h; }
}
class Square extends Rectangle {
@Override
void setWidth(int w) {
super.setWidth(w);
super.setHeight(w);
}
@Override
void setHeight(int h) {
super.setWidth(h);
super.setHeight(h);
}
}
这里Square不能完全替代Rectangle,因为设置宽高行为不一致。
3.1.4 接口隔离原则(ISP)
客户端不应该被迫依赖它们不使用的接口。应该将臃肿的接口拆分为更小、更具体的接口。
反例:
java复制interface Worker {
void work();
void eat();
void sleep();
}
class HumanWorker implements Worker {
// 实现所有方法
}
class RobotWorker implements Worker {
void work() { /* 工作 */ }
void eat() { /* 不需要 */ }
void sleep() { /* 不需要 */ }
}
正例:
java复制interface Workable {
void work();
}
interface Eatable {
void eat();
}
interface Sleepable {
void sleep();
}
class HumanWorker implements Workable, Eatable, Sleepable {
// 实现所有方法
}
class RobotWorker implements Workable {
void work() { /* 只实现工作 */ }
}
3.1.5 依赖倒置原则(DIP)
高层模块不应该依赖低层模块,两者都应该依赖抽象。抽象不应该依赖细节,细节应该依赖抽象。
反例:
java复制class LightBulb {
void turnOn() { /* 开灯 */ }
void turnOff() { /* 关灯 */ }
}
class Switch {
private LightBulb bulb;
void operate() {
// 直接依赖具体实现
if(/* 条件 */) {
bulb.turnOn();
} else {
bulb.turnOff();
}
}
}
正例:
java复制interface Switchable {
void turnOn();
void turnOff();
}
class LightBulb implements Switchable {
// 实现接口方法
}
class Fan implements Switchable {
// 实现接口方法
}
class Switch {
private Switchable device;
void operate() {
// 依赖抽象
if(/* 条件 */) {
device.turnOn();
} else {
device.turnOff();
}
}
}
3.2 其他重要原则
3.2.1 组合优于继承
继承虽然强大,但容易导致类层次结构过于复杂。组合通常更灵活:
java复制// 使用继承
class Logger {
void log(String message) { /* 记录日志 */ }
}
class Service extends Logger {
void doWork() {
log("工作开始");
// 工作逻辑
log("工作结束");
}
}
// 使用组合
class Service {
private Logger logger;
void doWork() {
logger.log("工作开始");
// 工作逻辑
logger.log("工作结束");
}
}
组合的优势:
- 运行时可以动态改变行为
- 不会破坏封装
- 更易于测试
3.2.2 迪米特法则(Law of Demeter)
一个对象应该对其他对象有最少的了解。简单说就是"只与直接朋友通信"。
反例:
java复制class A {
B b;
void method() {
C c = b.getC(); // A通过B获取C
c.doSomething(); // 然后直接调用C的方法
}
}
正例:
java复制class A {
B b;
void method() {
b.doSomethingWithC(); // A只与B交互
}
}
class B {
C c;
void doSomethingWithC() {
c.doSomething();
}
}
4. 设计模式实践
设计模式是面向对象设计中常见问题的解决方案模板。以下是几个常用模式:
4.1 单例模式
确保一个类只有一个实例,并提供全局访问点。
java复制public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if(instance == null) {
synchronized(Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
关键点:
- 私有构造方法
- volatile保证可见性
- 双重检查锁定
- 防止反射和序列化破坏单例
4.2 工厂模式
定义一个创建对象的接口,但让子类决定实例化哪个类。
java复制interface Product {
void use();
}
class ConcreteProductA implements Product {
public void use() {
System.out.println("使用产品A");
}
}
class ConcreteProductB implements Product {
public void use() {
System.out.println("使用产品B");
}
}
interface Factory {
Product createProduct();
}
class FactoryA implements Factory {
public Product createProduct() {
return new ConcreteProductA();
}
}
class FactoryB implements Factory {
public Product createProduct() {
return new ConcreteProductB();
}
}
4.3 观察者模式
定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会得到通知。
java复制interface Observer {
void update(String message);
}
class ConcreteObserver implements Observer {
private String name;
ConcreteObserver(String name) {
this.name = name;
}
public void update(String message) {
System.out.println(name + " 收到消息: " + message);
}
}
interface Subject {
void registerObserver(Observer o);
void removeObserver(Observer o);
void notifyObservers();
}
class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
private String state;
public void setState(String state) {
this.state = state;
notifyObservers();
}
public void registerObserver(Observer o) {
observers.add(o);
}
public void removeObserver(Observer o) {
observers.remove(o);
}
public void notifyObservers() {
for(Observer o : observers) {
o.update(state);
}
}
}
4.4 策略模式
定义一系列算法,将每个算法封装起来,并使它们可以互相替换。
java复制interface SortingStrategy {
void sort(int[] data);
}
class BubbleSort implements SortingStrategy {
public void sort(int[] data) {
System.out.println("使用冒泡排序");
// 实现
}
}
class QuickSort implements SortingStrategy {
public void sort(int[] data) {
System.out.println("使用快速排序");
// 实现
}
}
class Sorter {
private SortingStrategy strategy;
Sorter(SortingStrategy strategy) {
this.strategy = strategy;
}
void setStrategy(SortingStrategy strategy) {
this.strategy = strategy;
}
void sort(int[] data) {
strategy.sort(data);
}
}
5. Java高级特性与面向对象
5.1 泛型
泛型提供了编译时类型安全检查,并消除了强制类型转换。
java复制class Box<T> {
private T content;
void setContent(T content) {
this.content = content;
}
T getContent() {
return content;
}
}
// 使用
Box<String> stringBox = new Box<>();
stringBox.setContent("Hello");
String value = stringBox.getContent(); // 不需要强制转换
泛型限制:
- 不能使用基本类型(如int,要用Integer)
- 不能创建泛型数组
- 不能实例化类型参数(new T()是不允许的)
5.2 反射
反射允许在运行时检查类、接口、字段和方法,并动态调用方法。
java复制Class<?> clazz = Class.forName("com.example.Person");
Object obj = clazz.newInstance();
// 获取方法并调用
Method method = clazz.getMethod("setName", String.class);
method.invoke(obj, "张三");
// 获取字段
Field field = clazz.getDeclaredField("age");
field.setAccessible(true); // 访问私有字段
field.set(obj, 25);
反射用途:
- 框架开发(如Spring)
- 动态代理
- 测试工具
- 序列化/反序列化
注意:反射会破坏封装性,性能较差,应该谨慎使用。
5.3 注解
注解为代码添加元数据,可以用于编译时检查或运行时处理。
定义注解:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Test {
String name() default "";
boolean enabled() default true;
}
使用注解:
java复制class TestCase {
@Test(name = "加法测试", enabled = true)
public void testAdd() {
// 测试代码
}
}
处理注解(通过反射):
java复制Method[] methods = TestCase.class.getMethods();
for(Method method : methods) {
if(method.isAnnotationPresent(Test.class)) {
Test test = method.getAnnotation(Test.class);
if(test.enabled()) {
method.invoke(new TestCase());
}
}
}
5.4 Lambda表达式与函数式编程
Java 8引入了Lambda表达式,支持函数式编程风格。
java复制// 传统方式
Collections.sort(list, new Comparator<String>() {
public int compare(String s1, String s2) {
return s1.compareTo(s2);
}
});
// Lambda方式
Collections.sort(list, (s1, s2) -> s1.compareTo(s2));
函数式接口:
java复制@FunctionalInterface
interface MyFunction {
int apply(int a, int b);
}
MyFunction add = (a, b) -> a + b;
int result = add.apply(3, 5); // 8
Stream API:
java复制List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
long count = names.stream()
.filter(name -> name.length() > 4)
.count(); // 1
5.5 模块系统(Java 9+)
Java 9引入了模块系统,提供了更好的封装和依赖管理。
模块定义(module-info.java):
java复制module com.example.myapp {
requires java.base;
requires java.sql;
exports com.example.myapp.api;
}
模块特点:
- 强封装:未导出的包对其他模块不可见
- 显式依赖:必须声明所有依赖
- 更小的运行时镜像
- 改进的安全性
6. 面向对象实践建议
6.1 设计良好的类
- 保持类小而专注:一个类应该只有一个职责
- 优先使用组合:除非有明显的"is-a"关系,否则使用组合而非继承
- 遵循Liskov替换原则:子类应该能够替换父类而不破坏程序
- 封装变化:将可能变化的部分封装起来
- 面向接口编程:依赖抽象而非具体实现
6.2 避免常见陷阱
- 过度设计:不是所有地方都需要设计模式,简单优于复杂
- 滥用继承:继承会带来强耦合,考虑是否真的需要"is-a"关系
- 忽略equals和hashCode:当对象可能被放入集合时,必须正确实现这两个方法
- 可变性设计:不可变对象通常更安全,考虑将类设计为不可变
- 忽略异常处理:合理处理异常,不要简单地捕获并忽略
6.3 测试驱动开发
测试驱动开发(TDD)可以促进更好的面向对象设计:
- 先写测试,再写实现
- 小步前进,频繁重构
- 测试驱动出更好的接口设计
- 确保代码可测试性
示例:
java复制// 测试
@Test
public void testAccountDeposit() {
Account account = new Account();
account.deposit(100);
assertEquals(100, account.getBalance());
}
// 实现
class Account {
private int balance;
public void deposit(int amount) {
if(amount > 0) {
balance += amount;
}
}
public int getBalance() {
return balance;
}
}
6.4 重构技巧
- 提取方法:将长方法分解为小方法
- 提取类:当一个类承担太多职责时,拆分它
- 用多态替代条件语句:特别是复杂的switch-case
- 引入参数对象:将多个参数组合为对象
- 用工厂方法替代构造器:当创建逻辑复杂时
示例重构:
java复制// 重构前
class Order {
double calculatePrice() {
double basePrice = quantity * itemPrice;
double discount;
if(basePrice > 1000) {
discount = 0.95;
} else {
discount = 0.98;
}
return basePrice * discount;
}
}
// 重构后
class Order {
double calculatePrice() {
return new PriceCalculator(this).calculate();
}
}
class PriceCalculator {
private Order order;
PriceCalculator(Order order) {
this.order = order;
}
double calculate() {
return basePrice() * discountFactor();
}
private double basePrice() {
return order.quantity * order.itemPrice;
}
private double discountFactor() {
return basePrice() > 1000 ? 0.95 : 0.98;
}
}
7. Java面向对象高级特性
7.1 记录类(Java 14+)
记录类(Record)是不可变数据的透明载体:
java复制record Point(int x, int y) {
// 编译器自动生成:
// - final字段x和y
// - 构造方法
// - equals()和hashCode()
// - toString()
}
// 使用
Point p = new Point(10, 20);
System.out.println(p.x()); // 10
System.out.println(p); // Point[x=10, y=20]
记录类特点:
- 不可变
- 自动实现equals、hashCode和toString
- 可以声明静态字段和方法
- 可以添加自定义方法
7.2 密封类(Java 15+)
密封类限制哪些类可以继承它:
java复制sealed interface Shape
permits Circle, Square, Rectangle {
double area();
}
final class Circle implements Shape {
double radius;
public double area() { return Math.PI * radius * radius; }
}
final class Square implements Shape {
double side;
public double area() { return side * side; }
}
final class Rectangle implements Shape {
double width, height;
public double area() { return width * height; }
}
密封类特点:
- 明确控制继承层次
- 增强代码可维护性
- 与模式匹配配合良好
7.3 模式匹配(Java 16+)
简化instanceof检查和类型转换:
java复制// 传统方式
if(obj instanceof String) {
String s = (String)obj;
System.out.println(s.length());
}
// 模式匹配方式
if(obj instanceof String s) {
System.out.println(s.length());
}
switch表达式中的模式匹配:
java复制return switch(shape) {
case Circle c -> "圆形,半径:" + c.radius();
case Square s -> "正方形,边长:" + s.side();
case Rectangle r -> "长方形,长:" + r.width() + ",宽:" + r.height();
default -> "未知形状";
};
7.4 虚拟线程(Java 19+)
轻量级线程,适合高并发场景:
java复制try(var executor = Executors.newVirtualThreadPerTaskExecutor()) {
for(int i = 0; i < 10_000; i++) {
executor.submit(() -> {
Thread.sleep(Duration.ofSeconds(1));
return i;
});
}
}
虚拟线程特点:
- 由JVM管理,非操作系统线程
- 创建成本极低
- 适合I/O密集型任务
- 与传统线程API兼容
8. 面向对象在Java生态中的应用
8.1 Java集合框架
集合框架是面向对象设计的典范:
java复制// 多态使用集合
List<String> list = new ArrayList<>(); // 或LinkedList
list.add("Java");
list.add("Python");
// 使用迭代器(迭代器模式)
Iterator<String> it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
// 函数式操作
list.stream()
.filter(s -> s.startsWith("J"))
.forEach(System.out::println);
8.2 Java I/O系统
I/O系统展示了装饰器模式:
java复制// 装饰器模式层层包装
try(InputStream is = new FileInputStream("data.txt");
InputStream bis = new BufferedInputStream(is);
DataInputStream dis = new DataInputStream(bis)) {
// 读取数据
}
8.3 Spring框架
Spring核心是控制反转(IoC)和面向接口编程:
java复制// 定义接口
public interface UserService {
User findUserById(long id);
}
// 实现类
@Service
public class UserServiceImpl implements UserService {
@Override
public User findUserById(long id) {
// 实现
}
}
// 使用处(依赖注入)
@Controller
public class UserController {
@Autowired
private UserService userService;
// 使用userService
}
8.4 Hibernate ORM
Hibernate展示了对象-关系映射:
java复制@Entity
@Table(name = "employees")
public class Employee {
@Id
@GeneratedValue
private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "department_id")
private Department department;
// getters和setters
}
// 使用
Employee emp = session.get(Employee.class, 1L);
System.out.println(emp.getName() + " 属于 " + emp.getDepartment().getName());
9. 性能考量与最佳实践
9.1 对象创建与回收
-
避免不必要的对象创建:
java复制// 不好 - 每次循环都创建新对象 for(int i = 0; i < 1000; i++) { String s = new String("hello"); } // 好 - 重用对象 String s = "hello"; for(int i = 0; i < 1000; i++) { // 使用s } -
注意自动装箱:
java复制// 不好 - 大量Integer对象被创建 Integer sum = 0; for(int i = 0; i < 1000; i++) { sum += i; // 自动装箱 } -
使用对象池:对于创建成本高的对象(如数据库连接)
9.2 内存泄漏预防
常见内存泄漏场景:
-
静态集合:
java复制static List<Object> list = new ArrayList<>(); void addData(Object data) { list.add(data); // 除非显式移除,否则data永远不会被GC } -
监听器和回调:
java复制class MyButton { private List<ClickListener> listeners = new ArrayList<>(); void addListener(ClickListener listener) { listeners.add(listener); } // 经常忘记提供removeListener方法 } -
内部类引用外部类:
java复制class Outer { byte[] data = new byte[1024*1024]; // 1MB class Inner { void doSomething() { System.out.println(data.length); // 持有Outer的引用 } } Inner getInner() { return new Inner(); } } // 使用 Outer outer = new Outer(); Outer.Inner inner = outer.getInner(); outer = null; // outer不会被GC,因为inner持有引用
9.3 多线程注意事项
-
不可变对象:最简单的线程安全方案
java复制public final class ImmutablePoint { private final int x; private final int y; public ImmutablePoint(int x, int y) { this.x = x; this.y = y; } // 只有getter,没有setter } -
线程封闭:将对象限制在单个线程中使用
java复制public class ThreadLocalExample { private static ThreadLocal<SimpleDateFormat> dateFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd")); public String formatDate(Date date) { return dateFormat.get().format(date); } } -
安全发布:正确共享对象
java复制// 不安全发布 public class UnsafeHolder { public Holder holder; public void initialize() { holder = new Holder(42); } } // 安全发布方式1 - final字段 public class SafeHolder { public final Holder holder; public SafeHolder() { holder = new Holder(42); } } // 安全发布方式2 - volatile字段 public class SafeHolder { public volatile Holder holder; public void initialize() { holder = new Holder(42); } }
10. 现代Java开发中的面向对象
10.1 响应式编程
响应式流(Reactive Streams)规范:
java复制Flux<Integer> flux = Flux.range(1, 10)
.map(i -> i * 2)
.filter(i -> i > 5)
.subscribeOn(Schedulers.parallel())
.subscribe(
System.out::println,
error -> System.err.println("错误: " + error),
() -> System.out.println("完成")
);
面向对象在响应式编程中的应用:
- 观察者模式的扩展
- 流式API设计
- 背压处理
10.2 微服务架构
微服务中的面向对象设计:
-
领域驱动设计(DDD):
- 实体(Entity)
- 值对象(Value Object)
- 聚合根(Aggregate Root)
- 领域服务(Domain Service)
-
服务设计原则:
- 单一职责
- 明确边界
- 自治性
10.3 云原生Java
云原生应用中的面向对象考量:
- 不可变基础设施:强调不可变对象
- 函数即服务(FaaS):小型的、单一职责的函数
- 容器化:自包含的部署单元
java复制// 云函数示例
public class CloudFunction implements HttpFunction {
@Override
public void service(HttpRequest request, HttpResponse response) {
String name = request.getQueryParameters().get("name").stream().findFirst().orElse("world");
response.getWriter().write("Hello " + name + "!");
}
}
10.4 记录最佳实践
-
保持记录简单:主要用于数据传输
-
与旧代码兼容:
java复制record Point(int x, int y) { // 添加兼容构造方法 Point { if(x < 0 || y < 0) { throw new IllegalArgumentException("坐标不能为负"); } } // 添加兼容方法 public double distanceTo(Point other) { return Math.hypot(x - other.x, y - other.y); } } -
不要滥用:不是所有类都应该改为记录
11. 面向对象设计案例分析
11.1 电商系统设计
核心领域模型:
java复制// 聚合根
public class Order {
private OrderId id;
private CustomerId customerId;
private List<OrderItem> items;
private OrderStatus status;
public void addItem(ProductId productId, int quantity) {
// 业务逻辑
}
public void submit() {
// 验证并转换状态
}
}
// 值对象
public record OrderItem(ProductId productId, int quantity, Money price) {
public Money subtotal() {
return price.multiply(quantity);
}
}
// 领域服务
public class OrderService {
private final OrderRepository repository;
private final InventoryService inventory;
public void placeOrder(Order order) {
if(inventory.checkStock(order.getItems())) {
order.submit();
repository.save(order);
inventory.adjustStock(order.getItems());
}
}
}
11.2 游戏开发设计
游戏对象模型:
java复制// 组件基类
interface Component {
void update(GameObject gameObject, float deltaTime);
}
// 具体组件
class Transform implements Component {
Vector2 position;
float rotation;
public void update(GameObject gameObject, float deltaTime) {
// 更新位置
}
}
class SpriteRenderer implements Component {
Texture texture;
public void update(GameObject gameObject, float deltaTime) {
// 渲染精灵
}
}
// 游戏对象
class GameObject {
private Map<Class<?>, Component> components = new HashMap<>();
public <T extends Component> T getComponent(Class<T> type) {
return type.cast(components.get(type));
}
public void addComponent(Component component) {
components.put(component.getClass(), component);
}
public void update(float deltaTime) {
components.values().forEach(c -> c.update(this, deltaTime));
}
}
// 使用
GameObject player = new GameObject();
player.addComponent(new Transform());
player.addComponent(new SpriteRenderer());
11.3 金融系统设计
账户交易模型:
java复制public interface Account {
void deposit(BigDecimal amount);
void withdraw(BigDecimal amount) throws InsufficientFundsException;
BigDecimal getBalance();
}
public class SavingsAccount implements Account {
private BigDecimal balance;
private BigDecimal interestRate;
public void applyInterest() {
balance = balance.multiply(BigDecimal.ONE.add(interestRate));
}
// 实现接口方法
}
public class CheckingAccount implements Account {
private BigDecimal balance;
private BigDecimal overdraftLimit;
// 实现接口方法
}
// 交易处理器
public class TransactionProcessor {
public void transfer(Account from, Account to, BigDecimal amount) {
try {
from.withdraw(amount);
to.deposit(amount);
