开源日报 每天推荐一个 GitHub 优质开源项目和一篇精选英文科技或编程文章原文,坚持阅读《开源日报》,保持每日学习的好习惯。
今日推荐开源项目:《代码音乐 sonic-pi》
今日推荐英文原文:《Here’s How Consistency Improves Your Code’s Readability》

今日推荐开源项目:《代码音乐 sonic-pi》传送门:项目链接
推荐理由:这个项目将创作音乐与写代码融合到了一起——你可以通过代码来创造音乐了。操作这些代码并不需要很多乐理知识,而这些语法与常用的编程语言的差别也不算太大,如果只是想要在碎片时间玩一玩的话,甚至可以只通过不断调整与组合现有的示例代码来创作自己的旋律。
今日推荐英文原文:《Here’s How Consistency Improves Your Code’s Readability》作者:Yong Cui
原文链接:https://medium.com/better-programming/heres-how-consistency-improves-your-code-s-readability-644d64b142b5
推荐理由:一致性能够为代码可读性做出的贡献

Here’s How Consistency Improves Your Code’s Readability

There’s nothing more valuable than a consistent engineer

Writing code is difficult. Your code can’t run if your syntax is wrong, if your parameters are wrong, or if your data are corrupted. There are hundreds or thousands of things that make your code unable to execute.

Writing readable code is even more difficult. After learning the language and pertinent frameworks, you’re finally able to write some code that your computer understands. However, chances are that others can’t read your code — even with the help of your helpful (at least in your mind) comments.

The problem of code’s readability doesn’t happen only to junior developers, but also to seasoned developers if they haven’t learnt the right habit to begin with. In this article, I’d like to share the tips that I use to write code that is readable and thus maintainable in the long term by following just one principle — consistency.

1. Style Consistency

Different programming languages can have their own style guidelines, some of which are even part of the syntax. It’s always a good practice to respect these guidelines, although I can appreciate that developers can have certain variations in their code. However, within the scope of any project, developers should adopt the same coding styles.

For instance, you need to declare arrays in your project. Many of the arrays have multiple items. One way to have style consistency with better readability is to have these arrays occupy multiple lines, with each line having just one item, as shown below. Readability is reduced if you sometimes declare a long array using a single line while sometimes using multiple lines.
array0 = [
    "item_long_var0",
    "item_long_var1",
    "item_long_var2"
]

array1 = [
    "item_long_var0", 
    "item_long_var1", 
    "item_long_var2"
]
For another instance, we often need to call functions with multiple parameters, which results in the invocation exceeding the recommended line width. Some developers may adopt the following style.
do_something(param0=0, param1="hello", param2=["1", "2", "3"], param3=[2, 4, 5],
             param4="Item", param5="Hello World")

do_something(param0=100000, param1="hello world", param2=["1", "2", "3", "4", "5"],
             param3=[1, 2, 4, 5], param4="Long Item", param5="Hello World")
Function Invocation

However, with the varying lengths of individual parameters, it’s harder to eyeball what parameters are passed for different function invocations. Instead, the following style has better readability, which is particularly useful when functions involve multiple parameters.
do_something(param0=0,
             param1="hello",
             param2=["1", "2", "3"],
             param3=[2, 4, 5],
             param4="Item",
             param5="Hello World")

do_something(param0=100000,
             param1="hello world",
             param2=["1", "2", "3", "4", "5"],
             param3=[1, 2, 4, 5],
             param4="Long Item",
             param5="Hello World")
Function Invocation — Better Readability

Certainly, there are many variations in styles that your code can adopt. But I just want to reiterate: Keep your style consistent using the one with the best readability.

2. Consistent Naming

No matter what programming language you use, it’s so essential to follow the naming conventions. When it comes to naming, don’t reinvent the wheel. Think about your own name or your children’s names. You probably follow your culture’s convention, right? You don’t want to call your daughter David or your son Jessica — the same principle should apply to the naming in your code too.

Specifically, consistent naming applies to three aspects.
  • First, use camel case or snake case consistently following your language’s convention. For instance, in camel case naming, instance variables are usually named as varName, while classes are named as ClassName. In addition, these names should clearly reflect what they are. For instance, the names of functions should indicate the job they’re performing. The names of classes should show the data they’re holding.
  • Second, related variables, functions, or classes that do related things should be named similarly to reflect their close relationship. For instance, suppose that you’re creating multiple instances for a Team class. It’s not a good idea to call them t0, tm1, team2, and tem3. Instead, they should be called team0, team1, team2, and team3. Don’t be afraid of creating a long name — a long meaningful name is always better than a short unclear name.
  • Third, file names should be named consistently. It’s apparent that file names should reflect their content. But beyond that, consistent naming of files makes it easier for you to understand what they are. For instance, in Swift, we can name a series of files of subclass UIViewController so that they end with ViewController, such as UserProfileViewController and UserDashboardViewController.

3. Structural Consistency

We write code at various hierarchical levels. Some lower blocks of code can include functions, loops, and so on. Some higher blocks include classes and modules. It’s important for us to write these different levels of code in a consistent manner — structurally.

Let’s just use an example of writing a function. We all know that writing good functions is one of the most key tasks in any project. Suppose that we’re starting with the draft of the following function, say getProcessedData.
function getProcessedData() {
    // 10 lines of code to fetch the data from the server
    // 5 lines of code to run necessary calculation on the data
    // 1 or 2 lines of code to format the returned data
}
Structural Consistency in Function — Prototyping

Once we prototype the function and find that it works, it’s time to refactor the function. Some developers may tend to create the refactored version, as shown below.
function getProcessedData() {
    fetchDataRemotely()
    calculateData()
    // 1 or 2 lines of code to format the returned data 
}

function fetchDataRemotely() {
    // 10 line of code
}

function calculateData() {
    // 5 lines of code
}
Structural Consistency in Function—Refactored

As you may notice, this version moves a bunch of code to separate functions with proper names to indicate their intended purposes. Probably because of the shorter length of formatting, the code related to formatting is still part of the getProcessedData function. However, this refactoring doesn’t follow the structural consistency principle — these lines of code are at different abstraction levels. To create better readability, we should consider making code at the same abstraction level, regardless of the length of the abstracted components, as shown below.
function getProcessedData() {
    fetchDataRemotely()
    calculateData()
    formatData()
}

function fetchDataRemotely() {
    // 10 line of code
}

function calculateData() {
    // 5 lines of code
}

function formatData() {
    // 1 or 2 lines of code
}
Structural Consistency in Function — Refactored Better

In addition to functions, the same structural consistency should apply to classes that you’re creating. Relevant considerations include how you should order the instance and class variables, how you order the instance and class functions, and so on. How about calculated attributes? By applying the structural consistency principle, it’ll become much easier for you and your readers to locate things.

4. Directory/File Layout Consistency

With the increasing scope of your project, you’re creating more and more files as well as folders in your work project. If you don’t manage these files, your project is deemed to be a mess. When you show your work to your coworkers, it will a total headache for everyone, probably including yourself, trying to figure out what these files are and in which files you’ll find what you need.

For instance, when you start a project in Android Studio, you’ll have an automatically generated directory tree, as shown below.

Android Project File Structure (Source: Android Official Website)

It’s obvious that the template doesn’t only use one folder that has everything. Instead, it has different folders with their respective jobs. For instance, your resource-related files should go to the res folder, while your code should go to the java folder. More important, when your app is complicated, you should have subdirectories within the java folder, for instance, you can have a folder for your data models, or you probably have a folder for views, and so on.

I don’t think there is a one-size-fits-all solution, but you should develop your file structure with a meaningful organization and use it consistently, which is the key to improving your entire project’s readability and maintainability.

Conclusions

Again, it’s not simple to write readable code — it’s hard for beginners, and it’s also hard for seasoned programmers. In my opinion, it’s a lifelong learning process for every programmer to improve their code’s readability. I just shared the tips that I’ve learned from my ten-plus years of coding. Please feel free to share what you have for code readability so that we can all improve together.

Thank you for reading this piece.
下载开源日报APP:https://openingsource.org/2579/
加入我们:https://openingsource.org/about/join/
关注我们:https://openingsource.org/about/love/