Princípios de engenharia de software, do livro Robert C Martin Code , ar -condicionado com JavaScript. Este não é um método de estilo. É um guia de produção para um programa legível, reutilizável e re -fabricação no script Java.
Nem todo princípio aqui deve ser seguido com precisão e menos do que isso será acordado globalmente. Essas são diretrizes, não mais, mas são diretrizes por muitos anos de experiência coletiva por código limpo _.
A vida útil da engenharia de software é superior a 50 anos, assim como ainda aprendemos muitas coisas. "Quando a engenharia de software é antiga, a engenharia está em si", talvez tenhamos regras mais difíceis a serem seguidas. Agora, deixe essas diretrizes servirem como um teste para avaliar a qualidade do código JavaScript que você e sua equipe produzem.
Outra coisa: saber que esses princípios não farão você imediatamente o melhor programador de todos os tempos, e trabalhar com eles por muitos anos não significa que você não cometerá erros. Cada parte do código começa como um primeiro rascunho, como trabalhar em uma argila úmida que não obterá a forma final da primeira vista, pois sempre removemos defeitos quando. Nós o revisamos com nossos colegas. Portanto, não se pressione por causa dos primeiros rascunhos que precisam de melhorias. Em vez disso, supere o código!
ruim:
const yyyymmdstr = moment ( ) . format ( "YYYY/MM/DD" )bom:
const currentDate = moment ( ) . format ( "YYYY/MM/DD" )⬆ De volta ao topo
ruim:
getUserInfo ( )
getClientData ( )
getCustomerRecord ( )bom:
getUser ( )⬆ De volta ao topo
Vamos ler mais código do que escreveremos. É importante que o código que escrevemos seja legível e pesquise. Para não nomear as variáveis que acabam sendo significativas para entender nosso programa, dificultando os leitores. Faça seus nomes pesquisar. Ferramentas como Buddy.js e Eslint podem ajudar a determinar constantes sem nome.
ruim:
// What the heck is 86400000 for?
setTimeout ( blastOff , 86400000 )bom:
// Declare them as capitalized named constants.
const MILLISECONDS_PER_DAY = 60 * 60 * 24 * 1000 //86400000;
setTimeout ( blastOff , MILLISECONDS_PER_DAY )⬆ De volta ao topo
ruim:
const address = "One Infinite Loop, Cupertino 95014"
const cityZipCodeRegex = / ^[^,\]+[,\s]+(.+?)s*(d{5})?$ /
saveCityZipCode (
address . match ( cityZipCodeRegex ) [ 1 ] ,
address . match ( cityZipCodeRegex ) [ 2 ]
)bom:
const address = "One Infinite Loop, Cupertino 95014"
const cityZipCodeRegex = / ^[^,\]+[,\s]+(.+?)s*(d{5})?$ /
const [ _ , city , zipCode ] = address . match ( cityZipCodeRegex ) || [ ]
saveCityZipCode ( city , zipCode )⬆ De volta ao topo
É sempre claro melhor do que implícito.
ruim:
const locations = [ "Austin" , "New York" , "San Francisco" ]
locations . forEach ( ( l ) => {
doStuff ( )
doSomeOtherStuff ( )
// ...
// ...
// ...
// Wait, what is `l` for again?
dispatch ( l )
} )bom:
const locations = [ "Austin" , "New York" , "San Francisco" ]
locations . forEach ( ( location ) => {
doStuff ( )
doSomeOtherStuff ( )
// ...
// ...
// ...
dispatch ( location )
} )⬆ De volta ao topo
Se a classe/objeto de nome lhe informar algo, não repita isso em seu nome de variável.
ruim:
const Car = {
carMake : "Honda" ,
carModel : "Accord" ,
carColor : "Blue" ,
}
function paintCar ( car , color ) {
car . carColor = color
}bom:
const Car = {
make : "Honda" ,
model : "Accord" ,
color : "Blue" ,
}
function paintCar ( car , color ) {
car . color = color
}⬆ De volta ao topo
Argumentos padrão estão offline. Além disso, se você nós, eles, sua função fornecerá apenas valores padrão para argumentos undefined . Outros valores "falsamente" su '' , "" false , null , 0 e NaN , não serão adiados por um valor padrão.
ruim:
function createMicrobrewery ( name ) {
const breweryName = name || "Hipster Brew Co."
// ...
}bom:
function createMicrobrewery ( name = "Hipster Brew Co." ) {
// ...
}⬆ De volta ao topo
É muito difícil obter uma herança de aulas de leitura, construir e definições clássicas de classes ES5. Se você precisar de hereditariedade (e esteja ciente de que pode não precisar), você preferirá as classes ES2015/ES6. No entanto, tente permanecer as pequenas funções nas classes, para que você se sinta maior e mais complicado.
ruim:
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 ( ) { }bom:
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 ( ) {
/* ... */
}
}⬆ De volta ao topo
Esse estilo é muito útil no script Java e o vê em muitas bibliotecas como JQUEY e LODASH. Ele permite que seu código seja expresso e a menor fofoca. Por esse motivo, sugiro, use o método de sequência e dê uma olhada em como o seu código é limpo. Nas funções da sua classe, você só precisa retornar isso no final de cada função e pode conectar os métodos de classe adicionais.
ruim:
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 ( )bom:
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 ( )⬆ De volta ao topo
Conforme declarado em [ Padrões de design ] (https://en.wikipedia.org/wiki/design_patterns) por gangue de quatro, você deve preferir a composição da herança quando puder. Existem muitas causas do rosto para usar a herança e muitas das faces do uso da composição. O ponto principal desse princípio é que, se sua mente for instalada para herança, tente pensar se a composição pode resolver seu problema melhor. Em alguns casos, pode.
Você pode se perguntar depois disso: "Quando devo usar a herança?" Isso depende do seu problema que você deseja resolver, mas esta é uma lista decente quando a herança é mais lógica que a composição:
Sua herança é um relacionamento "e não" tem "relacionamento (humano-> animal oposto ao usuário-> Detalhes do usuário).
Você pode reutilizar o código das classes básicas (os humanos podem se mover como todos os animais).
Você deseja fazer alterações gerais nas classes derivadas, alterando a classe básica. (Mude as calorias para todos os animais quando eles se movem).
ruim:
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
}
// ...
}bom:
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 )
}
// ...
}⬆ De volta ao topo