JavaScript 的坚实原则
SOLID 原则是一组软件设计原则,它帮助我们理解如何构建代码,以尽可能地提高代码的健壮性、可维护性和灵活性
以下是SOLID原则:
S - 单一职责原则
任何函数都必须只负责做一件事。
软件规范中只有一个潜在的变化能够影响该类的规范。
示例:假设我们要验证表单,然后在数据库中创建一个用户
不
/* A function with such a name is a symptom of ignoring the Single Responsibility Principle
* Validation and Specific implementation of the user creation is strongly coupled.
* That's not good
*/
validateAndCreatePostgresUser = (name, password, email) => {
//Call an external function to validate the user form
const isFormValid = testForm(name, password, email);
//Form is Valid
if(isFormValid){
CreateUser(name, password, email) //Specific implementation of the user creation!
}
}
是的
//Only Validate
validateRequest = (req) => {
//Call an external function to validate the user form
const isFormValid = testForm(name, password, email);
//Form is Valid
if(isFormValid){
createUser(req); // implemented in another function/module
}
}
//Only Create User in the Database
createUser = (req) => CreateUser(req.name, req.password, req.email)
/*A further step is to declarel this function in another file
* and import it into this one.
*/
这似乎是一个很小的变化,但却将验证逻辑与用户创建分离,由于多种原因,这种情况在未来可能会发生变化!
O——开放封闭原则
必须允许软件系统通过添加新代码而不是更改现有代码来改变其行为。
对扩展开放,但对修改关闭
如果我们有这样的事情:
const roles = ["ADMIN", "USER"]
checkRole = (user) => {
if(roles.includes(user.role)){
return true;
}else{
return false
}
}
//Test role
checkRole("ADMIN"); //true
checkRole("Foo"); //false
无论出于何种原因,我们都想添加超级用户,而不必修改现有代码(或者也许我们无法修改它),我们可以在另一个函数中执行此操作。
//UNTOUCHABLE CODE!!!
const roles = ["ADMIN", "USER"]
checkRole = (user) => {
if(roles.includes(user.role)){
return true;
}else{
return false
}
}
//UNTOUCHABLE CODE!!!
//We can define a function to add a new role with this function
addRole(role){
roles.push(role)
}
//Call the function with the new role to add to the existing ones
addRole("SUPERUSER");
//Test role
checkRole("ADMIN"); //true
checkRole("Foo"); //false
checkRole("SUPERUSER"); //true
L - 里氏替换原则
使用可互换的部件构建软件系统。
程序中的对象应该可以用其子类型的实例替换,而不会改变该程序的正确性。
class Job {
constructor(customer) {
this.customer = customer;
this.calculateFee = function () {
console.log("calculate price"); //Add price logic
};
}
Simple(customer) {
this.calculateFee(customer);
}
Pro(customer) {
this.calculateFee(customer);
console.log("Add pro services"); //additional functionalities
}
}
const a = new Job("Francesco");
a.Simple();
//Output:
//calculate price
a.Pro();
//Output:
//calculate price
//Add pro services...
I - 接口隔离原则
许多特定于客户端的接口比一个通用接口更好。
Javascript 中没有接口,但让我们看看这个例子
不
//Validate in any case
class User {
constructor(username, password) {
this.username = username;
this.password = password;
this.initiateUser();
}
initiateUser() {
this.username = this.username;
this.validateUser()
}
validateUser = (user, pass) => {
console.log("validating..."); //insert validation logic here!
}
}
const user = new User("Francesco", "123456");
console.log(user);
// validating...
// User {
// validateUser: [Function: validateUser],
// username: 'Francesco',
// password: '123456'
// }
是的
//ISP: Validate only if it is necessary
class UserISP {
constructor(username, password, validate) {
this.username = username;
this.password = password;
this.validate = validate;
if (validate) {
this.initiateUser(username, password);
} else {
console.log("no validation required");
}
}
initiateUser() {
this.validateUser(this.username, this.password);
}
validateUser = (username, password) => {
console.log("validating...");
}
}
//User with validation required
console.log(new UserISP("Francesco", "123456", true));
// validating...
// UserISP {
// validateUser: [Function: validateUser],
// username: 'Francesco',
// password: '123456',
// validate: true
// }
//User with no validation required
console.log(new UserISP("guest", "guest", false));
// no validation required
// UserISP {
// validateUser: [Function: validateUser],
// username: 'guest',
// password: 'guest',
// validate: false
// }
D - 依赖倒置原则
抽象不能依赖于细节。
细节必须依赖于抽象。
不
//The Http Request depends on the setState function, which is a detail
http.get("http://address/api/examples", (res) => {
this.setState({
key1: res.value1,
key2: res.value2,
key3: res.value3
});
});
是的
//Http request
const httpRequest = (url, setState) => {
http.get(url, (res) => setState.setValues(res))
};
//State set in another function
const setState = {
setValues: (res) => {
this.setState({
key1: res.value1,
key2: res.value2,
key3: res.value3
})
}
}
//Http request, state set in a different function
httpRequest("http://address/api/examples", setState);
我要感谢我的朋友Oleksii Trekhleb对本文的贡献。
Oleksii 是这个传奇的GitHub 存储库https://github.com/trekhleb/javascript-algorithms的原作者
综上所述...
SOLID 原则的主要目标是任何软件都应该容忍变化并且易于理解。
SOLID 原则对于编写代码非常有用:
- 易于理解
- 事物在它们应该在的地方
- 类按照预期执行
- 可以轻松调整和扩展,且无错误
- 这将抽象与实现分开
- 这样可以轻松交换实现(Db、Api、框架......)
- 易于测试
就这样。如果您有任何疑问,请在下面发表评论。
文章来源:https://dev.to/francescoxx/solid-principles-in-javascript-3pek