- Bei der Wartung einer unbekannten Codebasis verbringt man viel Zeit damit, nach Strings zu suchen
- Selbst in Projekten, die man allein geschrieben hat, muss man vieles suchen, etwa Funktionsnamen, Fehlermeldungen und Klassennamen
- Wenn die Suche nicht gut funktioniert, findet man Referenzen in der Codebasis nicht und läuft Gefahr, sie als unnötig einzustufen
- Aus solchen Situationen wurden einige Regeln abgeleitet, mit denen sich die Greppability einer Codebasis erhalten lässt
Bezeichner nicht aufspalten
- Bezeichner aufzuspalten oder dynamisch zusammenzusetzen ist keine gute Idee
- Angenommen, es gibt zwei Datenbanktabellen namens
shipping_addresses und billing_addresses; dann mag es attraktiv erscheinen, den Tabellennamen je nach Bestelltyp dynamisch zusammenzubauen
const getTableName = (addressType: 'shipping' | 'billing') => {
return `${addressType}_addresses`
}
- Das wirkt zwar DRY, ist aber schlecht für die Wartbarkeit. Wer in der Codebasis nach dem Tabellennamen
shipping_addresses sucht, könnte diese Stelle übersehen
- Es ist besser, Bezeichner fest zu codieren
- Für bessere Durchsuchbarkeit refaktorisierter Code:
const getTableName = (addressType: 'shipping' | 'billing') => {
if (addressType === 'shipping') {
return 'shipping_addresses'
}
if (addressType === 'billing') {
return 'billing_addresses'
}
throw new TypeError('addressType must be billing or shipping')
}
- Dasselbe gilt für Spaltennamen, Objektfelder und Methoden-/Funktionsnamen (in JavaScript lassen sich Methodennamen leicht dynamisch zusammenbauen)
Im gesamten Stack dieselben Namen verwenden
- Feldnamen an Anwendungsgrenzen nicht ändern, nur um einem Benennungsschema zu entsprechen
- Ein typisches Beispiel: Identifikatoren im PostgreSQL-Stil mit snake_case nach JavaScript zu holen und in camelCase umzuwandeln, ist keine gute Idee
- Das erschwert die Suche. Um alles zu finden, muss man statt nach einem String nach zwei suchen
const getAddress = async (id: string) => {
const address = await getAddressById(id)
return {
streetName: address.street_name,
zipCode: address.zip_code,
}
}
- Es ist besser, das Objekt direkt zurückzugeben
const getAddress = async (id: string) => {
return await getAddressById(id)
}
Flach ist besser als verschachtelt
- Inspiriert vom Zen of Python gilt beim Umgang mit Namespaces meist: flach ist besser als verschachtelt, ob bei Ordnern oder Objektstrukturen
- Wenn es zwei Möglichkeiten für die Struktur einer Übersetzungsdatei gibt:
{
"auth": {
"login": {
"title": "Login",
"emailLabel": "Email",
"passwordLabel": "Password",
},
"register": {
"title": "Register",
"emailLabel": "Email",
"passwordLabel": "Password",
}
}
}
{
"auth.login.title": "Login",
"auth.login.emailLabel": "Email",
"auth.login.passwordLabel": "Password",
"auth.register.title": "Login",
"auth.register.emailLabel": "Email",
"auth.register.passwordLabel": "Password",
}
- Die zweite Option ist vorzuziehen. Die Keys lassen sich leicht finden und mit
t('auth.login.title') referenzieren
- Betrachtet man die Struktur von React-Komponenten:
./components/AttributeFilterCombobox.tsx
./components/AttributeFilterDialog.tsx
./components/AttributeFilterRating.tsx
./components/AttributeFilterSelect.tsx
- Diese Struktur ist vorzuziehen gegenüber
./components/attribute/filter/Combobox.tsx
./components/attribute/filter/Dialog.tsx
./components/attribute/filter/Rating.tsx
./components/attribute/filter/Select.tsx
- Denn aus Sicht der Suche kann man so nach dem vollständigen Komponenten-Namen mit Namespace wie
AttributeFilterCombobox suchen statt nach einem allgemeinen Namen wie Dialog
Meinung von GN⁺
- Dieser Blogbeitrag erklärt sehr gut, wie wichtig die Suche nach Bezeichnern bei der Pflege einer Codebasis ist
- Bezeichner dynamisch zusammenzubauen oder Namen an Anwendungsgrenzen zu ändern, erschwert die Wartung von Code. Bezeichner sollten konsistent und eindeutig sein
- Stattdessen sind fest codierte Bezeichner und flache Namespaces aus Sicht der Durchsuchbarkeit besser
- Es lohnt sich, diese Prinzipien in Projekten anzuwenden, um Lesbarkeit und Wartbarkeit des Codes zu verbessern
- Zusätzlich zu den vom Autor vorgeschlagenen Regeln gibt es viele weitere Wege, die Codequalität zu erhöhen, etwa Self-Documenting Code und sinnvolle Kommentare
5 Kommentare
Bitte konvertiere es in den vollständigen Pfad von
json– ich lasse auch noch ein Tool da, das es greppbar macht!https://de.news.hada.io/topic?id=3159
Gut … Greppability also …
Es scheint auch nützlich zu sein, möglichst viele hilfreiche Informationen in einer einzigen Zeile unterzubringen.
Klingt gut.
Hacker-News-Kommentare
Das Suchen nach Symbolen wie Funktionsnamen und Klassennamen ist schwächer als die Verwendung von Werkzeugen, die die Syntax des Codes verstehen
Es wäre nützlich, wenn grep einen Modus für „supergroßzügige Groß-/Kleinschreibungsignorierung“ hätte
Zustimmung zum Thema Greppability
Beim Entwurf von Hamilton war es ein Ziel, Funktionsdefinitionen und ihre nachgelagerten Verwendungen leicht grepbar zu machen
„greppable“ ist kein Wort bzw. Konzept, das eigenständig oft verwendet wird
Ich habe einmal ein komplexes Beispiel mit bedingter String-Interpolation gesehen
Viele Coding-Styles und Werkzeuge halten String-Konstanten unabhängig von der Zeilenlänge in einer einzelnen Zeile
Rust, Javascript und Lisp stellen Schlüsselwörter vor Funktionsdefinitionen, was die Suche erleichtert
Ich stimme der Greppability zu, bin aber dagegen, Namen über Grenzen hinweg gleich zu halten
Gute Durchsuchbarkeit von Code ist sinnvoll, aber die Beispiele erhöhen absichtlich die Fehleranfälligkeit