设计模式的六大原则是面向对象设计的基石,它们指导我们如何编写可维护、可扩展和灵活的代码。以下是六大原则的详细说明和示例:

1. 单一职责原则 (Single Responsibility Principle, SRP)

  • 定义:一个类应该只有一个引起它变化的原因,即一个类只负责一项职责。
  • 优点:降低类的复杂度,提高可读性和可维护性。
  • 示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 违反SRP的示例
class User {
public void login(String username, String password) {
// 登录逻辑
}

public void saveToDatabase(User user) {
// 数据库保存逻辑
}
}

// 符合SRP的示例
class User {
public void login(String username, String password) {
// 登录逻辑
}
}

class UserRepository {
public void saveToDatabase(User user) {
// 数据库保存逻辑
}
}

2. 开闭原则 (Open/Closed Principle, OCP)

  • 定义:软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。
  • 优点:提高代码的可扩展性,减少对现有代码的影响。
  • 示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 违反OCP的示例
class Discount {
public double calculateDiscount(String type) {
if (type.equals("VIP")) {
return 0.2;
} else if (type.equals("Regular")) {
return 0.1;
}
return 0;
}
}

// 符合OCP的示例
interface DiscountStrategy {
double calculateDiscount();
}

class VIPDiscount implements DiscountStrategy {
public double calculateDiscount() {
return 0.2;
}
}

class RegularDiscount implements DiscountStrategy {
public double calculateDiscount() {
return 0.1;
}
}

3. 里氏替换原则 (Liskov Substitution Principle, LSP)

  • 定义:子类必须能够替换其父类,并且替换后程序的行为不会发生变化。
  • 优点:确保继承关系的正确性,避免程序出现意外行为。
  • 示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 违反LSP的示例
class Bird {
public void fly() {
System.out.println("Flying");
}
}

class Ostrich extends Bird {
public void fly() {
throw new UnsupportedOperationException("Ostrich can't fly");
}
}

// 符合LSP的示例
class Bird {
}

class FlyingBird extends Bird {
public void fly() {
System.out.println("Flying");
}
}

class Ostrich extends Bird {
// 鸵鸟不会飞,但不重写fly方法
}

4. 接口隔离原则 (Interface Segregation Principle, ISP)

  • 定义:客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小的接口上。
  • 优点:减少接口的臃肿,提高系统的灵活性。
  • 示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 违反ISP的示例
interface Animal {
void eat();
void fly();
void swim();
}

class Bird implements Animal {
public void eat() { /* 实现 */ }
public void fly() { /* 实现 */ }
public void swim() { /* 无意义 */ }
}

// 符合ISP的示例
interface Eatable {
void eat();
}

interface Flyable {
void fly();
}

interface Swimmable {
void swim();
}

class Bird implements Eatable, Flyable {
public void eat() { /* 实现 */ }
public void fly() { /* 实现 */ }
}

5. 依赖倒置原则 (Dependency Inversion Principle, DIP)

  • 定义:高层模块不应该依赖低层模块,二者都应该依赖抽象;抽象不应该依赖细节,细节应该依赖抽象。
  • 优点:降低模块间的耦合度,提高系统的可维护性。
  • 示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// 违反DIP的示例
class EmailService {
public void sendEmail(String message) {
// 发送邮件逻辑
}
}

class Notification {
private EmailService emailService = new EmailService();
public void sendNotification(String message) {
emailService.sendEmail(message);
}
}

// 符合DIP的示例
interface MessageService {
void sendMessage(String message);
}

class EmailService implements MessageService {
public void sendMessage(String message) {
// 发送邮件逻辑
}
}

class Notification {
private MessageService messageService;
public Notification(MessageService messageService) {
this.messageService = messageService;
}
public void sendNotification(String message) {
messageService.sendMessage(message);
}
}

6. 迪米特法则 (Law of Demeter, LoD)

  • 定义:一个对象应该对其他对象有最少的了解,即只与直接的朋友通信。
  • 优点:降低类之间的耦合度,提高模块的独立性。
  • 示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 违反LoD的示例
class Employee {
private Address address;
public Address getAddress() {
return address;
}
}

class Company {
public void printEmployeeAddress(Employee employee) {
System.out.println(employee.getAddress().getCity()); // 直接访问Address的细节
}
}

// 符合LoD的示例
class Employee {
private Address address;
public String getCity() {
return address.getCity();
}
}

class Company {
public void printEmployeeAddress(Employee employee) {
System.out.println(employee.getCity()); // 只与Employee交互
}
}
原则名称 核心思想 优点
单一职责原则 (SRP) 一个类只负责一项职责 降低复杂度,提高可维护性
开闭原则 (OCP) 对扩展开放,对修改关闭 提高可扩展性
里氏替换原则 (LSP) 子类可以替换父类,且行为不变 确保继承关系的正确性
接口隔离原则 (ISP) 客户端不应该依赖它不需要的接口 减少接口臃肿,提高灵活性
依赖倒置原则 (DIP) 高层模块和低层模块都依赖抽象 降低耦合度,提高可维护性
迪米特法则 (LoD) 一个对象只与直接的朋友通信 降低类间耦合度,提高模块独立性

总结

通过遵循这些原则,可以设计出高内聚、低耦合的系统,从而提高代码的质量和可维护性。