Sobes.tech
Middle+

Pověz mi o návrhovém vzoru, který jsi ve svém vývoji použil.

sobes.tech AI

Odpověď od AI

Použil jsem následující návrhové vzory:

  • MVC (Model-View-Controller): Oddělení logiky aplikace. Model spravuje data, Pohled je zodpovědný za zobrazení a Řadič zpracovává interakci uživatele a aktualizuje Model nebo Pohled. Používal jsem v Angularu, kde komponenty částečně implementují tuto filozofii.

  • MVVM (Model-View-ViewModel): Podobné MVC, ale zavádí ViewModel jako prostředníka mezi Pohledem a Modelem. ViewModel obsahuje obchodní logiku pro zobrazování dat a zpracování akcí uživatele. Aktivně jsem ho používal s Reactem a Vuex (Vue), kde je stav aplikace řízen centralizovaně.

    // Příklad reaktivity s použitím useState
    import React, { useState } from 'react';
    
    function Counter() {
      const [count, setCount] = useState(0); // useState je součástí mechanismu MVVM
    
      const increment = () => {
        setCount(count + 1); // aktualizace stavu přes setter
      };
    
      return (
        <div>
          <p>Počítadlo: {count}</p> {/* zobrazení stavu */}
          <button onClick={increment}>Zvýšit</button> {/* akce ovlivňující stav */}
        </div>
      );
    }
    
  • Komponentní vzor: Rozdělení uživatelského rozhraní na nezávislé, znovu použitelné komponenty. Každá komponenta kapsuluje svou logiku, rozvržení a styly. Je základem moderních rámců, jako jsou React, Vue a Angular.

    // Příklad jednoduché komponenty React
    function Button(props) {
      return (
        <button className="my-button" onClick={props.onClick}>
          {props.label}
        </button>
      );
    }
    
  • Adaptér (Adapter): Převádí rozhraní jedné třídy na jiné, které očekávají klienti. Umožňuje spolupráci tříd s neslučitelnými rozhraními. Používal jsem pro integraci třetích knihoven nebo API s různými signaturami metod.

    // Příklad adaptéru pro různé API klienty
    class OldApi {
      getDataOld(id) {
        console.log(`Získávání dat z Old API pro id ${id}`);
        return { id: id, name: `Položka ${id}` };
      }
    }
    
    class NewApi {
      fetchDataNew(itemId) {
        console.log(`Načítání dat z Nového API pro položku id ${itemId}`);
        return { itemId: itemId, label: `Produkt ${itemId}` };
      }
    }
    
    class ApiAdapter {
      constructor(apiClient) {
        this.apiClient = apiClient;
      }
    
      getData(id) {
        if (this.apiClient instanceof OldApi) {
          return this.apiClient.getDataOld(id);
        } else if (this.apiClient instanceof NewApi) {
          // Převod dat z nového formátu
          const newData = this.apiClient.fetchDataNew(id);
          return { id: newData.itemId, name: newData.label };
        }
        throw new Error("Nepodporovaný API klient");
      }
    }
    
    const oldApiAdapter = new ApiAdapter(new OldApi());
    console.log(oldApiAdapter.getData(1));
    
    const newApiAdapter = new ApiAdapter(new NewApi());
    console.log(newApiAdapter.getData(2));
    
  • Iterátor (Iterator): Poskytuje způsob sekvenčního přístupu k prvkům složeného objektu, aniž by odhalil jeho vnitřní reprezentaci. Používá se v cyklech (for...of) a metodách polí (forEach, map, filter).

    // Příklad použití iterátoru v JavaScriptu
    const numbers = [1, 2, 3, 4, 5];
    
    // Přímé získání iterátoru
    const iterator = numbers[Symbol.iterator]();
    
    console.log(iterator.next()); // { value: 1, done: false }
    console.log(iterator.next()); // { value: 2, done: false }
    // ...
    console.log(iterator.next()); // { value: undefined, done: true }
    
    // Použití iterátoru v for...of
    for (const number of numbers) {
      console.log(number);
    }
    
  • Dekorátor (Decorator): Dynamicky přidává nové povinnosti objektu, umožňuje rozšířit funkčnost objektu bez změny jeho struktury. Používal jsem jako HOC (Higher-Order Components) v Reactu nebo dekorátory v Angular/TypeScript.

    // Příklad HOC v Reactu
    function withLogging(WrappedComponent) {
      return function WithLogging(props) {
        console.log(`Komponenta ${WrappedComponent.name} renderována s props:`, props);
        return <WrappedComponent {...props} />;
      };
    }
    
    // Použití HOC
    const EnhancedButton = withLogging(Button);
    
    // Použití vylepšené komponenty
    // <EnhancedButton label="Klikni" onClick={() => console.log('Kliknuto!')} />
    
  • Singleton (Jedinečný): Zajišťuje, že třída má pouze jeden instance a poskytuje k němu globický přístup. Používal jsem pro správu globálního stavu nebo pro vytvoření jediného instance služby (například služby logování, konfigurace).

    // Příklad vzoru Singleton
    class ConfigManager {
      constructor() {
        if (ConfigManager.instance) {
          return ConfigManager.instance;
        }
        this.settings = {}; // Inicializace nastavení
        ConfigManager.instance = this;
      }
    
      setSetting(key, value) {
        this.settings[key] = value;
      }
    
      getSetting(key) {
        return this.settings[key];
      }
    }
    
    const config1 = new ConfigManager();
    const config2 = new ConfigManager();
    
    console.log(config1 === config2); // true (stejný instance)
    
    config1.setSetting('apiUrl', 'https://api.example.com');
    console.log(config2.getSetting('apiUrl')); // https://api.example.com
    
  • Fabrika metoda (Factory Method): Definuje rozhraní pro tvorbu objektu, ale podtřídy rozhodují, který objekt vytvořit. Používal jsem pro tvorbu různých typů prvků uživatelského rozhraní nebo objektů na základě konfigurace.

  • Strategie (Strategy): Definuje rodinu algoritmů, kapsuluje každý z nich a činí je zaměnitelnými. Umožňuje algoritmu měnit se nezávisle na klientovi, který ho používá. Používal jsem pro implementaci různých přístupů k řazení dat, validaci formulářů nebo zpracování událostí.

Použití těchto vzorů pomáhalo vytvářet strukturovanější, modulárnější, testovatelnější a udržovatelnější kód.