paint-brush
Das zweischneidige Schwert des Atomdesignsvon@playerony
3,104 Lesungen
3,104 Lesungen

Das zweischneidige Schwert des Atomdesigns

von Paweł Wojtasiński14m2023/05/11
Read on Terminal Reader
Read this story w/o Javascript

Zu lang; Lesen

Atomic Design ist eine Methodik, die die Organisation und Strukturierung wiederverwendbarer Komponenten und Richtlinien optimiert. Es ist von der Chemie inspiriert, da es Benutzeroberflächen in ihre grundlegendsten Bausteine zerlegt und sie zu komplexeren Strukturen zusammensetzt. In dem Artikel werde ich die Anwendung dieser Prinzipien anhand eines realen Beispiels aus der von mir entwickelten App demonstrieren.
featured image - Das zweischneidige Schwert des Atomdesigns
Paweł Wojtasiński HackerNoon profile picture
0-item


Die Komplexität moderner Websites ist in den letzten Jahren deutlich gewachsen. Die gestiegene Nachfrage nach hochwertigen, branchenüblichen Designs verschärft die Herausforderungen für Frontend-Entwickler zusätzlich.


Selbst Frontend-Apps erfordern heutzutage einige architektonische Überlegungen, um den Entwicklungsprozess zu optimieren. In meinem vorherigen Artikel habe ich meine Erfahrungen bei der Implementierung des Clean-Architecture-Ansatzes in Front-End-Anwendungen während der Arbeit an meinem Nebenprojekt geteilt.


In diesem Artikel möchte ich mich eingehender mit dem Atomdesign-Ansatz befassen und dabei auf meinen Erfahrungen mit demselben Projekt aufbauen. Ich werde seine Vor- und Nachteile diskutieren und seinen Nutzen in verschiedenen Szenarien bewerten.


Hintergrundinformationen zu Designsystemen

Lassen Sie uns zunächst das Konzept eines Designsystems untersuchen. Designsysteme sind umfassende Sammlungen wiederverwendbarer Komponenten, Richtlinien und Prinzipien, die Teams in die Lage versetzen, konsistente Benutzeroberflächen über mehrere Plattformen hinweg zu entwerfen und zu entwickeln.


Sie fungieren sowohl für Designer als auch für Entwickler als zentrale Informationsquelle und stellen sicher, dass die visuellen und funktionalen Aspekte eines Produkts mit der etablierten Markenidentität übereinstimmen und dieser entsprechen. Wenn Sie daran interessiert sind, Beispiele für Designsystemimplementierungen zu erkunden, sollten Sie sich Folgendes ansehen:



Wenn Sie tiefer in das Thema Designsysteme eintauchen möchten, empfehle ich Ihnen, diesen Artikel zu lesen. Es beschreibt dieses Thema ausführlich, Details, die für uns im Rahmen dieser Arbeit nicht erforderlich sind.


Wie Atomdesign aus Designsystemen abgeleitet wird

Aufbauend auf der Grundlage von Designsystemen ist Atomic Design eine Methodik, die die Organisation und Strukturierung wiederverwendbarer Komponenten und Richtlinien rationalisiert. Atomic Design wurde von Brad Frost konzipiert und ist von der Chemie inspiriert, da es Benutzeroberflächen in ihre grundlegendsten Bausteine zerlegt und sie zu komplexeren Strukturen zusammenfügt.


Hier ist ein Bild, das die Analogie zur Chemie veranschaulicht:


Ein Beispiel für eine chemische Gleichung, die zeigt, wie sich Wasserstoff- und Sauerstoffatome zu einem Wassermolekül verbinden.



Chemische Reaktionen werden durch chemische Gleichungen dargestellt, die oft zeigen, wie sich atomare Elemente zu Molekülen verbinden. Im obigen Beispiel sehen wir, wie sich Wasserstoff und Sauerstoff zu Wassermolekülen verbinden.



Im Wesentlichen ist Atomic Design eine natürliche Weiterentwicklung von Designsystemen und bietet einen systematischen Ansatz zur Erstellung flexibler und skalierbarer Komponenten. Durch die Anwendung der Prinzipien des Atomic Design können Teams ihre Designsysteme effizienter verwalten, da der modulare Charakter dieser Methodik die Wartung, Aktualisierung und Erweiterung der Komponenten und Muster innerhalb des Systems erleichtert.


Wenn Sie befürchten, dass dies komplex klingen könnte, machen Sie sich keine Sorgen. In den kommenden Abschnitten werde ich anhand eines realen Beispiels aus der von mir entwickelten App demonstrieren, wie Sie diese Prinzipien anwenden, damit Sie sie leicht verstehen und in Ihren eigenen Projekten umsetzen können.


Überblick über Atomdesign

Das atomare Design organisiert Komponenten in fünf verschiedene Ebenen, die jeweils auf der vorherigen aufbauen. Lassen Sie uns diese fünf Ebenen im Detail untersuchen:


  • Atome : Atome sind die grundlegendsten Bausteine einer Benutzeroberfläche und repräsentieren einzelne HTML-Elemente wie Schaltflächen, Eingabefelder und Überschriften. Sie sind die kleinsten Funktionseinheiten und können nicht weiter zerlegt werden.


  • Moleküle : Moleküle entstehen durch die Kombination von zwei oder mehr Atomen zu einer funktionellen Gruppe. Beispielsweise könnte ein Suchformularmolekül aus einem Sucheingabeatom, einem Schaltflächenatom und einem Beschriftungsatom bestehen. Moleküle stellen einfache Komponenten dar, die im gesamten Projekt wiederverwendet werden können.


  • Organismen : Organismen sind komplexere Bestandteile, die durch die Kombination mehrerer Moleküle und/oder Atome entstehen. Sie stellen unterschiedliche Abschnitte einer Benutzeroberfläche dar, beispielsweise eine Kopfzeile, eine Fußzeile oder eine Seitenleiste. Organismen helfen dabei, das Gesamtlayout und die Struktur einer Seite zu gestalten.


  • Vorlagen : Vorlagen sind im Wesentlichen Seitenlayouts, die aus Organismen, Molekülen und Atomen erstellt wurden. Sie definieren die Struktur und Anordnung der Komponenten auf einer Seite, ohne konkrete Inhalte anzugeben, und dienen als Blaupause für verschiedene Inhaltsszenarien.


  • Seiten : Seiten sind die endgültigen, vollständig realisierten Instanzen von Vorlagen, komplett mit echten Inhalten und Daten. Sie stellen dar, was Benutzer letztendlich sehen und mit was sie interagieren werden, und zeigen, wie sich die Komponenten und das Layout an verschiedene Inhaltstypen und Anwendungsfälle anpassen.



Beim Atomic Design arbeiten Atome, Moleküle, Organismen, Vorlagen und Seiten gleichzeitig zusammen, um effektive Interface-Design-Systeme zu schaffen.


Die NotionLingo-App: eine Fallstudie

Um eine fundierte Perspektive auf Atomic Design für die Frontend-Entwicklung zu entwickeln, begab ich mich auf die Reise, eine Anwendung zu erstellen. Über einen Zeitraum von sechs Monaten habe ich bei der Arbeit an diesem Projekt wertvolle Erkenntnisse und Erfahrungen gesammelt.


Daher basieren die in diesem Artikel bereitgestellten Beispiele auf meiner praktischen Erfahrung mit der Anwendung. Um die Transparenz zu wahren, sind alle Beispiele aus öffentlich zugänglichem Code abgeleitet.


Sie können das Endergebnis erkunden, indem Sie das Repository oder die Website selbst besuchen.


Denken Sie daran, dass ich in React codierte Beispiele verwenden werde. Wenn Sie mit dieser Sprache nicht vertraut sind, machen Sie sich keine Sorgen – mein Ziel ist es, die grundlegenden Konzepte des Atomdesigns zu veranschaulichen, anstatt mich auf die kleinsten Details des Codes zu konzentrieren.


Atome

Um ein besseres Verständnis der Komponenten in meinem Repository zu erhalten, finden Sie diese im folgenden Verzeichnis: /client/presentation . An diesem Ort habe ich ein neues Verzeichnis mit dem Namen atoms erstellt, um eine konsistente Benennung mit der Atomic-Design-Methodik sicherzustellen. Dieses neue Verzeichnis enthält alle kleinen Teile, die zum Aufbau des gesamten Onboarding-Prozesses erforderlich sind.


Die vollständige Liste der Atome lautet wie folgt:

 atoms ├── box ├── button ├── card ├── card-body ├── card-footer ├── container ├── divider ├── flex ├── form-control ├── form-error-message ├── form-helper-text ├── form-label ├── heading ├── icon ├── input ├── list ├── list-icon ├── list-item ├── spinner ├── tab ├── tab-list ├── tab-panel ├── tab-panels ├── tabs └── text



Diese Atomnamen kommen Ihnen möglicherweise bekannt vor, da sie auf dem Chakra-UI- Paket basieren. Die meisten von ihnen enthalten bereits den Standard-Matching-Stil für meine Anwendung, daher gibt es auf dieser Ebene nichts besonders Einzigartiges zu beschreiben. Vor diesem Hintergrund können wir direkt mit der Diskussion der molecules fortfahren.


Moleküle

In diesem Stadium wird der atomare Designprozess interessanter und seine wahre Leistungsfähigkeit beginnt sich zu offenbaren. Während die Definition Ihrer Basisatome möglicherweise eine zeitaufwändige und eintönige Aufgabe war, macht der Bau neuer Komponenten mithilfe von Atomen viel mehr Spaß.


Um die Moleküle zu definieren, habe ich in meinem Verzeichnis /client/presentation ein molecules erstellt. Die vollständige Liste der erforderlichen Moleküle lautet wie folgt:


 molecules ├── available-notion-database ├── full-screen-loader ├── input-control ├── onboarding-step-layout └── onboarding-tab-list


Tatsächlich verfügen wir mit nur fünf Molekülen über genügend Komponenten, um unser Ziel zu erreichen. Es ist wichtig zu beachten, dass dies auch ein idealer Ort ist, um gemeinsame Layouts einzubinden, die auf anderen Atomen basieren. Beispielsweise wird das onboarding-step-layout genutzt, um in allen fünf Schritten des Onboarding-Prozesses ein einheitliches Erscheinungsbild zu gewährleisten.


Die anderen Komponenten sind wie folgt:


  • available-notion-database : Wird verwendet, um die Datenbankdetails des abgerufenen Benutzers anzuzeigen (Benutzer können über mehrere Datenbanken verfügen, daher biete ich in Schritt 4 die Möglichkeit, eine auszuwählen).


    Die Komponente wird auf der Benutzeroberfläche wie folgt angezeigt:


VerfügbareNotionDatabase-Komponente mit Header- und Basisinformationen zur Notion-Datenbank.


  • full-screen-loader : Wird ganz am Anfang verwendet, wenn ich Benutzerdetails abrufe, um zu überprüfen, ob der Benutzer die Notion-Integration bereits definiert hat oder nicht. Der Code für diese Komponente sieht folgendermaßen aus:


 import { FC } from 'react'; import { Flex, Spinner } from '@presentation/atoms'; import { FullScreenLoaderProps } from './full-screen-loader.types'; export const FullScreenLoader: FC<FullScreenLoaderProps> = ({ children, ...restProps }): JSX.Element => ( <Flex alignItems="center" bg="gray.50" height="full" justifyContent="center" left={0} position="fixed" top={0} width="full" zIndex="9999" {...restProps} > <Spinner /> {children} </Flex> );


Hier gibt es keine Raketenwissenschaft. Dies ist lediglich eine Kombination der bereits definierten flex und spinner Atome.


  • input-control : Ein Wrapper für das input mit form-label , form-control , form-error-label und spinner , um anzuzeigen, ob eine Hintergrundaktion stattfindet. Die Komponente wird auf der Benutzeroberfläche wie folgt angezeigt:


InputControl-Komponente mit der Bezeichnung.


  • onboarding-tab-list : Dies ist im Grunde eine Schrittkomponente, aber in meinem Fall verwende ich Chakra-UI- Registerkarten für die Navigation, daher kommt der Name. Die Komponente sieht folgendermaßen aus:


Die OnboardingTabList-Komponente wird verwendet, um den Fortschritt im Onboarding-Prozess anzuzeigen.


Da nun weitere Teile fertig sind, können wir mit der Definition größerer Blöcke in unserem Design-Puzzle fortfahren.


Organismen

In diesem Abschnitt erstelle ich jede Komponente, die für die Anzeige jedes Schritts des Onboarding-Prozesses verantwortlich ist.


Zur Verdeutlichung zeige ich Ihnen nur die Liste der geschaffenen Organismen:


 organisms ├── onboarding-step-one ├── onboarding-step-two ├── onboarding-step-three ├── onboarding-step-four └── onboarding-step-five



Ich glaube, dass die Namen selbsterklärend sind und es keine Missverständnisse geben sollte. Um zu veranschaulichen, wie ich alles zusammenfüge, stelle ich den Code eines Schritts als Beispiel vor. Wenn Sie mehr erfahren möchten, besuchen Sie natürlich einfach mein Repository .



 export const OnboardingStepFour: FC<OnboardingStepFourProps> = ({ onBackButtonClick, onNextButtonClick, }): JSX.Element => { const { hasApiTokenData, isSetApiTokenLoading, setApiToken, setApiTokenError } = useSetApiToken(); const handleInputChange = debounce(async (event: ChangeEvent<HTMLInputElement>) => { const result = await setApiToken(event.target.value); if (result) { onNextButtonClick(); } }, 1000); return ( <OnboardingStepLayout subtitle="Paste your copied integration token below to validate your integration." title="Validate your integration" onBackButtonClick={onBackButtonClick} > <InputControl isRequired errorMessage={setApiTokenError || undefined} isDisabled={isSetApiTokenLoading || hasApiTokenData} isLoading={isSetApiTokenLoading} label="Integration token" name="integrationToken" placeholder="Your integration token" onChange={handleInputChange} /> </OnboardingStepLayout> ); };



Dieser Code ist vollständig für die Anzeige von Schritt vier in meinem Onboarding-Prozess verantwortlich. Ich glaube, die einzige Sorge, die Sie haben könnten, besteht darin, Anfragen in Organismen zu stellen. Ist das akzeptabel? Es gibt keine allgemeingültige Antwort, und ich muss auf diese Bedenken mit „Es kommt darauf an“ antworten. Es hängt von Ihrer Struktur ab.


Wenn die Einbindung eines API-Aufrufs in ein Molekül oder einen Organismus im Kontext Ihrer Anwendung sinnvoll ist und die Komponente nicht übermäßig kompliziert, kann dies eine akzeptable Lösung sein. Achten Sie nur darauf, dass Präsentationskomponenten nicht zu eng mit dem Datenabruf oder der Geschäftslogik verknüpft werden, da dies die Wartung und das Testen erschweren kann.


In meinem Szenario wird diese Komponente an einer Stelle verwendet, und andere Lösungen zum Durchführen eines API-Aufrufs in diesem Szenario sind komplexer und erzeugen möglicherweise viel mehr Code als nötig.


Vorlagen

In dieser Phase liegt der Fokus eher auf der Struktur und Anordnung der Komponenten als auf den feineren Details der Benutzeroberfläche. Mithilfe von Vorlagen lässt sich außerdem ermitteln, wo die Statusverwaltung angesiedelt sein sollte, normalerweise in den Seitenkomponenten, die die Vorlagen verwenden.


Im bereitgestellten Codebeispiel haben wir eine Onboarding Komponente, die als Vorlage dient:


 import { FC } from 'react'; import { Flex, Heading, TabPanels, Tabs, Text } from '@presentation/atoms'; import { OnboardingTabList } from '@presentation/molecules'; import { OnboardingStepFive, OnboardingStepFour, OnboardingStepOne, OnboardingStepThree, OnboardingStepTwo, } from '@presentation/organisms'; import { OnboardingProps } from './onboarding.types'; export const Onboarding: FC<OnboardingProps> = ({ activeTabs, createNotionIntegrationTabRef, displayCreateNotionIntegrationTab, displaySelectNotionDatabaseTab, displayShareDatabaseIntegrationTab, displayValidateIntegrationTab, displayVerifyDatabaseTab, selectNotionDatabaseTabRef, shareDatabaseIntegrationTabRef, validateIntegrationTabRef, verifyDatabaseTabRef, }) => ( <Flex direction="column" overflowX="hidden" px={2} py={{ base: '20px', sm: '25px', md: '55px' }}> <Flex direction="column" textAlign="center"> <Heading color="gray.700" fontSize={{ base: 'xl', sm: '2xl', md: '3xl', lg: '4xl' }} fontWeight="bold" mb="8px" > Configure your Notion integration </Heading> <Text withBalancer color="gray.400" fontWeight="normal"> This information will let us know from which Notion database we should use to get your vocabulary. </Text> </Flex> <Tabs isLazy display="flex" flexDirection="column" mt={{ base: '10px', sm: '25px', md: '35px' }} variant="unstyled" > <OnboardingTabList activeTabs={activeTabs} createNotionIntegrationTabRef={createNotionIntegrationTabRef} selectNotionDatabaseTabRef={selectNotionDatabaseTabRef} shareDatabaseIntegrationTabRef={shareDatabaseIntegrationTabRef} validateIntegrationTabRef={validateIntegrationTabRef} verifyDatabaseTabRef={verifyDatabaseTabRef} /> <TabPanels maxW={{ md: '90%', lg: '100%' }} mt={{ base: '10px', md: '24px' }} mx="auto"> <OnboardingStepOne onNextButtonClick={displayCreateNotionIntegrationTab} /> <OnboardingStepTwo onBackButtonClick={displayVerifyDatabaseTab} onNextButtonClick={displayShareDatabaseIntegrationTab} /> <OnboardingStepThree onBackButtonClick={displayCreateNotionIntegrationTab} onNextButtonClick={displayValidateIntegrationTab} /> {activeTabs.validateIntegration ? ( <OnboardingStepFour onBackButtonClick={displayShareDatabaseIntegrationTab} onNextButtonClick={displaySelectNotionDatabaseTab} /> ) : null} {activeTabs.selectNotionDatabase ? ( <OnboardingStepFive onBackButtonClick={displayVerifyDatabaseTab} /> ) : null} </TabPanels> </Tabs> </Flex> );



Diese Onboarding Komponente setzt Atome, Moleküle und Organismen zusammen, um das Layout für den Onboarding-Prozess zu erstellen. Beachten Sie, dass die Statusverwaltung und die Tab-Navigationslogik von dieser Komponente getrennt wurden. Die notwendigen Status- und Rückruffunktionen werden nun als Requisiten empfangen, sodass eine übergeordnete „Seiten“-Komponente die Status- und Datenverwaltung übernehmen kann.


Durch diese Trennung der Belange bleibt die Vorlage auf Layout und Struktur ausgerichtet und stellt gleichzeitig sicher, dass die Statusverwaltung auf der entsprechenden Ebene erfolgt.


Abschließend möchte ich Schritt 4 als Endergebnis vorstellen:


Schritt 4 des Onboarding-Prozesses in der NotionLingo-Fallstudienanwendung.


Seiten

Im Kontext unserer vorherigen Diskussion verwendet die „Seite“-Komponente die Onboarding Vorlage und übernimmt die Statusverwaltung für den Onboarding-Prozess. Obwohl der Code für diese spezielle Seitenkomponente hier nicht bereitgestellt wird, können Sie ihn in meinem Repository finden. Wie bereits erwähnt, ist am Code der Seitenkomponente nichts Außergewöhnliches; Es konzentriert sich hauptsächlich auf die Verwaltung des Status und die Weitergabe an die Onboarding Vorlage.


Schauen wir uns an, wie Atomdesign in der Praxis aussieht. Lassen Sie uns die Vor- und Nachteile dieses Ansatzes untersuchen.


Keine Rose ohne Dornen

Während Atomic Design zahlreiche offensichtliche Vorteile wie Modularität, Wiederverwendbarkeit und Wartbarkeit bietet, bringt es auch einige Nachteile mit sich, die es zu Beginn zu bedenken lohnt:


  • Ersteinrichtung und Komplexität : Atomic Design erfordert eine gut geplante Struktur und Organisation, deren Einrichtung zunächst zeitaufwändig und schwierig sein kann. Es kann auch zu zusätzlicher Komplexität Ihrer Codebasis führen, insbesondere bei kleineren Projekten, bei denen ein derart granularer Ansatz möglicherweise nicht erforderlich ist.


  • Lernkurve : Für Entwickler, die neu im Atomdesign sind, kann die Methodik eine steile Lernkurve haben. Es erfordert ein solides Verständnis der verschiedenen Niveaus und ihrer Zusammenhänge, was für Anfänger überwältigend sein kann.


  • Overhead : Die Implementierung von Atomic Design kann die Erstellung einer großen Anzahl kleiner, spezialisierter Komponenten erfordern. Dies kann zu einem erhöhten Aufwand bei der Verwaltung und Wartung dieser Komponenten führen, insbesondere wenn eine Komponente nur in einem bestimmten Kontext verwendet wird.


  • Risiko von Over-Engineering : Da der Schwerpunkt auf der Erstellung wiederverwendbarer und modularer Komponenten liegt, besteht die potenzielle Gefahr von Over-Engineering, bei dem Entwickler möglicherweise zu viel Zeit damit verbringen, einzelne Komponenten zu verfeinern, anstatt sich auf die breitere Anwendung zu konzentrieren.


  • Kommunikation und Zusammenarbeit : Der Erfolg des Atomdesigns hängt von einer klaren Kommunikation und Zusammenarbeit zwischen Designern, Entwicklern und anderen Interessengruppen ab. Wenn es nicht gelingt, eine gemeinsame Sprache oder ein gemeinsames Verständnis der Methodik zu etablieren, kann dies zu Verwirrung und Inkonsistenzen bei der Umsetzung führen.


Allerdings hat dieser Ansatz seine eigenen, bereits erwähnten Stärken. Lassen Sie uns genauer darüber sprechen:


  • Skalierbarkeit : Durch die Zerlegung des Designs in die grundlegendsten Elemente wurde der Aufbau der Komplexität der Komponenten zu einer leichter zu bewältigenden Aufgabe. Während die Herstellung von Atomen einige Herausforderungen mit sich brachte, hat die Herstellung aller auf diesen Atomen basierenden Komponenten äußerst viel Spaß gemacht.


  • Effizienz : Die Fähigkeit, Atome, Moleküle und Organismen wiederzuverwenden, verkürzt den Zeitaufwand für das Design und die Entwicklung neuer Funktionen erheblich. Sobald die Basiskomponenten festgelegt sind, kann die Erstellung neuer Schnittstellen so einfach sein wie das Kombinieren vorhandener Elemente.


  • Konsistenz : kommt direkt aus dem vorherigen Punkt. Da in mehreren Vorlagen und Seiten dieselben Atome, Moleküle und Organismen verwendet werden, bleibt die Benutzeroberfläche einheitlich und bietet Benutzern ein nahtloses Erlebnis.


  • Dokumentation : Atomic Design unterstützt von Natur aus die Dokumentation. Die atombasierte Struktur kann als klarer, visueller Leitfaden dafür dienen, wie Komponenten gebaut und verwendet werden sollten. Dies kann besonders beim Onboarding neuer Teammitglieder hilfreich sein.


  • Wartbarkeit : Eine der größten Stärken des Atomdesigns besteht darin, wie es zur Wartbarkeit eines Designsystems beiträgt. Indem alles in seine atomaren Teile zerlegt wird, können alle Änderungen oder Aktualisierungen auf atomarer Ebene vorgenommen und dann im System verbreitet werden. Wenn Sie beispielsweise die Farbe einer Schaltfläche ändern möchten, müssen Sie diese Änderung nur einmal auf Atomebene vornehmen und sie wird auf alle Moleküle, Organismen und Vorlagen übertragen, in denen diese Schaltfläche verwendet wird. Dies vereinfacht den Prozess der Aktualisierung und Wartung des Designsystems im Laufe der Zeit erheblich.


Abschluss

Zusammenfassend lässt sich sagen, dass das Atomdesign zwar wie ein zweischneidiges Schwert erscheint – ein wenig entmutigend in Bezug auf die anfängliche Einrichtung und die Lernkurve –, aber seine potenziellen Vorteile sind den anfänglichen Kampf durchaus wert. Und denken Sie daran, selbst die beeindruckendsten Schwerter sind in den Händen eines erfahrenen Ritters harmlos!