Sobes.tech
Middle+

Papaskinkite apie šabloninio projektavimo, kurį naudojote savo plėtroje.

sobes.tech AI

Atsakymas iš AI

Naudoti šie projektavimo modeliai:

  • MVC (Model-View-Controller): Programos logikos atskyrimas. Modelis valdo duomenis, Vaizdas atsako už atvaizdavimą, o Valdiklis apdoroja naudotojo sąveiką ir atnaujina Modelį arba Vaizdą. Naudota Angular, kur komponentai iš dalies įgyvendina šią idėją.

  • MVVM (Model-View-ViewModel): Panašus į MVC, bet įveda ViewModel kaip tarpininką tarp Vaizdo ir Modelio. ViewModel turi verslo logiką duomenų atvaizdavimui ir naudotojo veiksmų apdorojimui. Aktyviai naudota React ir Vuex (Vue), kur programos būsena valdomas centralizuotai.

// Reaktyvumo pavyzdys React su useState
import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0); // useState - MVVM dalis

  const increment = () => {
    setCount(count + 1); // Būsenos atnaujinimas su setter
  };

  return (
    <div>
      <p>Count: {count}</p> {/* Būsenos rodymas */}
      <button onClick={increment}>Increment</button> {/* Veiksmas, paveikiantis būseną */}
    </div>
  );
}

Komponento modelis: vartotojo sąsajos padalijimas į nepriklausomas, pernaudojamas komponentus. Kiekvienas komponentas įsikapsuliuoja savo logiką, maketą ir stilių. Tai šiuolaikinių framework'ų pagrindas, tokių kaip React, Vue ir Angular.

// Paprasto React komponento pavyzdys
function Button(props) {
  return (
    <button className="my-button" onClick={props.onClick}>
      {props.label}
    </button>
  );
}

Adapteris (Adapter): paverčia vieno klases sąsają į kitą, kurios tikisi klientai. Leidžia dirbti su nesuderinamomis sąsajomis. Naudota trečiųjų šalių bibliotekų ar API integracijai su skirtingais metodų parašais.

// Adapterio pavyzdys, dirbant su skirtingais API klientais
class OldApi {
  getDataOld(id) {
    console.log(`Gaunama duomenys iš senojo API, ID: ${id}`);
    return { id: id, name: `Item ${id}` };
  }
}

class NewApi {
  fetchDataNew(itemId) {
    console.log(`Gaunama duomenys iš naujo API, ID: ${itemId}`);
    return { itemId: itemId, label: `Product ${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) {
      const newData = this.apiClient.fetchDataNew(id);
      return { id: newData.itemId, name: newData.label };
    }
    throw new Error("Nepalaikomas API klientas");
  }
}

const oldApiAdapter = new ApiAdapter(new OldApi());
console.log(oldApiAdapter.getData(1));

const newApiAdapter = new ApiAdapter(new NewApi());
console.log(newApiAdapter.getData(2));

Iteratoriaus (Iterator) pavyzdys: siūlo būdą nuosekliai prieiti prie sudėtinio objekto elementų, neatskleidžiant jo vidinės reprezentacijos. Naudojama cikluose (for...of) ir masyvų metoduose (forEach, map, filter).

// Iteratoriaus naudojimo pavyzdys JavaScript
const numbers = [1, 2, 3, 4, 5];

// Tiesioginis iteratoriaus gavimas
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 }

// Iteratoriaus naudojimas for...of
for (const number of numbers) {
  console.log(number);
}

Dekoratorius (Decorator): dinamiškai prideda naujas pareigas objektui, leidžia išplėsti objekto funkcionalumą be jo struktūros keitimo. Naudota HOC (Higher-Order Components) React arba dekoratoriai Angular/TypeScript.

// Higher-Order Component (HOC) React pavyzdys
function withLogging(WrappedComponent) {
  return function WithLogging(props) {
    console.log(`Komponentas ${WrappedComponent.name} renderintas su props:`, props);
    return <WrappedComponent {...props} />;
  };
}

// HOC taikymas
const EnhancedButton = withLogging(Button);

// Patobulinto komponento naudojimas
// <EnhancedButton label="Paspausk mane" onClick={() => console.log('Paspausta!')} />

Singleton (Odininkas): garantuoja, kad klasei yra tik vienas egzempliorius, ir suteikia globalią prieigą prie jo. Naudota globalios būsenos valdymui arba vieno paslaugos (pvz., logavimo, konfigūracijos) sukūrimui.

// Odininko šablonas
class ConfigManager {
  constructor() {
    if (ConfigManager.instance) {
      return ConfigManager.instance;
    }
    this.settings = {}; // Nustatymų inicializavimas
    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 (tas pats egzempliorius)

config1.setSetting('apiUrl', 'https://api.example.com');
console.log(config2.getSetting('apiUrl')); // https://api.example.com

Fabrikos metodas (Factory Method): apibrėžia sąsają objektui kurti, bet leidžia pogrupiams nuspręsti, kokį objektą kurti. Naudota kuriant įvairių tipų vartotojo sąsajos elementus arba objektus pagal konfigūraciją.

Strategijos (Strategy): apibrėžia algoritmų šeimą, juos įkapsuliuoja ir leidžia keisti jų naudojimą. Leidžia algoritmą keisti nepriklausomai nuo klientų, kurie jį naudoja. Naudota duomenų rūšiavimo, formų validacijos ar įvykių apdorojimo skirtingų metodų įgyvendinimui.

Šių šablonų naudojimas padėjo kurti labiau struktūruotą, modulinį, testuojamą ir palaikomą kodą.