No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Generics en clases

22/25
Recursos

Aportes 18

Preguntas 0

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Literal pasé las 2 clases preguntándome por qué esto era importante, hasta que la luz salvadora me iluminó en un instante de raciocinio, y comprendí la magnitud de Generics. Sencillamente, wow.

¿Esto serviría para crear un Backend completo con Node? Si alguien tiene un ejemplo, se lo agradecería.

Mi cerebro exploto, pero entendi muchas cosas con esta clase 😄

Vengo usando JS para el backend pero con esto pues no hay pierde. Me cambio a usar TS desde ahora. jeje

Tambien se puede escribir usando la convencion de nombres para genericos, que es comunmente con lo que te vas a topar

export class BaseHttpService<T> {

  constructor(
    private url: string
  ){}

  async getAll(): Promise<T[]> {
    const { data } = await axios.get<T[]>(this.url);
    return data;
  }
}

También se puede capturar el resultado de una promesa de este modo, para no hacer la función auto-invocada:

const url1 = "https://api.escuelajs.co/api/v1/products";

const productService = new BaseHttpService<Product>(url1);

productService.getAll().then(console.log);

Creo entender, usando la misma clase se hacen diferentes peticiones al servidor de diferentes entidades, lo que cambiaría es el tipado o genérico que le apliquemos a dicha clase, con esto se ahorraría la generación de una clase para cada entidad y varios métodos crud para cada entidad, lo cual ahorraría mucho en materia de líneas de código. Pero me surge una pregunta: ¿Hasta qué punto esto es beneficioso, ya que separar la lógica aparte de tener mayor claridad conserva el principio de una sola responsabilidad .? Si por alguna razon esta clase falla que sería la unica, fallaría toda la estructura relacionada con esa clase, por el contrario separando la lógica en diferentes clases mitigaría de cierta forma algún error que se presente en alguna clase especifica. Por otro lado las clases son representaciones abstractas del mundo real por ende cada entidad del mundo real, se representa como una clase por separado, entonces, se podría decir que separar las clases es algo mas cercano al mundo real. Entonces deben haber casos específicos donde se usen este tipo de genéricos . O NO, NO SE. solo son conjeturas mías, no soy experto. alguien que sepa mas que yo que me oriente por favor.

Sería mucho mejor pasar la url en el método, y no el constructor, ya que si transformamos nuestro servicio a un singleton, la segunda instanacia del servicio, la url no la tomaría.

Una Clase elegante, poderosa la utilidad de los generics cuando lo entiendes.

Llevo dos horas intentando entender los genéricos. Hasta que me carburo el cerebro y por arte de magia lo entendí :0

Aquí tienes un ejemplo de cómo implementar el patrón Singleton en TypeScript para la clase BaseHttpService:

import axios from 'axios';

export class BaseHttpService<TypeClass> {
  private static instance: BaseHttpService<any>;
  private url: string;

  private constructor(url: string) {
    this.url = url;
  }

  public static getInstance<TypeClass>(url: string): BaseHttpService<TypeClass> {
    if (!BaseHttpService.instance) {
      BaseHttpService.instance = new BaseHttpService<TypeClass>(url);
    }
    return BaseHttpService.instance;
  }

  async getAll() {
    const { data } = await axios.get<TypeClass[]>(this.url);
    return data;
  }

  async update(id: string, changes: Partial<TypeClass>) {
    const { data } = await axios.put(`${this.url}/${id}`, changes);
    return data;
  }

  async create(dto: TypeClass) {
    const { data } = await axios.post(this.url, dto);
    return data;
  }

  async findOne(id: string) {
    const { data } = await axios.get(`${this.url}/${id}`);
    return data;
  }

  async delete(id: string) {
    const { data } = await axios.delete(`${this.url}/${id}`);
    return data;
  }
}

En este ejemplo, hemos agregado un método estático llamado getInstance que se encarga de crear y mantener una única instancia de la clase BaseHttpService. El constructor de la clase es privado, lo que significa que no se puede acceder directamente a él desde fuera de la clase. Esto evita que se creen múltiples instancias de BaseHttpService y garantiza que siempre se utilice la misma instancia en todo el código.
.
Ahora, veamos por qué es bueno utilizar el patrón Singleton:

  1. Garantiza una única instancia: El patrón Singleton asegura que solo haya una instancia de una clase determinada en todo el programa. Esto puede ser útil cuando se necesita un objeto único para coordinar acciones en diferentes partes del código.

  2. Acceso global: Al utilizar el patrón Singleton, la instancia única se vuelve accesible globalmente desde cualquier parte del programa. Esto simplifica el acceso a la funcionalidad proporcionada por la clase, ya que no es necesario pasar la instancia entre diferentes componentes o clases.

  3. Mantiene el estado: Si la clase Singleton tiene estado, este estado se mantiene a lo largo de todo el ciclo de vida de la aplicación. Esto puede ser útil cuando se necesita mantener información o configuraciones específicas en un solo lugar y compartirlas en diferentes partes del programa.

  4. Promueve el acoplamiento débil: Al utilizar el patrón Singleton, los componentes o clases que dependen de la instancia no necesitan conocer los detalles de cómo se crea o se mantiene esa instancia. Solo necesitan solicitar la instancia al Singleton, lo que promueve un acoplamiento débil y facilita la modificación o sustitución de la implementación del Singleton en el futuro.

.
Sin embargo, es importante tener en cuenta que el patrón Singleton también puede tener algunas desventajas. Por ejemplo, puede dificultar las pruebas unitarias, ya que la dependencia de la instancia única puede ser difícil de simular o reemplazar en las pruebas. Además, el uso excesivo del patrón Singleton puede ocultar dependencias y dificultar la comprensión del flujo de datos y la arquitectura general del programa.
.
Por lo tanto, es recomendable utilizar el patrón Singleton con moderación y evaluar cuidadosamente si es la mejor solución para el problema específico que se está abordando.

Personalizando la clase en execution time.

Parece que ya no sirve la api 😕

Los genéricos son lo mejor

🤯🤯🤯

Typescript the best💙

Tuve que mirar la clases dos veces para poder entender un poco más acerda de la clases generics pero aquí está el resumen que pude sacar

RESUMEN:
Este es un servivio generico que podemos utilizar solamente pasando el tipo de dato
que queremos utulizar o hacer request, eso nos ahorraria hacer un servicio para
productos, categorias, usuarios etc…

Mi aporte:

import axios from 'axios';
import { Category } from '../models/category.model';
import { Product } from '../models/product.model';


export class BaseHttpService<TypeClass> {
  // data: TypeClass[] = [];
  constructor (private url: string) {}

  async getAll(): Promise<TypeClass[]> {
    const { data } = await axios.get<TypeClass[]>(this.url);
    return data;
  }

}

(async () => {
  const URL_PRODUCTS = 'https://api.escuelajs.co/api/v1/products'
  const URL_CATEGORIES = 'https://api.escuelajs.co/api/v1/categories'
  
  const productService = new BaseHttpService<Product>(URL_PRODUCTS);
  const categoryService = new BaseHttpService<Category>(URL_CATEGORIES);
  
  const products = await productService.getAll()
  const categories = await categoryService.getAll()

  
  console.log('products: >>>> ', products.length);
  console.log('categories: >>>> ', categories.length);
})()

Generics en clases

import axios from "axios";

import { Category } from "./models/category.model";
import { Product } from "./models/product.model";

export class BaseHttpService<TypeClass> {
  constructor(
    private url: string,
  ) { }

  async getAll() {
    const { data } = await axios.get<TypeClass[]>(this.url)
    return data;
  }
}

(async()=> {
  const url1 = 'https://api.escuelajs.co/api/v1/products'

  const productService = new BaseHttpService<Product>(url1)
  const rta = await productService.getAll()
  console.log('products: ', rta.length)

  const url2 = 'https://api.escuelajs.co/api/v1/categories'
  const categoryService = new BaseHttpService<Category>(url2)
  const rta2 = await categoryService.getAll()
  console.log('categories: ', rta2.length)
})()