惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
Security Latest
Security Latest
C
Cisco Blogs
P
Palo Alto Networks Blog
Know Your Adversary
Know Your Adversary
Project Zero
Project Zero
C
Cyber Attacks, Cyber Crime and Cyber Security
NISL@THU
NISL@THU
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
S
Secure Thoughts
P
Privacy International News Feed
V
Vulnerabilities – Threatpost
D
Docker
Google Online Security Blog
Google Online Security Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Recent Announcements
Recent Announcements
T
The Exploit Database - CXSecurity.com
G
Google Developers Blog
Schneier on Security
Schneier on Security
小众软件
小众软件
爱范儿
爱范儿
GbyAI
GbyAI
J
Java Code Geeks
T
Tailwind CSS Blog
Cisco Talos Blog
Cisco Talos Blog
The Hacker News
The Hacker News
D
DataBreaches.Net
Blog — PlanetScale
Blog — PlanetScale
TaoSecurity Blog
TaoSecurity Blog
MyScale Blog
MyScale Blog
B
Blog RSS Feed
Cyberwarzone
Cyberwarzone
有赞技术团队
有赞技术团队
Martin Fowler
Martin Fowler
C
CXSECURITY Database RSS Feed - CXSecurity.com
S
Securelist
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Y
Y Combinator Blog
S
Schneier on Security
Latest news
Latest news
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - 叶小钗
F
Fortinet All Blogs
M
MIT News - Artificial intelligence
PCI Perspectives
PCI Perspectives
V
V2EX
V2EX - 技术
V2EX - 技术
O
OpenAI News
W
WeLiveSecurity

Dmitri Pavlutin Blog

Pure Functions in JavaScript: A Beginner's Guide Record Type in TypeScript: A Quick Intro How to Write Comments in React: The Good, the Bad and the Ugly 4 Ways to Create an Enum in JavaScript React forwardRef(): How to Pass Refs to Child Components TypeScript Function Types: A Beginner's Guide How to Use v-model to Access Input Values in Vue Mastering Vue refs: From Zero to Hero Environment Variables in JavaScript: process.env 5 Must-Know Differences Between ref() and reactive() in Vue How to Destructure Props in Vue (Composition API) Triangulation in Test-Driven Development How to Use nextTick() in Vue Programming to Interface Vs to Implementation A Smarter JavaScript Mapper: array.flatMap() Array Grouping in JavaScript: Object.groupBy() How to Access ES Module Metadata using import.meta JSON Modules in JavaScript How to Trim Strings in JavaScript TypeScript Function Overloading How to Debounce and Throttle Callbacks in Vue How to Show/Hide Elements in Vue Sparse vs Dense Arrays in JavaScript How to Fill an Array with Initial Values in JavaScript Covariance and Contravariance in TypeScript What are Higher-Order Functions in JavaScript? How to Use TypeScript with React Components Index Signatures in TypeScript How to Use React useReducer() Hook unknown vs any in TypeScript A Guide to React Context and useContext() Hook How to Use Promise.any() 2 Ways to Remove a Property from an Object in JavaScript 'return await promise' vs 'return promise' in JavaScript How to Use Promise.allSettled() How to Use fetch() with JSON JavaScript Promises: then(f,f) vs then(f).catch(f) What is a Promise in JavaScript? How to Use Promise.all() A Simple Guide to Component Props in React Don't Stop Me Now: How to Use React useTransition() hook A Simple Explanation of JavaScript Variables: const, let, var ES Modules Dynamic Import How to Memoize with React.useMemo() How to Cleanup Async Effects in React Why Math.max() Without Arguments Returns -Infinity How to Debounce and Throttle Callbacks in React Don't Confuse Function Expressions and Function Declarations in JavaScript How to Use ES Modules in Node.js Solving a Mystery Behavior of parseInt() in JavaScript How to Use Array Reduce Method in JavaScript 3 Ways to Merge Arrays in JavaScript A Guide to Jotai: the Minimalist React State Management Library The Difference Between Values and References in JavaScript How to Implement a Queue in JavaScript A Helpful Algorithm to Determine "this" value in JavaScript React useRef() Hook Explained in 3 Steps 7 Interview Questions on "this" keyword in JavaScript. Can You Answer Them? How to Greatly Enhance fetch() with the Decorator Pattern 7 Interview Questions on JavaScript Closures. Can You Answer Them? What's a Method in JavaScript? array.sort() Does Not Simply Sort Numbers in JavaScript How to Solve the Infinite Loop of React.useEffect() The New Array Method You'll Enjoy: array.at(index) What's the Difference between DOM Node and Element? Why Promises Are Faster Than setTimeout()? Everything About Callback Functions in JavaScript How React Updates State 5 Mistakes to Avoid When Using React Hooks 5 Best Practices to Write Quality JavaScript Variables Type checking in JavaScript: typeof and instanceof operators 3 Ways to Check if a Variable is Defined in JavaScript React Forms Tutorial: Access Input Values, Validate, Submit Forms Prototypal Inheritance in JavaScript How to Timeout a fetch() Request How to Learn JavaScript If You're a Beginner A Simple Explanation of React.useEffect() A Simple Explanation of JavaScript Iterators How to Use React Controlled Inputs Everything about null in JavaScript How to Use Fetch with async/await Getting Started with Arrow Functions in JavaScript An Interesting Explanation of async/await in JavaScript Front-end Architecture: Stable and Volatile Dependencies Is it Safe to Compare JavaScript Strings? How to Access Object's Keys, Values, and Entries in JavaScript What Actually is a String in JavaScript? 3 Ways to Shallow Clone Objects in JavaScript (w/ bonuses) Checking if an Array Contains a Value in JavaScript JavaScript Event Delegation: A Beginner's Guide How to Parse URL in JavaScript: hostname, pathname, query, hash 3 Ways to Detect an Array in JavaScript How to Get the Screen, Window, and Web Page Sizes in JavaScript 3 Ways to Check If an Object Has a Property/Key in JavaScript How to Compare Objects in JavaScript Object.is() vs Strict Equality Operator in JavaScript Own and Inherited Properties in JavaScript 5 Differences Between Arrow and Regular Functions How to Use Object Destructuring in JavaScript Your Guide to React.useCallback()
The Explicit Coding Discipline
Dmitri Pavlutin · 2020-01-15 · via Dmitri Pavlutin Blog

The more I evaluate my experience as a software developer, the more I understand the importance of good communication.

The code is the source of truth for both running and developing the application. The discipline of writing quality, performant and understandable code is the key to the success of the project.

In the real world, there's always room for mistakes. The platforms, the programming languages have flaws. The developers regularly make mistakes and write confusing code, jerk-knee solutions.

A good way to diminish the flaws of unreadable code is to develop a discipline of explicit coding: an approach that favors good naming that leaves no doubt about the intent of the code.

Let's see how explicit coding discipline can help you.

1. Why explicit matters

Before discussing the coding discipline, I'd like to tell you a story of how communication misunderstanding and dual interpretation can lead to problems.

In March 2019 I traveled to Canary Islands: a beautiful Spanish archipelago with never-ending spring. I had arrived at Tenerife Island by flying from Barcelona to Tenerife North Airport.

Tenerife North Airport

While being there, I was reading that at the Tenerife North Airport in 1977 happened the worst airline disaster ever: two Boeing 747 passenger jets collided on the runway.

Citing Wikipedia, the short conclusion of why the accident had happened:

"The subsequent investigation by Spanish authorities concluded that the primary cause of the accident was the KLM captain's decision to take off in the mistaken belief that a takeoff clearance from air traffic control (ATC) had been issued. Dutch investigators placed a greater emphasis on mutual misunderstanding in radio communications between the KLM crew and ATC."

Non-deterministic communication was one of the reasons for the accident.

Being at a different scale, still efficient communication through deterministic naming and leaving no room for side interpretation is important in software development too.

2. Explicit naming

The most time-consuming in software development is not writing new code... but understanding what the actual code does.

2.1 Variables naming

Variables should clearly indicate the meaning of the content it has.

For example, if you're summing the number of an array:


// Bad

let s = 0;

const items = [1, 2, 3];

for (const item of items) {

s += item;

}

s; // => 6


What does s variable stand for? Only after looking at the s += item expression you can understand that s holds the sum of items.

An explicit variable name sum clearly increases the readability of the code snippet. Without knowing the details, you can understand that sum indicates a variable that holds the sum of some numbers.


// Good

let sum = 0;

const items = [1, 2, 3];

for (const item of items) {

sum += item;

}

sum; // => 6


When naming the variable, if you get back to this code in 1 month, can you understand what the variable does for just by looking at the name?

The following list of examples clearly and explicitly says the intent. Even having the variables extracted from the context of the usage, you understand what they do:


// A variable holding the first name. Probably a string.

firstName;

// A variable holding the sum of numbers. Probably a number.

sum;

// A variable holding days. Probably a number.

daysSinceLastModified;

// A variable holding the validation result. Probably a boolean.

isValid;


2.2 Functions naming

Functions should indicate what the cohesive chunk of code does. Again, exactly like with the variables, the function name should explicitly explain what the function does.

For example, you'd like to write a function that calculates the number of days of a day until now. A good name could be daysUntilNow():


function daysUntilNow(date) {

const MILLISECONDS_IN_DAY = 86400 * 1000;

return Math.floor(

(Date.now() - date.getTime()) / MILLISECONDS_IN_DAY

);

}

// Assuming today is 2020-01-15

daysUntilNow(new Date('2020-01-13')); // => 2


daysUntilNow() clearly says that the function calculates the number of days that have passed from a date until now. Moreover, daysUntilNow name helps infer that the function returns a number, which is the count of days.

On the other side, what if this function would have been named untilNow()? Such name leaves open many interpretations of what the function does. Does it return the time passed in seconds or days?

2.3 Avoid anonymous functions

An anonymous function is a function that has no name. A function without a name is also a problem for an easy understanding.

Let's use an anonymous function as an event handler:


button.addEventListener('click',

function() {

const value = document.getElementById('name').value;

if (value !== '') {

itemsList.push(value);

}

}

);


The anonymous function says nothing about what happens in the event handler. You have to read the whole function to get the idea.

Let's apply the explicit coding discipline and add a meaningful name to the function:


button.addEventListener('click',

function appendInputValueToList() {

const value = document.getElementById('name').value;

if (value !== '') {

itemsList.push(value);

}

}

);


appendInputValueToList() is a good name for what happens when the button is clicked. Even without reading the body of the function, by reading its name, you can conclude that: when the button is clicked, an input value is read and appended to the list.

Having the functions (and variables, methods, classes, source files) meaningfully and explicitly named helps in debugging. When an error happens, if all the functions explicitly describe what happens in them, the stack trace gives more clues about what had happened and where is the source of error.

An exception are inline functions (that have just one expression): they can be anonymous. For example:


const items = [1, 2, 3];

items.map(item => item * 2);


item => item * 2 is an inline arrow function that is easy to understand.

3. Avoid tricks in favor of explicit code

When I was a student, I was playing to find the shortest possible code that solves a particular task. It was indeed fun: I was searching the language operators to find the shortest expression to solve the task. It was a playful way of learning.

While the shortest code and tricks are fun when you're a student, it's not fun when you write that in production. Nobody cares about shortest code. What everybody cares is to easily understand what the code does.

Shortest possible code meme

Another problem is the use of implicit side effects of the operators. For example, you'd like to access a property and default if the property doesn't exist.

Let's use the trick that involves || operator:


function getFontSize(style) {

return style.fontSize || 0;

}


style.fontSize || 0 evaluates to 0 when style.fontSize is a falsy value. This expression uses a side-effect of the or operator.

I choose an explicit code that clearly indicates that fontSize property might be missing:


function getFontSize(style) {

let fontSize = 0;

if ('fontSize' in style) {

fontSize = style.fontSize;

}

return fontSize;

}


if ('fontSize' in style) expresses that fontSize property could be missing. Even being verbose, I prefer this code over the previous one.

If you're lucky, the programming language can provide short expressions without loosing in meaningness. Here's an another alternative to access the fontSize property using destructuring assignment:


function getFontSize(style) {

const { fontSize = 0 } = style;

return fontSize;

}


{ fontSize = 0 } = style destructuring assignment is short. But at the same time clearly indicates that fontSize property might be missing and defaults to 0.

4. Screaming architecture

The explicit discipline is not limited to naming only.

The uses-cases of the application should be seen in the source files organization of the application at the highest level.

For example, my blog implements these use-cases: show a particular post for reading, list posts excerpts with pagination, list all posts on a single page, list posts by a tag. When you look at the main folder of the components, the uses-cases are explicitly visible.

Application structure by use-cases

Neither the framework (like GatsbyJS), UI library (React) should dictate me how to structure the application.

This structuring can be metaphorically named Screaming architecture.

5. Conclusion

The explicit coding discipline favors clear and explicit expression of intent in the code.

It suggests writing meaningful names for variables, functions, classes and other constructions. It suggests avoiding tricky solutions in favor of readings and clear intent.

The uses-cases dictate the structure of the application. What the application does should not be implicitly hidden in an organization that the framework is trying to dictate you. Avoid having folders like /controllers, /views at the highest level of folders organization, in favor of folders containing features and use-cases: /categories, /products, etc.

Explicit code and structure let you develop the system easier.