Sobes.tech
Middle+

Mesélj a mintázattervezésről, amit a fejlesztésed során használtál.

sobes.tech MI

Válasz az MI-től

Az alábbi tervezési mintákat használtam:

  • MVC (Model-View-Controller): Az alkalmazás logikájának szétválasztása. A modell kezeli az adatokat, a nézet felelős a megjelenítésért, a vezérlő pedig a felhasználói interakciókat kezeli, és frissíti a modellt vagy a nézetet. Angularban használtam, ahol a komponensek részben valósítják meg ezt az ideológiát.

  • MVVM (Model-View-ViewModel): Hasonló az MVC-hez, de bevezeti a ViewModel-t, mint közvetítőt a nézet és a modell között. A ViewModel tartalmazza az üzleti logikát az adatok megjelenítéséhez és a felhasználói műveletek kezeléséhez. Aktívan használtam React és Vuex (Vue) esetén, ahol az alkalmazás állapota központilag van kezelve.

    // Reaktív példa useState használatával
    import React, { useState } from 'react';
    
    function Counter() {
      const [count, setCount] = useState(0); // a useState az MVVM mechanizmus része
    
      const increment = () => {
        setCount(count + 1); // állapot frissítése a setterrel
      };
    
      return (
        <div>
          <p>Szám: {count}</p> {/* állapot megjelenítése */}
          <button onClick={increment}>Növel</button> {/* művelet, ami befolyásolja az állapotot */}
        </div>
      );
    }
    
  • Komponens mintázat: A felhasználói felületet független, újra felhasználható komponensekre bontja. Minden komponens inkapszulálja a saját logikáját, szerkezetét és stílusát. Ez a modern keretrendszerek, mint a React, Vue és Angular alapja.

    // Egyszerű React komponens példa
    function Button(props) {
      return (
        <button className="my-button" onClick={props.onClick}>
          {props.label}
        </button>
      );
    }
    
  • Adapter (Adapter): Egy osztály interfészét másikra alakítja, amit a kliensek elvárnak. Lehetővé teszi inkompatibilis interfészekkel rendelkező osztályok együttműködését. Harmadik fél könyvtárak vagy API-k integrációjára használtam, különböző metódusszignatúrákkal.

    // Adapter példa különböző API-kliensekhez
    class OldApi {
      getDataOld(id) {
        console.log(`Adatok lekérése az Old API-ból, id ${id}`);
        return { id: id, name: `Tétel ${id}` };
      }
    }
    
    class NewApi {
      fetchDataNew(itemId) {
        console.log(`Adatok lekérése az Új API-ból, tétel id ${itemId}`);
        return { itemId: itemId, label: `Termék ${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) {
          // Az adatok átalakítása az új formátumból
          const newData = this.apiClient.fetchDataNew(id);
          return { id: newData.itemId, name: newData.label };
        }
        throw new Error("Nem támogatott API kliens");
      }
    }
    
    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): Lehetővé teszi az elemek sorozatos hozzáférését anélkül, hogy feltárná belső reprezentációját. Használják ciklusokban (for...of) és tömbmetódusokban (forEach, map, filter).

    // Iterátor használatának példája JavaScriptben
    const numbers = [1, 2, 3, 4, 5];
    
    // Közvetlen iterator megszerzése
    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 }
    
    // Iterator használata for...of ciklusban
    for (const number of numbers) {
      console.log(number);
    }
    
  • Díszítő (Decorator): Dinamikusan ad hozzá új feladatokat egy objektumhoz, lehetővé téve az objektum funkcionalitásának bővítését anélkül, hogy megváltoztatná szerkezetét. Reactben HOC-ként (Higher-Order Components) vagy dekorátorokként Angular/TypeScript környezetben használtam.

    // HOC példa Reactben
    function withLogging(WrappedComponent) {
      return function WithLogging(props) {
        console.log(`A ${WrappedComponent.name} komponens renderelése, props:`, props);
        return <WrappedComponent {...props} />;
      };
    }
    
    // HOC alkalmazása
    const EnhancedButton = withLogging(Button);
    
    // Bővített komponens használata
    // <EnhancedButton label="Kattints" onClick={() => console.log('Kattintás!')} />
    
  • Singleton (Egyszemélyes): Biztosítja, hogy egy osztálynak csak egy példánya legyen, és globális hozzáférést biztosítson hozzá. Ezt alkalmaztam a globális állapot kezelésére vagy egyetlen szolgáltatás példányának létrehozására (pl. naplózás, konfiguráció).

    // Egyszemélyes minta példája
    class ConfigManager {
      constructor() {
        if (ConfigManager.instance) {
          return ConfigManager.instance;
        }
        this.settings = {}; // Beállítások inicializálása
        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 (egy és ugyanaz a példány)
    
    config1.setSetting('apiUrl', 'https://api.example.com');
    console.log(config2.getSetting('apiUrl')); // https://api.example.com
    
  • Gyármetódus (Factory Method): Meghatározza az interfészt egy objektum létrehozására, de az alosztályok döntenek arról, hogy melyik objektumot hozzák létre. Ezt alkalmaztam különböző felhasználói felület elemek vagy konfiguráció alapú objektumok létrehozására.

  • Stratégia (Strategy): Egy család algoritmusát határozza meg, mindegyiket kapszulázza, és egymással helyettesíthetővé teszi. Lehetővé teszi az algoritmus változtatását a felhasználóktól függetlenül. Ezt alkalmaztam különböző adatszortálási, űrlap-ellenőrzési vagy eseménykezelési megközelítések megvalósítására.

Ezeknek a mintáknak a használata segített strukturáltabb, modulárisabb, tesztelhetőbb és könnyebben karbantartható kód létrehozásában.