Принципы разработки программного обеспечения, из книги Robert C Martin Code , Air -кондиционированный с JavaScript. Это не метод стиля. Это производственное руководство для читаемой программы, многоразового и перепроизводства в сценарии Java.
Не каждый принцип здесь должен следовать точно, и даже меньше, чем это будет согласовано во всем мире. Это руководящие принципы, не более, но они являются руководящими принципами для многолетнего коллективного опыта с помощью чистого кода _.
Срок службы разработки программного обеспечения составляет более 50 лет, а также мы все еще узнаем многое. «Когда разработка программного обеспечения старая, инженерная инженерия сама по себе», возможно, у нас будут более сложные правила. Теперь пусть эти руководящие принципы служат тестом для оценки качества кода JavaScript, который вы и ваша команда производите.
Другая вещь: знание этих принципов не сделает вас сразу же лучшим программистом за всю историю, и работа с ними в течение многих лет не означает, что вы не будете делать ошибки. Каждая часть кода начинается как первый черновик, такой как работа над влажной глиной, которая не получит окончательную форму с первого взгляда, так как мы всегда снимаем дефекты, когда. Мы рассмотрим это с нашими сверстниками. Так что не давите себя из -за первых черновиков, которые нуждаются в улучшении. Вместо этого преодолеть код!
плохой:
const yyyymmdstr = moment ( ) . format ( "YYYY/MM/DD" )хороший:
const currentDate = moment ( ) . format ( "YYYY/MM/DD" )⬆ Вернуться к вершине
плохой:
getUserInfo ( )
getClientData ( )
getCustomerRecord ( )хороший:
getUser ( )⬆ Вернуться к вершине
Мы прочитаем больше кода, чем будем написать. Важно, чтобы код, который мы пишем, читаемый и исследовал. Не называть переменные, которые в конечном итоге имеют смысл понять нашу программу, что затрудняет читателей. Сделайте ваши имена поиск. Такие инструменты, как Buddy.js и Eslint, могут помочь определить неназванные константы.
плохой:
// What the heck is 86400000 for?
setTimeout ( blastOff , 86400000 )хороший:
// Declare them as capitalized named constants.
const MILLISECONDS_PER_DAY = 60 * 60 * 24 * 1000 //86400000;
setTimeout ( blastOff , MILLISECONDS_PER_DAY )⬆ Вернуться к вершине
плохой:
const address = "One Infinite Loop, Cupertino 95014"
const cityZipCodeRegex = / ^[^,\]+[,\s]+(.+?)s*(d{5})?$ /
saveCityZipCode (
address . match ( cityZipCodeRegex ) [ 1 ] ,
address . match ( cityZipCodeRegex ) [ 2 ]
)хороший:
const address = "One Infinite Loop, Cupertino 95014"
const cityZipCodeRegex = / ^[^,\]+[,\s]+(.+?)s*(d{5})?$ /
const [ _ , city , zipCode ] = address . match ( cityZipCodeRegex ) || [ ]
saveCityZipCode ( city , zipCode )⬆ Вернуться к вершине
Всегда ясно, чем неявное.
плохой:
const locations = [ "Austin" , "New York" , "San Francisco" ]
locations . forEach ( ( l ) => {
doStuff ( )
doSomeOtherStuff ( )
// ...
// ...
// ...
// Wait, what is `l` for again?
dispatch ( l )
} )хороший:
const locations = [ "Austin" , "New York" , "San Francisco" ]
locations . forEach ( ( location ) => {
doStuff ( )
doSomeOtherStuff ( )
// ...
// ...
// ...
dispatch ( location )
} )⬆ Вернуться к вершине
Если класс имени/объект скажет вам что -то, не повторяйте это в имени переменной.
плохой:
const Car = {
carMake : "Honda" ,
carModel : "Accord" ,
carColor : "Blue" ,
}
function paintCar ( car , color ) {
car . carColor = color
}хороший:
const Car = {
make : "Honda" ,
model : "Accord" ,
color : "Blue" ,
}
function paintCar ( car , color ) {
car . color = color
}⬆ Вернуться к вершине
Аргументы по умолчанию не в автономном режиме. Бей, что если вы нас, они, ваша функция будет предоставлять значения по умолчанию только для undefined аргументов. Другие «фальсификационные» значения su '' , "" false , null , 0 , и NaN , не будут привлечены к значению по умолчанию.
плохой:
function createMicrobrewery ( name ) {
const breweryName = name || "Hipster Brew Co."
// ...
}хороший:
function createMicrobrewery ( name = "Hipster Brew Co." ) {
// ...
}⬆ Вернуться к вершине
Очень трудно получить наследство классов чтения, создать и классические определения классов ES5. Если вам нужна наследственность (и имейте в виду, что он вам не понадобится), вы предпочтете классы ES2015/ES6. Тем не менее, постарайтесь оставаться небольшими функциями на классах, чтобы вы оказались необходимыми больше и сложнее.
плохой:
const Animal = function ( age ) {
if ( ! ( this instanceof Animal ) ) {
throw new Error ( "Instantiate Animal with `new`" )
}
this . age = age
}
Animal . prototype . move = function move ( ) { }
const Mammal = function ( age , furColor ) {
if ( ! ( this instanceof Mammal ) ) {
throw new Error ( "Instantiate Mammal with `new`" )
}
Animal . call ( this , age )
this . furColor = furColor
}
Mammal . prototype = Object . create ( Animal . prototype )
Mammal . prototype . constructor = Mammal
Mammal . prototype . liveBirth = function liveBirth ( ) { }
const Human = function ( age , furColor , languageSpoken ) {
if ( ! ( this instanceof Human ) ) {
throw new Error ( "Instantiate Human with `new`" )
}
Mammal . call ( this , age , furColor )
this . languageSpoken = languageSpoken
}
Human . prototype = Object . create ( Mammal . prototype )
Human . prototype . constructor = Human
Human . prototype . speak = function speak ( ) { }хороший:
class Animal {
constructor ( age ) {
this . age = age
}
move ( ) {
/* ... */
}
}
class Mammal extends Animal {
constructor ( age , furColor ) {
super ( age )
this . furColor = furColor
}
liveBirth ( ) {
/* ... */
}
}
class Human extends Mammal {
constructor ( age , furColor , languageSpoken ) {
super ( age , furColor )
this . languageSpoken = languageSpoken
}
speak ( ) {
/* ... */
}
}⬆ Вернуться к вершине
Этот стиль очень полезен в сценарии Java и видит его во многих библиотеках, таких как Jquey и Lodash. Это позволяет выразить ваш код и наименьшие сплетни. По этой причине, я полагаю, используйте метод последовательности и посмотрите, насколько чистый ваш код. В ваших функциях класса вам нужно только вернуть это в конце каждой функции, и вы можете подключить дополнительные методы класса.
плохой:
class Car {
constructor ( make , model , color ) {
this . make = make
this . model = model
this . color = color
}
setMake ( make ) {
this . make = make
}
setModel ( model ) {
this . model = model
}
setColor ( color ) {
this . color = color
}
save ( ) {
console . log ( this . make , this . model , this . color )
}
}
const car = new Car ( "Ford" , "F-150" , "red" )
car . setColor ( "pink" )
car . save ( )хороший:
class Car {
constructor ( make , model , color ) {
this . make = make
this . model = model
this . color = color
}
setMake ( make ) {
this . make = make
// NOTE: Returning this for chaining
return this
}
setModel ( model ) {
this . model = model
// NOTE: Returning this for chaining
return this
}
setColor ( color ) {
this . color = color
// NOTE: Returning this for chaining
return this
}
save ( ) {
console . log ( this . make , this . model , this . color )
// NOTE: Returning this for chaining
return this
}
}
const car = new Car ( "Ford" , "F-150" , "red" ) . setColor ( "pink" ) . save ( )⬆ Вернуться к вершине
Как указано в [ дизайнерских шаблонах ] (https://en.wikipedia.org/wiki/design_patterns) по банде из четырех человек, вы должны предпочесть композицию над наследством, когда можете. Есть много причин лица, чтобы использовать наследование и многие лица использования композиции. Основной момент этого принципа заключается в том, что если ваш ум будет установлен для наследования, постарайтесь подумать, может ли композиция решить вашу проблему лучше. В некоторых случаях это может.
После этого вы можете задаться вопросом: «Когда мне следует использовать наследство?» Это зависит от вашей проблемы, которую вы хотите решить, но это приличный список, когда наследование более логично, чем композиция:
Ваше наследство-это отношения », а не« имеет отношения »(человеческое-> животное противоположное пользователь-> данные пользователя).
Вы можете повторно использовать код из основных классов (люди могут перемещаться как все животные).
Вы хотите внести общие изменения в полученных классах, изменяя базовый класс. (Измените калории для всех животных, когда они движутся).
плохой:
class Employee {
constructor ( name , email ) {
this . name = name
this . email = email
}
// ...
}
// Bad because Employees "have" tax data. EmployeeTaxData is not a type of Employee
class EmployeeTaxData extends Employee {
constructor ( ssn , salary ) {
super ( )
this . ssn = ssn
this . salary = salary
}
// ...
}хороший:
class EmployeeTaxData {
constructor ( ssn , salary ) {
this . ssn = ssn
this . salary = salary
}
// ...
}
class Employee {
constructor ( name , email ) {
this . name = name
this . email = email
}
setTaxData ( ssn , salary ) {
this . taxData = new EmployeeTaxData ( ssn , salary )
}
// ...
}⬆ Вернуться к вершине