Contains a written down set of principles and other information on //base/util. Please add to it!
This directory is meant to house common utilities that can be shared across the whole Chromium codebase. //base is similar, but due to the way //base grew over time, it has not been well organized to allow for fine-grained ownership. Also, there is a mixture of commonly useful utility code and extremely subtle code with performance and security implications. The combination of the two lead to a small number of //base OWNERS enforcing a very high quality bar over a diverse bag of code. The goal of //base/util is to avoid both these issues. Over time, functionality in //base proper will sorted into //base/util and one of two things will occur:
We will iterate on this purpose as we add more functionality into this directory.
It is specifically NOT the OWNERS job to gatekeep what is a “good pattern” for Chromium code. Obviously they can still object, but the objection should be considered similar to any other Chromium dev objection.
There will be cases when a utility is deemed to be more negative than positive after it has been landed. The //base/util/OWNERS may aide in coordinating and tracking removal, but responsibility for actually deleting the code and its uses falls to the category OWNERS.
::utilnamespace. All implementation details should be in
::util::internal. Macros, which are not namespaceable, are permitted but should be used sparingly and cause a small pang of guilt.
At some point, //base/util directories could get moved back into //base. Until then, //base/util will
The boundary is still a work-in-progress, but should clear itself up with time after some of the more obviously “utility-esque” classes are moved.
Both //components and //base/util contain subdirectories that are (a) intended for reuse. In addition, //components imposes no global layering in Chromium, so a subdirectory placed in //components can be used from most-to-all layers in the codebase, subject to the dependencies that that subdirectory itself holds.
In spite of these similarities, there are conceptual differences: //components contains things are closer to full features or subsystems (eg autofill, heap profiler, cloud devices, visited link tracker) that are not really intended for large scale reuse.
There is some overlap and at some point it will become a judgment call, but in general, //components are a better fit if the code in question is a feature, module, or subsystem. //base/util is better if it is a more narrow construct such as a data structure, coding primitive, etc.
The Rule-of-3 is a simple guidance on when it makes sense to extract common functionality out versus duplicating it. It has commonly been used in //base as a way of measuring “how general” is this functionality.
Unfortunately, there are reasons for wanting to share code beyond just cleanliness. For example, if you need to guarantee exact behavior across two modules, duplication is not proper even if there will ever only be 2 users.
Furthermore, there is a chicken-and-egg problem that prevents incremental adoption of a utility. For example, someone introduces ThingerDoer in //foo/bar. Later, ThingerDoer is wanted in //foo/qux, but this still fails the rule-of-3 test, MyDoer is created. When //foo/waldo wants it, it‘s completely a game of chance whether or not the CL author manages to find both classes, wants to spend the time to determine if they’ve diverged, and then tries to abstract it.
As such, the rule-of-3 runs contrary to the goal of sharing that //base/util is designed to facilitate.