Article
单一职责原则:独孤九剑的每一式只破一种兵器
· 6 分钟阅读
单一职责就像令狐冲所学的独孤九剑。独孤九剑讲究一招一式皆有其特定的目标和用途,或破剑、或破刀、或破枪等,每一式都专注于应对一种兵器的攻击。单一职责原则也是如此,一个类只负责一项职责,如同独孤九剑的每一式都专注于破解一类兵器。

一个类只该有一个变更理由
单一职责原则强调:一个类应该只有一个引起它变化的原因。即,一个类只负责一个职责。
示例:员工管理与报酬管理分离
拆开之后
class Employee {
private name: string;
constructor(name: string) {
this.name = name;
}
getName(): string {
return this.name;
}
}
// 职责1:员工管理
class EmployeeManager {
private employees: Employee[] = [];
addEmployee(employee: Employee): void {
this.employees.push(employee);
}
getEmployees(): Employee[] {
return this.employees;
}
}
// 职责2:员工报酬管理
class EmployeePayroll {
calculatePay(employee: Employee): number {
// 计算员工报酬逻辑
return 1000; // 示例
}
}
// 使用示例
const emp1 = new Employee("Alice");
const empManager = new EmployeeManager();
empManager.addEmployee(emp1);
const payroll = new EmployeePayroll();
console.log(`Pay for ${emp1.getName()}: ${payroll.calculatePay(emp1)}`); // Pay for Alice: 1000
类图

Employee类负责处理员工的基本信息。EmployeeManager类负责管理员工,如添加员工、获取员工信息等。EmployeePayroll类负责计算员工的报酬。
体现单一职责原则的设计模式
- 策略模式(Strategy Pattern):通过将算法封装到具体的策略类中,使每个策略类只负责一种特定的算法逻辑,遵循单一职责原则。
- 装饰器模式(Decorator Pattern):通过将额外的职责封装到装饰器类中,使得每个装饰器类只负责一种特定的职责,符合单一职责原则。
- 观察者模式(Observer Pattern):通过将通知逻辑封装到观察者类中,使得每个观察者类只负责处理特定的通知事件,体现了单一职责原则。
- 命令模式(Command Pattern):通过将请求封装到具体的命令类中,使得每个命令类只负责一个特定的请求,符合单一职责原则。
前端里的四个高发场景
表单验证
在前端开发中,表单验证是一个常见的需求。可以将不同的验证逻辑封装到不同的类中,使得每个类只负责一种验证方式,如邮箱验证、手机号验证、密码强度验证等。 示例:
class EmailValidator {
validate(email: string): boolean {
const regex = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/
return regex.test(email)
}
}
class PhoneValidator {
validate(phone: string): boolean {
const regex = /^\d{10}$/
return regex.test(phone)
}
}
class PasswordValidator {
validate(password: string): boolean {
return password.length >= 8
}
}
// 使用示例
const emailValidator = new EmailValidator()
console.log(emailValidator.validate('[email protected]')) // true
const phoneValidator = new PhoneValidator()
console.log(phoneValidator.validate('1234567890')) // true
const passwordValidator = new PasswordValidator()
console.log(passwordValidator.validate('strongpass')) // true
动画处理
动画处理在前端开发中非常常见,可以将不同的动画效果封装到不同的类中,使得每个类只负责一种动画效果,如淡入淡出动画、滑动动画等。 示例:
class FadeInAnimation {
animate(element: HTMLElement): void {
element.style.transition = 'opacity 1s'
element.style.opacity = '1'
}
}
class SlideInAnimation {
animate(element: HTMLElement): void {
element.style.transition = 'transform 1s'
element.style.transform = 'translateX(0)'
}
}
// 使用示例
const element = document.getElementById('myElement')
const fadeInAnimation = new FadeInAnimation()
fadeInAnimation.animate(element) // 应用淡入动画
const slideInAnimation = new SlideInAnimation()
slideInAnimation.animate(element) // 应用滑动动画
数据请求处理
在前端开发中,数据请求处理也是一个常见的应用场景。可以将不同的请求逻辑封装到不同的类中,使得每个类只负责一种请求方式,如 GET 请求、POST 请求等。 示例:
class GetRequest {
send(url: string): Promise<Response> {
return fetch(url)
}
}
class PostRequest {
send(url: string, data: any): Promise<Response> {
return fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
}
}
// 使用示例
const getRequest = new GetRequest()
getRequest
.send('https://api.example.com/data')
.then((response) => response.json())
.then((data) => console.log(data))
const postRequest = new PostRequest()
postRequest
.send('https://api.example.com/data', { key: 'value' })
.then((response) => response.json())
.then((data) => console.log(data))
数据格式化
在前端开发中,数据格式化也是经常需要处理的,可以将不同的格式化逻辑封装到不同的类中,使得每个类只负责一种格式化方式,如日期格式化、货币格式化等。 示例:
class DateFormatter {
format(date: Date): string {
return date.toLocaleDateString()
}
}
class CurrencyFormatter {
format(amount: number): string {
return `$${amount.toFixed(2)}`
}
}
// 使用示例
const dateFormatter = new DateFormatter()
console.log(dateFormatter.format(new Date())) // 输出: 例如 12/31/2022
const currencyFormatter = new CurrencyFormatter()
console.log(currencyFormatter.format(123.456)) // 输出: $123.46
Keep Reading