设计原则
设计原则是指在软件设计过程中应该遵循的一些指导性原则,它们可以帮助设计出更加灵活、可扩展和易于维护的软件系统。在面向对象设计中,有一些经典的设计原则被广泛应用,例如 SOLID 原则。它们可以帮助开发人员设计出高内聚、低耦合的软件系统,提高代码的可读性、可维护性和可扩展性。
以下是一些常见的设计原则:
-
单一职责原则 (Single Responsibility Principle, SRP):一个类应该只有一个引起变化的原因,即一个类应该只有一个职责。
-
开闭原则 (Open/Closed Principle, OCP):软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。可以通过抽象化来实现。
-
里氏替换原则 (Liskov Substitution Principle, LSP):子类应该能够替换掉父类并出现在父类能够出现的任何地方,而不引起任何错误或异常。
-
依赖倒置原则 (Dependency Inversion Principle, DIP):高层模块不应该依赖于低层模块,两者都应该依赖于抽象;抽象不应该依赖于细节,细节应该依赖于抽象。
-
接口隔离原则 (Interface Segregation Principle, ISP):一个类对另一个类的依赖应该建立在最小的接口上。
-
迪米特法则 (Law of Demeter, LoD):一个对象应该对其他对象有最少的了解。也称为最少知识原则。
-
合成复用原则 (Composite/Aggregate Reuse Principle, CRP):尽量使用对象组合,而不是继承来达到复用的目的。
-
最少知识原则 (Principle of Least Knowledge, PoLK):一个软件实体应当尽可能少地与其他实体发生相互作用。
设计模式
设计模式和设计原则之间有着密切的关系。设计原则是指导软件设计的基本原则,而设计模式则是根据这些设计原则总结出来的实际应用模板。
常见的设计模式有:
-
创建型模式(Creational Patterns):用于创建对象的模式,包括工厂模式、抽象工厂模式、单例模式、建造者模式和原型模式。
-
结构型模式(Structural Patterns):用于处理类或对象之间的组合关系的模式,包括适配器模式、装饰器模式、代理模式、组合模式、桥接模式、外观模式和享元模式。
-
行为型模式(Behavioral Patterns):用于处理类或对象之间的通信方式的模式,包括策略模式、模板方法模式、观察者模式、迭代器模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式和中介者模式。
Spring框架中使用的设计模式体现
单例模式(Singleton)
在 Spring 框架中,单例模式体现在 Bean 的创建和管理上。Spring 默认情况下,容器中的 Bean 是单例的,也就是说容器中只有一个实例。
以下是一个举例
public class MyBean {
private String message;
public MyBean(String message) {
this.message = message;
}
public void setMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public MyBean myBean() {
return new MyBean("Hello, Spring!");
}
}
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
MyBean bean1 = context.getBean(MyBean.class);
MyBean bean2 = context.getBean(MyBean.class);
System.out.println(bean1 == bean2); // 输出 true,说明是同一个实例
}
}
工厂模式(Factory)
工厂模式也体现在 Bean 的创建和管理上,主要通过工厂类来创建对象。
例如 BeanFactory容器与ApplicationContext容器
在上一个例子中,我们使用了ApplicationContext的getBean方法获取实例对象,就是一种工厂模式的体现
代理模式(Proxy)
在 Spring 中,代理模式被广泛应用于 AOP(面向切面编程)。AOP 将横切关注点(如日志记录、事务管理等)与应用程序的业务逻辑分离,这种分离通过代理模式实现。
Spring 使用两种类型的代理来实现 AOP:JDK 动态代理和 CGLIB 代理。
JDK 动态代理是基于接口的代理,它通过 java.lang.reflect.Proxy
类和 InvocationHandler
接口实现。当目标对象实现了接口时,Spring 将使用 JDK 动态代理来创建代理对象
CGLIB 代理是基于类的代理,它通过继承目标类并重写方法来实现。当目标对象没有实现接口时,Spring 将使用 CGLIB 代理来创建代理对象
模板模式(Template)
模板模式通常用于简化重复性操作,例如数据库操作、JDBC 访问、JPA 操作等。Spring 提供了一些模板类,如 JdbcTemplate 等,这些模板类封装了底层操作,提供了一种模板化的方式来执行常见的操作
以下是使用JdbcTemplate的举例
@Configuration
public class AppConfig {
@Bean
public DataSource dataSource() {
// 配置数据源
return new DriverManagerDataSource("jdbc:mysql://localhost:3306/test", "username", "password");
}
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
// 配置 JdbcTemplate
return new JdbcTemplate(dataSource);
}
}
public class UserRepository {
private JdbcTemplate jdbcTemplate;
@Autowired
public UserRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public List<User> findAllUsers() {
// 使用 JdbcTemplate 查询所有用户
return jdbcTemplate.query("SELECT * FROM users", (rs, rowNum) -> {
User user = new User();
user.setId(rs.getLong("id"));
user.setName(rs.getString("name"));
user.setEmail(rs.getString("email"));
return user;
});
}
}
模板模式的体现在于 JdbcTemplate
封装了执行数据库操作的逻辑,开发人员只需要关注自己的业务逻辑,而不必编写重复的数据库访问代码。