为什么是“明确性”?被认为是一件好事吗?

发布于 2024-08-15 01:45:01 字数 134 浏览 5 评论 0原文

我经常听到人们称赞语言、框架、构造等“明确”。我正在尝试理解这个逻辑。语言、框架等的目的是隐藏复杂性。如果它让你明确指定各种细节,那么它并没有隐藏太多复杂性,只是移动它。显式性有什么好处?如何使语言/框架/API“显式”,同时仍使其达到隐藏复杂性的目的?

I often hear people praise languages, frameworks, constructs, etc. for being "explicit". I'm trying to understand this logic. The purpose of a language, framework, etc. is to hide complexity. If it makes you specify all kinds of details explicitly, then it's not hiding much complexity, only moving it around. What's so great about explicitness and how do you make a language/framework/API "explicit" while still making it serve its purpose of hiding complexity?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

为你拒绝所有暧昧 2024-08-22 01:45:01

应该明确还是隐含取决于具体情况。你是对的,因为你经常试图隐藏复杂性,并且在幕后自动为你完成某些事情是好的。有时

,虽然框架或构造向我们隐藏了它们不应该看到的东西,但这使得事情不太变得清晰。有时某些信息或设置对我们隐藏,因此我们不知道发生了什么。我们不理解也无法确定的假设。行为的发生是我们无法预测的。

封装性:良好。隐藏:不好。做出正确的决定需要经验。逻辑所在的地方应该是明确的。

示例:我曾经从一系列十几个代码隐藏页面中删除了大约 90 行代码;数据访问代码、业务逻辑等不属于那里。我将它们移至基本页面和关键业务对象。这是(封装、关注点分离、代码组织、解耦等)。

然后我兴奋地意识到我可以从许多页面中删除最后一行代码,将其移动到基页面。这是一行从 url 获取参数并将其传递给业务对象的行。很好,对吧?嗯,不,这糟糕(我躲起来)。这个逻辑属于这里,尽管每一页上几乎都是同一行。它将 UI 意图与业务对象联系起来。它需要明确。否则我是在隐藏,而不是封装。有了这句话,查看该页面的人就会知道该页面做了什么以及为什么;如果没有它,确定发生了什么将会很痛苦。

Whether you should be explicit or implicit depends on the situation. You are correct in that often you are trying to hide complexity, and certain things being done behind the scenes for you automatically is good. encapsulation, etc.

Sometimes though frameworks or constructs hide things from us that they should not, and this makes things less clear. Sometimes certain information or settings are hidden from us and hence we don't know what's happening. Assumptions are made that we don't understand and can't determine. Behaviors happen that we can't predict.

Encapsulation: good. Hiding: bad. Making the right call takes experience. Where logic belongs, it should be explicit.

Example: I once removed about 90 lines of code from a series of a dozen code behind pages; data access code, business logic, etc., that did not belong there. I moved them to base pages and the key business object. This was good (encapsulation, separation of concerns, code organization, decoupling, etc.).

I then excitedly realized that I could remove the last line of code from many of these pages, moving it to the base page. It was a line that took a parameter from url and passed it to the business object. Good, right? Well, no, this was bad (I was hiding). This logic belonged here, even though it was almost the same line on every page. It linked the UI intention with the business object. It need to be explicit. Otherwise I was hiding, not encapsulating. With that line, someone looking at that page would know what that page did and why; without it, it would be a pain to determine what was going on.

独自唱情﹋歌 2024-08-22 01:45:01

我认为显式指的是当你使用它时确切地知道它在做什么。这与确切地知道它是如何完成的不同,后者是复杂的部分。

I believe that explicit refers to knowing exactly what it is doing when you use it. That is different from knowing exactly how it's done, which is the complex part.

对岸观火 2024-08-22 01:45:01

与其说显式是好的(当然,密切相关的详细是不好的),不如说当隐式出错时,很难纠正。告诉WTF 发生了什么事。

Hack C++ 一两年,你就会明白我的意思。

It's not so much that explicit is good (certainly the closely-related verbose is bad) as that when implicit goes wrong, it's so hard to tell WTF is going on.

Hack C++ for a decade or two and you'll understand exactly what I mean.

简美 2024-08-22 01:45:01

这是关于表达意图。读者无法判断默认值是由于错误还是有意而为之。明确地消除了这种疑虑。

It is about expressing intentions. The reader can't tell if the default was left by mistake or by design. Being explicit removes that doubt.

情场扛把子 2024-08-22 01:45:01

代码读起来比写起来更难。在重要的应用程序中,一段给定的代码的读取频率也将高于其写入频率。因此,我们编写的代码应该让读者尽可能容易理解。做了很多不明显的事情的代码不容易阅读(或者更确切地说,当你阅读它时很难理解)。因此,明确性被认为是一件好事。

Code is harder to read than to write. In nontrivial applications, a given piece of code will also be read more often than it is written. Therefore, we should write our code to make it as easy on the reader as possible. Code that does a lot of stuff that isn't obvious is not easy to read (or rather, it's hard to understand when you read it). Ergo, explicitness is considered a good thing.

倾听心声的旋律 2024-08-22 01:45:01

依赖默认行为会向不熟悉该语言/框架/其他内容的人隐藏重要细节。

考虑一下对于不了解 Perl 的人来说,广泛依赖速记的 Perl 代码是如何难以理解的。

Relying on default behaviour hides important details from people who aren't intimately familiar with the language/framework/whatever.

Consider how Perl code which relies extensively on shorthands is difficult to understand for people who don't know Perl.

墨落成白 2024-08-22 01:45:01

显式与隐式的区别在于你隐藏什么,以及你展示什么。

理想情况下,您公开用户关心或必须关心(无论他们是否愿意)的概念。

明确的优点是更容易追踪并找出正在发生的事情,尤其是在失败的情况下。例如,如果我想进行日志记录,我可以拥有一个需要使用日志目录进行显式初始化的 API。或者,我可以使用默认值。

如果我给出一个明确的目录,并且失败,我会知道原因。如果我使用隐式路径,并且失败了,我将不知道出了什么问题,为什么,或者在哪里修复它。

隐性行为几乎总是向消费者隐藏信息的结果。有时这是正确的做法,例如当您知道在您的环境中只有一个“答案”时。但是,最好知道何时隐藏信息以及隐藏信息的原因,并确保让消费者更接近他们的意图,而不是试图隐藏本质复杂的项目。

通常隐式行为是“自配置”对象的结果,这些对象查看其环境并尝试猜测正确的行为。我一般会避免这种模式。

我可能总体上遵循的一条规则是,对于给定的 API,任何操作都应该是显式的或隐式的,但绝不是组合。要么使操作成为用户必须执行的操作,要么使操作成为用户不必考虑的操作。当你将这两者混合在一起时,你就会遇到最大的问题。

Being explicit vs. implicit is all about what you hide, and what you show.

Ideally, you expose concepts that either the user cares about, or has to care about (whether they want to or not).

The advantage of being explicit is that it's easier to track down and find out what's going on, especially in case of failure. For instance, if I want to do logging, I can have an API that requires explicit initialization with a directory for the log. Or, I can use a default.

If I give an explicit directory, and it fails, I'll know why. If I use an implicit path, and it fails, I will have no idea of what has gone wrong, why, or where to look to fix it.

Implicit behavior is almost always a result of hiding information from the consumer. Sometimes that's the right thing to do, such as when you know in your environment there's only one "answer". However, it's best to know when you're hiding information and why, and ensure that you're letting your consumers work closer to their level of intent, and without trying to hide items of essential complexity.

Frequently implicit behavior is a result of "self-configuring" objects that look at their environment and try to guess the correct behavior. I'd avoid this pattern in general.

One rule I'd probably follow overall is that, for a given API, any operation should either be explicit, or implicit, but never a combination. Either make the operation something the user has to do, or make it something they don't have to think about. It's when you mix those two that you will run into the biggest problems.

Smile简单爱 2024-08-22 01:45:01

框架等可以是显式的,也可以通过为要完成的工作提供正确的抽象来隐藏复杂性。

明确可以让其他人检查并理解原始开发人员的含义。

隐藏复杂性并不等于隐式。隐式会导致代码只有编写者才能理解,因为在这种情况下,试图理解幕后发生的事情类似于逆向工程。

显式代码理论上有机会被证明是正确的。隐式代码在这方面永远没有机会。

显式代码是可维护的,隐式代码则不然——这链接到提供正确的注释并谨慎选择标识符。

Frameworks, etc., can be both explicit and hide complexity by offering the right abstractions for the job to be done.

Being explicit allows others to inspect and understand what is meant by the original developer.

Hiding complexity is not equivalent with being implicit. Implicitness would result in code that is only understandable by the person who wrote it as trying to understand what goes on under the hood is akin to reverse engineering in this case.

Explicit code has a theoretical chance of being proved correct. Implicit code never stands a chance in this respect.

Explicit code is maintainable, implicit code is not - this links to providing correct comments and choosing your identifiers with care.

雪若未夕 2024-08-22 01:45:01

“显式”语言允许计算机发现软件中的错误,而不太显式的语言则不能。

例如,C++ 有 const 关键字来表示其值永远不会改变的变量。如果程序尝试更改这些变量,编译器可以指出代码可能是错误的。

An "explicit" language allows the computer to find bugs in software that a less-explicit language does not.

For example, C++ has the const keyword for variables whose values should never change. If a program tries to change these variables, the compiler can state that the code is likely wrong.

爱殇璃 2024-08-22 01:45:01

良好的抽象不会隐藏复杂性,它会将最好留给编译器的决策从您的手中转移出去。

考虑垃圾收集:释放资源的复杂性被委托给垃圾收集器,垃圾收集器(大概)比程序员更有资格做出决定。它不仅让你不再做决定,而且做出了比你自己更好的决定。

明确性(有时)是好的,因为它使得在某些情况下最好留给程序员的某些决定不会由不合格的代理自动做出。一个很好的例子是,当您在 C 类型语言中声明浮点数据类型并将其初始化为整数时:

double i = 5.0;

如果您将其声明为

var i = 5;

编译器会正确地假设您想要一个 int 并且稍后的操作将是被截断。

Good abstraction doesn't hide complexities, it takes decisions that are best left to the compiler off of your plate.

Consider garbage collection: The complexities of releasing resources are delegated to a garbage collector which is (presumably) better qualified to make a decision than you, the programmer. Not only does it take the decision off your hands, but it makes a better decision than you would have yourself.

Explicitness is (sometimes) good because it makes it so that certain decisions that in some cases are better left to the programmer are not automatically made by a less qualified agent. A good example is when you're declaring a floating point data type in a c-type language and initializing it to an integer:

double i = 5.0;

if instead you were to declare it as

var i = 5;

the compiler would rightfully assume you want an int and operations later on would be truncated.

悟红尘 2024-08-22 01:45:01

为了让代码的读者清楚你想要做什么,明确性是可取的。

例子有很多,但都是为了让你的意图毫无疑问。

例如,这些不是很明确:

while (condition);

int MyFunction()

bool isActive;         // In C# we know this is initialised to 0 (false)

a = b??c;

double a = 5;

double angle = 1.57;

但这些是:

while (condition)
    /* this loop does nothing but wait */ ;

private int MyFunction()

int isActive = false;  // Now you know I really meant this to default to false

if (b != null) a = b; else a = c;

double a = 5.0;

double angleDegrees = 1.57;

后一种情况没有留下任何误解的余地。当有人未​​能仔细阅读它们,或者无法清楚地理解执行某些操作时可读性较差的语法,或者混合了整数和浮点类型时,前者可能会导致错误。

Explicitness is desirable in the context of making it clear to the reader of your code what you intended to do.

There are many examples, but it's all about leaving no doubt about your intent.

e.g. These are not very explicit:

while (condition);

int MyFunction()

bool isActive;         // In C# we know this is initialised to 0 (false)

a = b??c;

double a = 5;

double angle = 1.57;

but these are:

while (condition)
    /* this loop does nothing but wait */ ;

private int MyFunction()

int isActive = false;  // Now you know I really meant this to default to false

if (b != null) a = b; else a = c;

double a = 5.0;

double angleDegrees = 1.57;

The latter cases leave no room for misinterpretation. The former might lead to bugs when someone fails to read them carefully, or doesn't clearly understand a less readable syntax for doing something, or mixes up integer and float types.

千寻… 2024-08-22 01:45:01

在某些情况下,相反的情况是“神奇的” - 如“然后奇迹发生了”

当开发人员阅读代码试图理解或调试正在发生的事情时,明确性可能是一种美德。

In some cases the opposite is "magic" - as in "then a miracle occurs".

When a developer's reading code trying to understand or debug what's going on, explicitness can be a virtue.

吲‖鸣 2024-08-22 01:45:01

框架移动事物的目的是消除代码中的重复并允许更轻松地编辑块而不破坏整个事物。
当你只有一种方法来做某事时,比如 SUM(x,y);
我们确切地知道这将要做什么,没有理由需要重写它,如果你必须的话,你可以,但这极不可能。
与此相反的是 .NET 等编程语言,它们提供非常复杂的函数,如果您执行除明显简单示例之外的其他操作,通常需要重写这些函数。

The purpose of frameworks moving things around is to remove duplication in code and allow easier editing of chunks without breaking the whole thing.
When you have only one way of doing something, like say SUM(x,y);
We know exactly what this is going to do, no reason to ever need to rewrite it, and if you must you can, but its highly unlikely.
The opposite of that is programming languages like .NET that provide very complex functions that you often will need to rewrite if your doing anything but the obvious simple example.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文