返回资讯中心
外部精选
软件工程
#开发者实时流

Avoid Public Functions Calling Other Public Functions

A small-scale rule of thumb. This article will land much better with a concrete

Hacker News 最新surprisetalk2026/10/29 · 3 天前8 分钟阅读

以下正文同步自 Hacker News 最新,版权归原站所有,已转换为易读排版。

A small-scale rule of thumb. This article will land much better with a concrete example, but I am drawing a blank here, so you gotta just blindly trust my say so!

When implementing a software module, it’s often a case that you are writing a public function foo, and at least part of what foo does is already handled by another public function bar. The DRY instinct encourages you to call bar() from within foo. This usually creates problems down the line. Instead, create a new private function and refactor both foo and bar to call that shared helper:

// BAD pub fn foo() void { return bar(.{ .frobnicate = true }); }

pub fn bar(options: struct { frobnicate: bool = false, }) void { // ... }

// GOOD pub fn foo() void { return helper(.frobnicate); }

pub fn bar() void { return helper(.transmogrify); }

fn helper(mode: enum { frobnicate, transmogrify }) void { // ... }

Rationale: the goal of a public API is to provide an interface that works best at the call site. If parts of public API are re-used to implement the rest of the API, then there’s a tension between making the interface convenient for the outside user and making it convenient to use from within abstraction itself. Namely, functions tend to grow optional parameters that should never be set by the user. Crucially, the parameter growth and interface degradation can happen after the original code sharing.

By proactively making the shared implementation private, the tension is defused. You still might need to tinker with helper signature until it does everything it needs to do, but, because the helper is private, this is a cheap, local change.

A notable exception to this rule of thumb are “shortcut” APIs, where a public function is defined as a commonly used chain of calls to other public functions. There, the rule is the opposite — no private calls are allowed, to make sure that it is a genuine shortcut, and not a midlayer mistake.

P.S. While researching if anyone wrote a better blog post already, I stumbled upon a fun stack overflow question, asking, paraphrasing:

I’ve heard that it is bad when a public function calls another public function. Is this really so?

The most upvoted answer explains that it is indeed bad, because this makes mocking to test a single method in isolation more complicated. Which is, imo, a natural, but horrible consequence of misguided approach to testing. You shouldn’t be mocking your methods, you should mock your IO. And, similarly, you shouldn’t test methods, but rather software functionality (unless you are building a public library with a stable API, which is a fun and important, but very narrow fraction of software development).

The accepted answer says that this recommendation makes no sense if it is not backed by an industry wide or an organizational standard. Which somehow manages to make even less sense — you shouldn’t follow the guideline rules because they are written in sanctified ink! Rather, you should apply each particular rule because of the underlying reasons that motivate the rule. Guidelines and best practices articles can concentrate lots of good reasoning in a single place, but they don’t absolve you from thinking!

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →