dll简洁易懂

    科技2025-03-19  28

    dll简洁易懂

    Being able to write clean code is crucial to becoming a better software developer. Not only will this practice make your life easier, but it will help others who are accessing your code and work to grow your reputation as a developer who is known for being thorough. This article is a high-level run-through of different tips and techniques that you can use to write clean and understandable code in a project; helping you to maintain code for a longer period of time without any hassle.

    能够编写干净的代码对于成为更好的软件开发人员至关重要。 这种做法不仅会使您的生活变得更轻松,而且还将帮助其他正在访问您代码的人,并努力提高您作为以全面而闻名的开发人员的声誉。 本文是不同技巧和技术的高级概括,可用于在项目中编写简洁易懂的代码。 帮助您更长久地维护代码,而不会遇到麻烦。

    什么是干净代码? (What is clean code?)

    To understand clean code we first need to have an idea of what bad code is — then we can identify problems and solutions to achieve clean code from there.

    为了理解干净的代码,我们首先需要了解什么是坏代码-然后我们可以识别问题和解决方案以从那里实现干净的代码。

    There is a famous analogy about defining bad code that is first narrated by Thomas Holwerda, later in Robert C Martin’s book, in which the measurement of code quality in WTFs/minute!

    托马斯·霍尔维达( Thomas Holwerda )首先叙述了一个有关定义错误代码的著名类比,后来在罗伯特·马丁( Robert C Martin )的书中谈到,用WTF /分钟来衡量代码质量!

    The original image can be found here . 原始图像可以在 这里 找到 。

    Suppose we wrote a piece of code and some other teammates are reading or reviewing the code. If they immediately understand what the code is meant to do, that’s good code. But sometimes we ourselves can’t even understand something that we wrote a few months ago because we ignored understandability practices and wrote bad codes!

    假设我们编写了一段代码,而其他一些队友正在阅读或查看该代码。 如果他们立即了解该代码的用途,那就是好代码。 但是有时我们自己甚至无法理解几个月前写的东西,因为我们忽略了可理解性实践并编写了错误的代码!

    有意义的名字 (Meaningful Names)

    Sometimes we developers say that naming something is the toughest job while writing code, yes indeed! A variable, function, or a class should be self-explanatory to the person who is reading the code, which makes naming very important.

    有时,我们的开发人员会说在编写代码时给某事命名是最困难的工作,的确如此! 变量,函数或类对于正在阅读代码的人员来说应该是不言自明的,这使得命名非常重要。

    Look at this sample code:

    看下面的示例代码:

    Here, we can see two variables list1 and list2 but from the names, we are not getting what the values are or the types of these variables. Here comes the first tip (i.e. using intention-revealing names which also helps developers to stop the spread of disinformation). Please also note that the arrow function inside the filter has the argument named item. This is not very clear as we can’t say what kind of thing this item is!

    在这里,我们可以看到两个变量list1和list2但是从名称来看,我们没有得到这些变量的值或类型。 这是第一个技巧(即使用意图揭示名称,这也有助于开发人员阻止虚假信息的传播)。 另请注意,过滤器中的arrow函数具有名为item的参数。 这不是很清楚,因为我们不能说这是什么东西!

    Let’s refactor it and see how we can make improve here:

    让我们对其进行重构,看看如何在此处进行改进:

    The distinction between function names based on what they do is very important. Suppose we have a function that returns all the users, but now we need the other two functions which will return a specific user by id as well as a list of users who are admins.

    基于函数名称之间的区别非常重要。 假设我们有一个返回所有用户的函数,但是现在我们需要另外两个函数,这些函数将按ID返回特定的用户以及admin用户列表。

    I have seen so many codebases where I found function names like this:

    我看到了很多代码库,在其中找到了这样的函数名:

    It’s not until you read what is inside the function that you can say what this function intends to do. This type of function names creates ambiguity and also keeps other developers in a dark zone where they don’t know about the existing functions and end up creating a new one which does the same thing as getUsers2.

    直到您阅读了函数内部的内容后,您才能说出该函数打算做什么。 这种类型的函数名称会造成歧义,并使其他开发人员无法了解现有功能,因而陷入了一个黑暗的地带,最终创建了一个与getUsers2相同功能的新开发人员。

    Let’s refactor this.

    让我们重构一下。

    You can see in all of the function names we have added the action i.e. get as a prefix. Using verbs as a prefix of the function name is a convention that we should follow because it says what action the function does.

    您可以在所有添加了操作的函数名称中看到,例如,获取作为前缀。 使用动词作为函数名称的前缀是我们应该遵循的约定,因为它说明了函数将执行的操作。

    There are times when super-coders form a team and use super acronyms in every other thing that they write. When we go through their code we can see some short names and sometimes we can’t even pronounce the names they have written down.

    有时,超级编码者组成一个团队,并在他们编写的所有其他东西中使用超级缩写。 当我们浏览他们的代码时,我们可以看到一些短名称,有时我们甚至无法念出他们写下的名称。

    Let’s look into this piece of beautifully created but incomprehensible code:

    让我们看一下这段创建精美但难以理解的代码:

    Here, we have a class named Box (always remember that a class name cannot be a verb and should always be a noun). In this Box class, we have some variables as h, w, a_m, a_ft . Do you understand what these mean and what they store in them? If the answer is yes then this is most likely because it is a pretty simple, small code block and a simple one, but trust me, if you see something like this in a big project you will feel completely confused.

    在这里,我们有一个名为Box的类(总是记住,一个类名不能是动词,而应该始终是名词)。 在这个Box类中,我们有一些变量,如h , w , a_m , a_ft 。 您了解这些含义以及它们存储在其中的含义吗? 如果答案是肯定的,那么这很有可能是因为它是一个非常简单,很小的代码块和一个简单的代码块,但是请相信我,如果您在大型项目中看到类似的东西,您会感到完全困惑。

    Let’s refactor the above code and try to understand how we’re doing it:

    让我们重构上面的代码,并尝试了解我们的做法:

    We have explicitly written down the variable and function names and also added their units. Adding units in the variable names is very important when you have a program that deals with multiple units. It also saves a lot of time while debugging and adding new features.

    我们已经明确写下了变量和函数名称,并添加了它们的单位。 当您有一个处理多个单位的程序时,在变量名称中添加单位非常重要。 在调试和添加新功能时,它还节省了大量时间。

    When writing names, we can follow different conventions for choosing case styles e.g. Snake Case, Pascal Case, Kebab Case, Camel Case. Some languages have their own conventions for using a case style, but we should follow a single case-style throughout the codebase.

    在编写名称时,我们可以遵循不同的约定来选择大小写样式,例如Snake Case,Pascal Case,Kebab Case,Camel Case。 某些语言在使用案例样式时有其自己的约定,但是我们应该在整个代码库中遵循一种案例样式。

    有意义的功能 (Meaningful Functions)

    Functions are a key component of any programming language, and we write a lot of functions in any project. Sometimes they are called the building blocks of the business logic inside the codebase. We might see a long function having a body of hundreds of lines of code but it gets difficult to catch the gist of what it’s doing inside of it. To resolve this issue we follow a simple rule: write small functions that only do one thing.

    函数是任何编程语言的关键组成部分,我们在任何项目中都编写了很多函数。 有时,它们被称为代码库内部业务逻辑的构建块。 我们可能会看到一个长函数包含数百行代码,但要了解其内部功能的要点变得很困难。 要解决此问题,我们遵循一个简单的规则:编写仅做一件事的小函数。

    Sometimes we write functions where we fetch multiple data-points from the database, filter them on different attributes, sort them, run additional transformation methods on the data, generate the HTML from a template, and so on. When this occurs, we can separate out those functions and create small functions. This also creates a good separation of concern among the functions.

    有时,我们会编写一些函数,从数据库中获取多个数据点,对它们进行不同属性的过滤,对它们进行排序,对数据运行其他转换方法,从模板生成HTML,等等。 发生这种情况时,我们可以分离出这些功能并创建较小的功能。 这也会在功能之间建立良好的关注点分离。

    Let’s look into this example function:

    让我们看一下这个示例函数:

    Reading the function you might lose the context of what’s happening inside of it. Here, we are fetching all the pending messages from the database for users who are a merchant and then creating multiple batches based on the BATCH_SIZE before pushing these batches to the job queue and finally updating the status of the sent messages.

    阅读该函数可能会丢失其内部正在发生的情况的上下文。 在这里,我们正在从数据库中为商人用户获取所有待处理消息,然后基于BATCH_SIZE创建多个批次,然后再将这些批次推送到作业队列中,最后更新已发送消息的状态。

    It works, but it looks really cluttered, right? Let’s break this long function into multiple small pieces where each of them performs a single task.

    它可以工作,但是看起来很混乱,对吗? 让我们将此长函数分成多个小块,每个小块执行一个任务。

    This is how the refactored function will look:

    这就是重构函数的外观:

    From the look of it, we can identify what these separate functions are doing, making it easy for developers to narrow down the scope while they refactor or debug around this function.

    从外观上,我们可以确定这些单独的功能在做什么,从而使开发人员在围绕该功能进行重构或调试时,很容易缩小范围。

    Suppose there is a function that is doing multiple things and we cannot separate them as they are closely related. These types of functions need proper indentation and blocking in the code; this explains which block is doing what and creates an abstraction on that separation we were talking about above.

    假设有一个函数正在执行多项操作,并且由于它们关系密切,我们无法将它们分开。 这些类型的函数需要在代码中进行适当的缩进和阻塞。 这解释了哪个块在做什么,并创建了我们上面所讨论的分离的抽象。

    Function arguments are another important thing when it comes to clean code. A helpful convention to follow is to never use more than two arguments in a function, and if you must do this then use an object or a dictionary. As a result, anyone can understand what the data-points re that they are sending as arguments to the function from the keys of the objects.

    当涉及到干净的代码时,函数参数是另一重要的事情。 遵循的一个有用的约定是,函数中不要使用两个以上的参数,如果必须这样做,则可以使用对象或字典。 结果,任何人都可以从对象的键中了解它们作为函数的参数发送的数据点。

    We also follow another rule called DRY (Do not Repeat Yourself) while writing functions. The mental model is pretty easy here, whenever we are writing a block of code that is already written somewhere in the codebase, we should treat that block of code as a function and create one to use in multiple places.

    在编写函数时,我们还遵循另一条称为DRY (请勿重复自己)的规则。 心智模型在这里非常简单,每当我们编写已经在代码库中某处编写的代码块时,我们都应将该代码块视为一个函数,并创建一个可在多个地方使用的代码块。

    相关评论 (Relevant Comments)

    Comments are like butter on bread, without it the bread will be dryer and not as enjoyable to eat. If we put relevant comments in each of the modules or functions we write, then whenever someone jumps into that part of the code they might understand the intention behind the writing of that piece of code. Furthermore, if any change is required then they can do this more confidently as they understand what is going on inside of it!

    评论就像面包上的黄油,没有它,面包将变得更干燥,吃起来也不愉快。 如果我们在编写的每个模块或函数中添加相关的注释,那么每当有人跳入代码的那一部分时,他们可能就会理解编写这段代码背后的意图。 此外,如果需要任何更改,那么他们可以更自信地做到这一点,因为他们了解其中发生的一切!

    There are many different types of comments for different occasions, let’s check those out:

    针对不同场合有多种不同类型的评论,让我们检查一下:

    Legal Comments: Sometimes we developers are forced to write certain comments for legal reasons (e.g., copyright). Authorship of the code can be put at the top of each of the files.

    法律评论:有时,出于法律原因(例如,版权),我们开发人员被迫撰写某些评论。 可以将代码的作者放在每个文件的顶部。

    Informative Comments: In a line of code, we might share some information that might be taken as an assumption before writing that line of code. Putting that assumption as a piece of information before that line is a very good habit.

    内容丰富的注释:在一行代码中,我们可能会共享一些信息,这些信息可能会在编写该行代码之前作为假设。 将这一假设作为一条信息放在该行之前是一个很好的习惯。

    Explanation of Intent: We have already talked about this, and most developers are kind of aware of this sort of comment in the codebase because these explanatory comments are highly effective while refactoring or debugging codes.

    意图说明:我们已经讨论过这一点,并且大多数开发人员都知道代码库中的这种注释,因为这些注释在重构或调试代码时非常有效。

    Warning of Consequences: These might be functions or jobs which are not intended to run in a particular environment, or any warning that a developer should know/notice before running that module.

    后果警告:这些警告可能是某些功能或作业,它们不打算在特定环境中运行,或者是开发人员在运行该模块之前应了解/注意的任何警告。

    TODO Comments: You may have come across a type of comment that starts with TODO or FIXME. We developers do this to remind us that there is something left that still needs to be completed or fixed. There are some tools that generate a tree from these comments and help developers to stay accountable.

    TODO评论:您可能遇到过以TODO或FIXME开头的评论类型。 我们的开发人员这样做是为了提醒我们,还有一些尚需完成或修复的问题。 有一些工具可以根据这些注释生成一棵树,并帮助开发人员保持责任心。

    Other than these, sometimes we put comments to create auto-generated documentation for our projects. Creating documentation from code-snippets is pretty much famous in the open-source ecosystem as it helps contributors or users understand what the code does from the look of the documentation.

    除此之外,有时我们会添加注释以为项目创建自动生成的文档。 在开放源代码生态系统中,从代码片段创建文档非常有名,因为它可以帮助贡献者或用户从文档的外观中了解代码的作用。

    整理和格式化 (Linting and Formatting)

    Whatever development platform we use, they all have guidelines for code formatting which we should follow in order to maintain consistency in the codebase. Although a big team may have multiple team tracks that are working on the same repository, having some sort of code conventions applied in the repo helps to make the code clean.

    无论我们使用什么开发平台,它们都具有代码格式化准则,为了保持代码库的一致性,我们应该遵循这些准则。 尽管一个大团队可能在同一个存储库上有多个团队工作,但是在回购中应用某种代码约定有助于使代码干净。

    Linting for static code analyzing is very helpful because it automatically checks a few things on top of the rules that we set and gives alerts if we try to break any of them. For JavaScript we use ESLint, Prettier is also a popular code formatting tool in this ecosystem. In Python, we use autopep8 or black as a formatter.

    整理静态代码分析非常有用,因为它会在设置的规则之上自动检查一些内容,并在尝试破坏任何规则时发出警报。 对于JavaScript,我们使用ESLint ,更漂亮也是在这个生态系统中一个流行的代码格式化工具。 在Python中,我们使用autopep8或black作为格式化程序。

    I believe that linting and formatting should be done automatically because we are humans and so make mistakes. There is a chance of pushing unformatted code with linter errors in it to the remote repository. Using Git hooks can be very helpful in avoiding this as it allows us to do auto linting and formatting before pushing or committing any codes to the Git.

    我相信,整理和格式化应该自动完成,因为我们是人类,因此会犯错误。 有机会将其中包含linter错误的未格式化代码推送到远程存储库。 使用Git钩子对避免这种情况非常有帮助,因为它允许我们在将任何代码推送或提交到Git之前进行自动整理和格式化。

    结论 (Conclusion)

    Finally, writing clean and understandable code completely depends on the mental model of a developer. If we simply follow the boy scout rule i.e. “Leave your code better than you found it”, we can eventually end up having a codebase that is way better than before and that people love to work on. Making an effort today to improve your ability to write clean code will certainly pay off in the future, I hope that my article can play a helpful role in your software development journey.

    最后,编写清晰易懂的代码完全取决于开发人员的思维模式。 如果我们只是遵循童子军规则,即“让代码比发现的要好” ,我们最终可能会拥有比以前更好的代码库,并且人们喜欢继续工作。 今天努力提高您编写干净代码的能力肯定会在将来有所回报,我希望我的文章可以在您的软件开发过程中发挥有益的作用。

    翻译自: https://codeburst.io/how-to-keep-your-code-clean-and-easy-to-understand-25b54e7a1b49

    dll简洁易懂

    相关资源:四史答题软件安装包exe
    Processed: 0.012, SQL: 8