No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Singleton: pros y contras

6/27
Recursos

Aportes 40

Preguntas 1

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

Les dejo mi codigo en TypeScript:

class Product {
  private id: number;
  private name: string;
  private cost: number;

  constructor(id: number, name: string, cost: number) {
    this.id = id;
    this.name = name;
    this.cost = cost;
  }

  getId() {
    return this.id;
  }

  getName() {
    return this.name;
  }

  getCost() {
    return this.cost;
  }
}

class ShoppingCart {
  private static instance: ShoppingCart;
  private cart: Product[] = [];

  private constructor() {}

  getCart() {
    return this.cart;
  }

  add(product: Product) {
    this.cart.push(product);
  }

  deleteById(id: number) {
    this.cart = this.cart.filter((prod) => prod.getId() !== id);
  }

  static getInstance() {
    if (!this.instance) this.instance = new ShoppingCart();
    return this.instance;
  }
}

(() => {
  const cart = ShoppingCart.getInstance();
  const cart2 = ShoppingCart.getInstance();
  const prod1 = new Product(1, "mate", 3000);
  const prod2 = new Product(2, "bombilla", 2900);
  const prod3 = new Product(3, "matera", 2400);

  // agregamos products al cart
  cart.add(prod1);
  cart.add(prod2);
  cart.add(prod3);

  console.log(cart.getCart());

  // borramos por id
  cart.deleteById(2);

  console.log(cart.getCart());

  // verificamos que ambos cart tienen la misma instancia, por tanto ambos tienen los mismos products
  console.log(cart === cart2);
  console.log(cart.getCart());
  console.log(cart2.getCart());
})();

Hasta este punto del curso, me hubiese gustado profundizar m谩s en diferentes casos de uso que pudiese tener el Patr贸n Singleton en desarrollo de software, pues de esta manera es como se podr铆a interiorizar el concepto de mejor forma.

Gracias.

Esta version implementa un carrito diferente para cada usuario, utilizando el patron singleton: ```js const PRODUCTS: Product[] = [ { name: "apple", id: 1, cost: 2000 }, { name: "banana", id: 2, cost: 500 }, { name: "coconut", id: 3, cost: 3000 }, { name: "meat", id: 4, cost: 20000 }, { name: "pineapple", id: 5, cost: 1000 }, { name: "coke", id: 6, cost: 1800 }, ] as Product[]; interface Product { id: number; name: string; cost: number; getName(): string; getCost(): number; getId(): number; } interface cart { add(product: Product): void; deleteById(id: number): void; getInstance(client: string): ShoppingCart; } class ShoppingCart implements cart { private products: Product[] = []; private constructor() {} static usersCarts: Record<string, ShoppingCart> = {}; static getInstance(client: string): ShoppingCart { return this.usersCarts[client] ? this.usersCarts[client] : new ShoppingCart(); } add(product: Product): void { this.products.push(product); } deleteById(id: number): void { const productIndex = this.products.findIndex( (product) => product.id === id ); if (productIndex !== -1) { this.products.splice(productIndex, 1); } } getTotal(): number { return this.products.reduce((total, product) => total + product.cost, 0); } } function clientApp() { const cartUser1 = ShoppingCart.getInstance("Client_1"); const cartUser2 = ShoppingCart.getInstance("Client_2"); const cartUser3 = ShoppingCart.getInstance("Client_3"); cartUser1.add(PRODUCTS[0]); cartUser1.add(PRODUCTS[1]); cartUser2.add(PRODUCTS[2]); cartUser2.add(PRODUCTS[3]); cartUser3.add(PRODUCTS[4]); cartUser3.add(PRODUCTS[5]); // Display the cart contents and total cost for each user console.info("Cart Contents and Total Cost for Each User:"); console.log("Client 1 Cart:"); console.log("Cart Contents:", cartUser1); console.log("Total Cost:", cartUser1.getTotal()); console.log("Client 2 Cart:"); console.log("Cart Contents:", cartUser2); console.log("Total Cost:", cartUser2.getTotal()); console.log("Client 3 Cart:"); console.log("Cart Contents:", cartUser3); console.log("Total Cost:", cartUser3.getTotal()); cartUser1.deleteById(PRODUCTS[0].id); cartUser2.deleteById(PRODUCTS[2].id); cartUser3.deleteById(PRODUCTS[4].id); // Display the updated cart contents and total cost for each user console.info("Cart Contents and Total Cost After Deletion for Each User:"); console.log("Client 1 Cart:"); console.log("Cart Contents:", cartUser1); console.log("Total Cost:", cartUser1.getTotal()); console.log("Client 2 Cart:"); console.log("Cart Contents:", cartUser2); console.log("Total Cost:", cartUser2.getTotal()); console.log("Client 3 Cart:"); console.log("Cart Contents:", cartUser3); console.log("Total Cost:", cartUser3.getTotal()); } clientApp(); ```
class Product {
    private id: number
    private name: string
    private cost: number

    public constructor(id: number, name: string, cost: number) {
        this.id = id
        this.name = name
        this.cost = cost
    }

    public getName(): string {
        return this.name
    }

    public getCost(): number {
        return this.cost
    }
    
    public getId(): number {
        return this.id
    }
}

class ShoppingCart {
    private static instance: undefined | ShoppingCart
    private products: Product[]
    
    private constructor() {
        this.products = []
    }

    public add(product: Product): void {
        this.products.push(product)
    }

    public deleteById(id: number): void {
        this.products = this.products.filter(product => product.getId() !== id)
    }

    public getProducts(): Product[] {
        return this.products
    }

    public static getInstance(): ShoppingCart {
        if(!ShoppingCart.instance) ShoppingCart.instance = new ShoppingCart()

        return ShoppingCart.instance
    }
}

function clientApp() {
    const silla = new Product(1, 'Silla de oficina', 10000)
    const mesa = new Product(2, 'Mesa para oficina', 20000)
    const lampara = new Product(3, 'Lampara de oficina', 5000)

    const shoppingCart = ShoppingCart.getInstance()

    // agregamos los productos al carrito
    shoppingCart.add(silla)
    shoppingCart.add(mesa)
    shoppingCart.add(lampara)

    console.log(shoppingCart.getProducts())

    // eliminamos un producto
    shoppingCart.deleteById(mesa.getId())

    console.log(shoppingCart.getProducts())
}

clientApp()

Usen ChatGPT o Bard de google para solicitarle casos de uso reales, eso me ayudo a entender mejor.

I think this should do it:

class ShoppingCart {
    static instance = undefined;

    constructor() {
        this.products = [];
    }

    getProducts = () => {
        return this.products;
    }

    addProduct = (product) => {
        return this.products.push(product);
    }

    deleteProductById = (id) => {
        return this.products = this.products.filter((product) => product.id !== id);
    }

    static getInstance = () => {
        if (!ShoppingCart.instance) ShoppingCart.instance = new ShoppingCart()
        return ShoppingCart.instance;
    }
}

class Product {
    constructor(id, name, cost) {
        this.id = id;
        this.name = name;
        this.cost = cost;
    }
    getID() {
        return this.id;
    }
    getName() {
        return this.name;
    }
    getCost() {
        return this.cost;
    }
}

const ClientApp = () => {
    const cart = ShoppingCart.getInstance();
    const vasos = new Product(1205, 'paquete de vasos', 12000);
    const zapatos = new Product(2166, 'zapatos - par', 57600)
    console.log(vasos.getName(), vasos.getCost(), vasos.getID());
    // Agregamos productos al carrito. 
    cart.addProduct(vasos);
    console.log('Agregamos vasos al cart', cart.getProducts());

    // confirmamos que el cart es el mismo, a煤n en otra instancia. 
    const cart2 = ShoppingCart.getInstance();
    cart2.addProduct(zapatos);
    console.log('Probamos que el nuevo cart tambi茅n tiene productos', cart2.getProducts());

    // Borramos el producto y probamos en ambos carritos. 
    cart.deleteProductById(1205);
    console.log('Eliminamos vasos del cart', cart.getProducts(), cart2.getProducts());
}

ClientApp();
Esta fue mi solucion para el reto, me costo pero lo logre comprender muy bien a la final ```js //Se crea la clase producto con sus atributos y m茅todos class Product { constructor(id, name, cost) { this.id = id; this.name = name; this.cost = cost; } getId() { return this.id; } getName() { return this.name; } getCost() { return this.cost; } } //Se crea la clase carrito class ShoppingCart { //Se crea su instancia que sea estatica static instance = undefined; constructor() { this.cart = []; } //Se crean sus diferentes metodos getCart() { return this.cart; } add(product) { this.cart.push(product); } deleteById(id) { this.cart = this.cart.filter((prod) => prod.getId() !== id); } //Se crea el metodo que llamara al constructor y retornara la instancia static getInstance() { if (!ShoppingCart.instance) ShoppingCart.instance = new ShoppingCart(); return ShoppingCart.instance; } } function appSingleton() { const product1 = new Product(1, "Cafe", 3000) const product2 = new Product(2, "Atun", 5000) const product3 = new Product(3, "Gelatina", 1500) const cart1 = ShoppingCart.getInstance() const cart2 = ShoppingCart.getInstance() cart1.add(product1) cart1.add(product2) cart1.add(product3) cart1.deleteById(1) console.log(cart1.getCart()); console.log(cart1 === cart2); } appSingleton() ```

Mi soluci贸n

class ShoppingCar {
    
    static instance = {};

    constructor(cliente) {
        this.cliente = cliente;
        this.products = [];
    }

    static getInstance(cliente) {
        if(!ShoppingCar.instance[cliente]){
            ShoppingCar.instance[cliente] = new ShoppingCar(cliente);
        }

        return ShoppingCar.instance[cliente];
    }

    add(product) {
        this.products.push(product);
    }

    deleteById(id){
        const index = this.products.findIndex(product => product.id === id);
        if (index !== -1) {
            this.products.splice(index, 1);
        }
    }
}

class Product {
    
    constructor(id,name,cost){
        this.id = id;
        this.name = name;
        this.cost = cost;
    }

    getName() {
        return this.name;
    }

    getCost() {
        return this.cost;
    }

    getId() {
        return this.number;
    }
}

function clientApp() {
    const cliente1 = ShoppingCar.getInstance('cliente1');
    const cliente1copia = ShoppingCar.getInstance('cliente1');
    const cliente2 = ShoppingCar.getInstance('cliente2');

    cliente1.add(new Product(0,'Computadora',1200));
    cliente1.add(new Product(1,'Celular',850));
    cliente1.add(new Product(2,'Cubo Rubik',10));

    cliente1.deleteById(1);

    console.log(cliente1,cliente1copia);


    console.log(
        `cliente1 y cliente1copia son iguales? ${ cliente1 === cliente1copia ? 'yes' : 'no'}`
    );

    console.log(
        `cliente1 y cliente2 son iguales? ${ cliente1 === cliente2 ? 'yes' : 'no'}`
    );
}

clientApp();
Les paso mi implementaci贸n de nuevo, porque el editor me fall贸. ![](https://static.platzi.com/media/user_upload/product-98354531-0281-41bb-b979-86df6970b089.jpg) ![](https://static.platzi.com/media/user_upload/shopingCart-e840fe3a-c3b6-4a40-86e2-a8773202f2e8.jpg) ![](https://static.platzi.com/media/user_upload/clientApp-6be5642d-ea50-4bf8-bfd7-e99bdc410fd6.jpg) Y el resultado: ![](https://static.platzi.com/media/user_upload/image-a2d24fea-dc65-4f15-9a5a-c8c912218543.jpg)

Hola, comparto mi soluci贸n, pense primero en usar .findIndex() y luego .splice() para el deleteById, aunque note en los comentarios que la mayoria usaron .filter():

class Product {
    private _id: number;
    private _name: string;
    private _cost: number;

    constructor(id: number, name: string, cost: number) {
        this._id = id;
        this._name = name;
        this._cost = cost;
    }

    get id() {
        return this._id;
    }
    get name() {
        return this._name;
    }
    get cost() {
        return this._cost;
    }
}

class ShoppingCar {
    private static instance: ShoppingCar;
    private _products: Array<Product>;

    private constructor() {
        this._products = [];
    }

    public static getInstance(): ShoppingCar {
        if (!ShoppingCar.instance) {
            ShoppingCar.instance = new ShoppingCar();
        }
        return ShoppingCar.instance;
    }

    get products() {
        return this._products;
    }

    add(product: Product): void {
        this._products.push(product);
    }
    deleteById(id: number): void {
        const index = this._products.findIndex(product => product.id === id);
        if (index !== -1) this._products.splice(index, 1);
        else console.log("producto no encontrado");
    }
}

function clientApp() {
    const shoppingCar = ShoppingCar.getInstance();

    shoppingCar.add(new Product(1, "Collar Dorado", 200));
    shoppingCar.add(new Product(3, "Silla", 250));
    shoppingCar.add(new Product(2, "Vaso", 50));

    console.log(shoppingCar.products);

    shoppingCar.deleteById(1);
    shoppingCar.deleteById(1);

    console.log(shoppingCar.products);

    const shoppingCar2 = ShoppingCar.getInstance();
    console.log(shoppingCar === shoppingCar2);
}

clientApp();

Les dejo como implemente el codigo del reto, espero sus feedback

Class Product

class Product {
    constructor(id, name, cost) {
        this._id = id;
        this._name = name;
        this._cost = cost;
    }
    getName() {
        return this._name;
    }
    getCost() {
        return this._cost;
        }
    getId() {
        return this._id;
    }
}

Class ShoppingCar

class ShoppingCar {
    static instance = undefined

    constructor() {
        this._products = []
    }

    static getInstance() {
        if(!ShoppingCar.instance) {
            ShoppingCar.instance = new ShoppingCar()
        }
        return ShoppingCar.instance
    }

    addProduct(product) {
        this._products.push(product)        
    }
    getProductById(id) {
        return this._products.find(product => product._id === id)
    }
    getProductByName(name) {
        return this._products.filter(product => product._name === name)
    }
    setProduct(newProductList) {
        this._products = newProductList
    }
    deleteProduct(id) {
        const deletedProduct = this.getProductById(id)
        const newProductList = this._products.filter(product => product._id !== id)
        this.setProduct(newProductList)
        return deletedProduct._name
    }
    getAllProduct() {
        return this._products
    }    
}

Cliente App para probar el funcionamiento del codigo

(function clienteApp() {
    const cart = ShoppingCar.getInstance();
    const vasos = new Product(1, "vasos plasticos" , 3)
    const zapatos = new Product(2, "gomas deportivas" , 30)
    const franela = new Product(3, "franela azul" , 25)
    const gorra = new Product(4, "gorra americana" , 10)
    const shorts = new Product(5, "shorts rojos" , 15)    

    cart.addProduct(vasos)
    cart.addProduct(zapatos)
    cart.addProduct(franela)
    cart.addProduct(gorra)
    /* Validamos que hay productos en el carrito */
    console.log(cart.getAllProduct);
    
    /* Instanciamos un segundo carrito y validamos que ya tiene productos*/
    const cart2 = ShoppingCar.getInstance();
    console.log(cart2.getAllProduct);
    /* Le agregamos un producto */
    cart2.addProduct(shorts);
    console.log(cart2.getAllProduct())
    /* Eliminamos un producto */
    console.log('Eliminamos exitosament el producto', cart.deleteProduct(2))

    /* Validamos que se elimino en ambos carritos */    
    console.log(cart.getAllProduct(),)
    console.log(cart2.getAllProduct())
})()
`class ShoppingCar {聽 private static instance: ShoppingCar;聽 public products: Product[] = [];` `聽 private constructor() { }` `聽 static getInstance(): ShoppingCar {聽 聽 if(!ShoppingCar.instance) {聽 聽 聽 ShoppingCar.instance = new ShoppingCar();聽 聽 }` `聽 聽 return ShoppingCar.instance;聽 }` `聽 public add(``product``: Product): void {聽 聽 this.products.push(``product``);聽 }` `聽 public deleteById(``id``: number): void {聽 聽 this.products = this.products.filter(``product`` => ``product``.getId() !== ``id``);聽 }}` `class Product{聽 constructor(private ``id``: number, private ``name``: string, private ``cost``: number) { }` `聽 public getId(): number {聽 聽 return this.id;聽 }` `聽 public getName(): string {聽 聽 return this.name;聽 }` `聽 public getCost(): number {聽 聽 return this.cost;聽 }}` `function app() {聽 const shoppingCar = ShoppingCar.getInstance();聽 const product = new Product(1, 'TV', 1000);聽 const product2 = new Product(2, 'PC', 2000);聽 const product3 = new Product(3, 'Phone', 3000);聽 shoppingCar.add(product);聽 shoppingCar.add(product2);聽 shoppingCar.add(product3);` `聽 const shoppingCar2 = ShoppingCar.getInstance();聽 const product4 = new Product(4, 'video game', 4000);聽 shoppingCar2.add(product4);` `聽 console.log(shoppingCar.products);` `聽 shoppingCar.deleteById(2);` `聽 console.log(shoppingCar.products);聽 console.log(shoppingCar2.products);}` `app();`
` ```javascript ` class ShoppingCar {聽 private static instance: ShoppingCar;聽 public products: Product\[] = \[]; 聽 private constructor() { } 聽 static getInstance(): ShoppingCar {聽 聽 if(!ShoppingCar.instance) {聽 聽 聽 ShoppingCar.instance = new ShoppingCar();聽 聽 } 聽 聽 return ShoppingCar.instance;聽 } 聽 public add(*product*: Product): void {聽 聽 this.products.push(*product*);聽 } 聽 public deleteById(*id*: number): void {聽 聽 this.products = this.products.filter(*product* => *product*.getId() !== *id*);聽 }} class Product{聽 constructor(private *id*: number, private *name*: string, private *cost*: number) { } 聽 public getId(): number {聽 聽 return this.id;聽 } 聽 public getName(): string {聽 聽 return this.name;聽 } 聽 public getCost(): number {聽 聽 return this.cost;聽 }} function app() {聽 const shoppingCar = ShoppingCar.getInstance();聽 const product = new Product(1, 'TV', 1000);聽 const product2 = new Product(2, 'PC', 2000);聽 const product3 = new Product(3, 'Phone', 3000);聽 shoppingCar.add(product);聽 shoppingCar.add(product2);聽 shoppingCar.add(product3); 聽 const shoppingCar2 = ShoppingCar.getInstance();聽 const product4 = new Product(4, 'video game', 4000);聽 shoppingCar2.add(product4); 聽 console.log(shoppingCar.products); 聽 shoppingCar.deleteById(2); 聽 console.log(shoppingCar.products);聽 console.log(shoppingCar2.products);} app(); ` ``` `
```js class ShoppingCar { private static instance: ShoppingCar; public products: Product[] = []; private constructor() { } static getInstance(): ShoppingCar { if(!ShoppingCar.instance) { ShoppingCar.instance = new ShoppingCar(); } return ShoppingCar.instance; } public add(product: Product): void { this.products.push(product); } public deleteById(id: number): void { this.products = this.products.filter(product => product.getId() !== id); } } class Product{ constructor(private id: number, private name: string, private cost: number) { } public getId(): number { return this.id; } public getName(): string { return this.name; } public getCost(): number { return this.cost; } } function app() { const shoppingCar = ShoppingCar.getInstance(); const product = new Product(1, 'TV', 1000); const product2 = new Product(2, 'PC', 2000); const product3 = new Product(3, 'Phone', 3000); shoppingCar.add(product); shoppingCar.add(product2); shoppingCar.add(product3); const shoppingCar2 = ShoppingCar.getInstance(); const product4 = new Product(4, 'video game', 4000); shoppingCar2.add(product4); console.log(shoppingCar.products); shoppingCar.deleteById(2); console.log(shoppingCar.products); console.log(shoppingCar2.products); } app(); ```class ShoppingCar {聽 private static instance: ShoppingCar;聽 public products: Product\[] = \[]; 聽 private constructor() { } 聽 static getInstance(): ShoppingCar {聽 聽 if(!ShoppingCar.instance) {聽 聽 聽 ShoppingCar.instance = new ShoppingCar();聽 聽 } 聽 聽 return ShoppingCar.instance;聽 } 聽 public add(*product*: Product): void {聽 聽 this.products.push(*product*);聽 } 聽 public deleteById(*id*: number): void {聽 聽 this.products = this.products.filter(*product* => *product*.getId() !== *id*);聽 }} class Product{聽 constructor(private *id*: number, private *name*: string, private *cost*: number) { } 聽 public getId(): number {聽 聽 return this.id;聽 } 聽 public getName(): string {聽 聽 return this.name;聽 } 聽 public getCost(): number {聽 聽 return this.cost;聽 }} function app() {聽 const shoppingCar = ShoppingCar.getInstance();聽 const product = new Product(1, 'TV', 1000);聽 const product2 = new Product(2, 'PC', 2000);聽 const product3 = new Product(3, 'Phone', 3000);聽 shoppingCar.add(product);聽 shoppingCar.add(product2);聽 shoppingCar.add(product3); 聽 const shoppingCar2 = ShoppingCar.getInstance();聽 const product4 = new Product(4, 'video game', 4000);聽 shoppingCar2.add(product4); 聽 console.log(shoppingCar.products); 聽 shoppingCar.deleteById(2); 聽 console.log(shoppingCar.products);聽 console.log(shoppingCar2.products);} app();

Buenas! Dejo mi implementaci贸n en Python

class Product:

    def __init__(self, id, name, cost):
        self._id = id
        self._name = name
        self._cost = cost

    def get_name(self):
        return self._name

    def get_cost(self):
        return self._cost
    
    def get_id(self):
        return self._id

class ShoppingCar:

    _instance = None
    _products = []

    def __new__(cls):
        if not cls._instance:
            cls._instance = super().__new__(cls)
        return cls._instance
    
    def add_product(self, product):
        self._products.append(product)

    def delete_by_id(self,id):
        for elemento in self._products:
            if elemento['id'] == id:
                self._products.remove(elemento)
    def show_products(self):
        return self._products

    @staticmethod
    def get_instance():
        return ShoppingCar()

class ClientApp:
    def __init__(self, id):
        self.id = id
        self.shopping_car = ShoppingCar.get_instance()

client = ClientApp(1)
client_2 = ClientApp(2)
print(client.shopping_car , client_2.shopping_car, client.shopping_car == client_2.shopping_car) # True
client.shopping_car.add_product(Product(1,'chocolate',22))

print(client.shopping_car == client_2.shopping_car, '#######')

Haciendo privada las propiedades de Product, es la forma en la que se me ocurri贸 despu茅s acceder a ellas mediante ShoppingCar.

class ShoppingCar{
    static #instanceSC = undefined;
    #products = [];
    
    addProduct(product){
        this.#products.push(product);
    }
    getProducts(){
        return this.#products;
    }

    deleteById(id){
        for (let n = 0; n < this.#products.length; n++) {
            if (this.#products[n].id === id) {
                this.#products.splice(n, 1);
                break; // Si los IDs son 煤nicos, puedes salir del bucle una vez encontrado
            }
        }
        return this.#products;
    }
    static getInstance(){
        if(!ShoppingCar.#instanceSC){
            ShoppingCar.#instanceSC = new ShoppingCar();
        }
        return ShoppingCar.#instanceSC;
    }
}

class Product{
    #id;
    #name;
    #cost;

    constructor(id, name, cost) {
        this.#id = id;
        this.#name = name;
        this.#cost = cost;
    }

    getName() {
        return this.#name;
    }

    getCost() {
        return this.#cost;
    }

    getId() {
        return this.#id;
    }
}

const myShoppingCart = ShoppingCar.getInstance();
const myProduct = new Product(1, 'kevin', 100000);

myShoppingCart.addProduct(myProduct);

const products = myShoppingCart.getProducts();
products.forEach(product => {
    console.log(`ID: ${product.getId()}, Name: ${product.getName()}, Cost: ${product.getCost()}`);
});
I just want to share my solution in TS: ```ts class ShoppingCart { private static instance: ShoppingCart; private cart: Product[] = []; private constructor() {} static getInstance(): ShoppingCart { if (!ShoppingCart.instance) { ShoppingCart.instance = new ShoppingCart(); } return ShoppingCart.instance; } public getCart(): Product[] { return this.cart; } public addProduct(product: Product): void { this.cart.push(product); } public deleteById(id: number): void { let indexProduct = this.cart.findIndex((item) => item.getId() == id); this.cart.splice(indexProduct, 1); } } class Product { private id: number; private name: string; private cost: number; public constructor(id: number, name: string, cost: number) { this.id = id; this.name = name; this.cost = cost; } public getId(): number { return this.id; } public getName(): string { return this.name; } public getCost(): number { return this.cost; } } (() => { const cart = ShoppingCart.getInstance(); const cart2 = ShoppingCart.getInstance(); const p1 = new Product(1, "camara", 500); const p2 = new Product(2, "cama", 1500); const p3 = new Product(3, "cojin", 20); cart.addProduct(p1); cart.addProduct(p2); cart.addProduct(p3); console.log(cart.getCart()); cart.deleteById(2); console.log(cart.getCart()); // Verify the instance is the same in both carts console.log(cart === cart2); console.log(cart.getCart()); console.log(cart2.getCart()); })(); ```class ShoppingCart {聽 private static instance: ShoppingCart;聽 private cart: Product\[] = \[]; 聽 private constructor() {} 聽 static getInstance(): ShoppingCart {聽 聽 if (!ShoppingCart.instance) {聽 聽 聽 ShoppingCart.instance = new ShoppingCart();聽 聽 }聽 聽 return ShoppingCart.instance;聽 }聽 public getCart(): Product\[] {聽 聽 return this.cart;聽 }聽 public addProduct(product: Product): void {聽 聽 this.cart.push(product);聽 }聽 public deleteById(id: number): void {聽 聽 let indexProduct = this.cart.findIndex((item) => item.getId() == id);聽 聽 this.cart.splice(indexProduct, 1);聽 }} class Product {聽 private id: number;聽 private name: string;聽 private cost: number; 聽 public constructor(id: number, name: string, cost: number) {聽 聽 this.id = id;聽 聽 this.name = name;聽 聽 this.cost = cost;聽 }聽 public getId(): number {聽 聽 return this.id;聽 }聽 public getName(): string {聽 聽 return this.name;聽 }聽 public getCost(): number {聽 聽 return this.cost;聽 }} (() => {聽 const cart = ShoppingCart.getInstance();聽 const cart2 = ShoppingCart.getInstance();聽 const p1 = new Product(1, "camara", 500);聽 const p2 = new Product(2, "cama", 1500);聽 const p3 = new Product(3, "cojin", 20); 聽 cart.addProduct(p1);聽 cart.addProduct(p2);聽 cart.addProduct(p3); 聽 console.log(cart.getCart()); 聽 cart.deleteById(2); 聽 console.log(cart.getCart());聽 // Verify the instance is the same in both carts聽 console.log(cart === cart2);聽 console.log(cart.getCart());聽 console.log(cart2.getCart());})();

Mi sulocion Ts

class Product {
    private id: number;
    private name: string;
    private cost: number;

    constructor(id: number, name: string, cost: number) {
        this.id = id;
        this.name = name;
        this.cost = cost;
    }

    getid(): number {
        return this.id;
    };

    getName(): string {
        return this.name;
    };

    getCost(): number {
        return this.cost;
    };
};

class ShoppingCar {
    private static instance: ShoppingCar;
    private products: Product[];

    private constructor() {
        this.products = [];
    }

    static getInstance(): ShoppingCar {
        if (!ShoppingCar.instance) {
            ShoppingCar.instance = new ShoppingCar;
        }
        return ShoppingCar.instance;
    }

    addProduct(...product: Product[]) {
        this.products.push(...product)
    }

    getProducts(): Product[] {
        return this.products;
    }

    deleteById(id: number) {
        return this.products = this.products.filter(elem => elem.getid() !== id);
    }

}

// implementacion 
// crear una unica instancia de shopping car
const car = ShoppingCar.getInstance();
const car2 = ShoppingCar.getInstance();

// crear 2 products para poblar
let product1 = new Product(1, 'amp', 1500);
let product2 = new Product(2, 'guitar', 1700);

car.addProduct(product1, product2)

// comprobaciones en consola
console.log(`shold be true, ${car === car2}`);
console.log(car.getProducts());




```js class Singelton { static instance = undefined; #listProducts = []; constructor(versions) { this.version = this.version }; static getInstance(version) { if (!Singelton.instance) { Singelton.instance = new Singelton(version); } return Singelton.instance } addProduct(product) { this.#listProducts.push(product) } removeProduct(product) { this.#listProducts.splice(listProducts.indexOf(product), 1) } showProducts() { this.#listProducts.forEach(e => { console.log(e) }) } } function appSingelton(){ const singelton1 = Singelton.getInstance("1.0") const singelton2 = Singelton.getInstance("2.0") const sigleton3 = Singelton.getInstance("3.0") sigleton3.addProduct("Producto 1") sigleton3.addProduct("Producto 2") sigleton3.addProduct("Producto 3") sigleton3.showProducts() singelton2.showProducts() console.log(singelton1 === singelton2) } appSingelton() ```class Singelton { static instance = undefined; \#listProducts = \[]; constructor(versions) { this.version = this.version }; static getInstance(version) { if (!Singelton.instance) { Singelton.instance = new Singelton(version); } return Singelton.instance } addProduct(product) { this.#listProducts.push(product) } removeProduct(product) { this.#listProducts.splice(listProducts.indexOf(product), 1) } showProducts() { this.#listProducts.forEach(e => { console.log(e) }) } } function appSingelton(){ const singelton1 = Singelton.getInstance("1.0") const singelton2 = Singelton.getInstance("2.0") const sigleton3 = Singelton.getInstance("3.0") sigleton3.addProduct("Producto 1") sigleton3.addProduct("Producto 2") sigleton3.addProduct("Producto 3") sigleton3.showProducts() singelton2.showProducts() console.log(singelton1 === singelton2) } appSingelton()
aporte `class products { constructor({id, name , cost}){ this._id = id, this._name = name, this._cost = cost } get id(){ return this._id; } get name(){ return this._name; } get cost(){ return this._cost; } }const carro = new products({id:0, name:"carro", cost:200})const moto = new products({id:1, name:"motos", cost:300})const avion = new products({id:1, name:"motos", cost:300})console.log(carro)class ShoppingCart { static instance = undefined; constructor (client){ this._client = client this._product = [] } static getInstance (client){ if (!ShoppingCart.instance){ ShoppingCart.instance = new ShoppingCart(client) } return ShoppingCart.instance } set addProduct(products){ this._product.push(products) } set removeProduct(products){ this._product= this._product.remove(e => console.log) } set deletProduct(productId){ this._product = this._product.filter(product => !(product.id == productId)) }}const client1 = ShoppingCart.getInstance("cliente 1")const client2 = ShoppingCart.getInstance("cliente 2")` `client1.addProduct = carroclient1.addProduct = motoclient1.deletProduct = 0` `console.log(client1)`
Dejo la implementacion en python, en este caso haciendo uso del parametro ```metaclass``` , que a lo que investige esta metaclase define el comportameito de la clase , de modo que al sobreescribir el metodo \_\_call\_\_ en esta, se sobreescribe el comportamiento cuando llamas o invocas a la clase, y es ahi donde validamos la creacion de la unica instancia. ```js class Product: def __init__(self, _id: int, name: str, cost: float): self._id = _id self.name = name self.cost = cost def get_id(self): return self._id class ShoppingCarMeta(type): _instances = {} def __call__(cls, *args, **kwargs): if cls not in cls._instances: instance = super().__call__(*args, **kwargs) cls._instances[cls] = instance return cls._instances[cls] class ShoppingCar(metaclass=ShoppingCarMeta): products: list[Product] = [] def add_product(self, product: Product): self.products.append(product) def delete_product(self, id_product: int): self.products = list(filter(lambda p: p.get_id() != id_product, self.products)) def show_products(self): return [product.name for product in self.products] if __name__ == '__main__': my_car = ShoppingCar() my_car.add_product(ball) my_car.add_product(shirt) print(my_car.show_products()) my_car2 = ShoppingCar() my_car2.add_product(notebook) print(my_car2.show_products()) my_car.delete_product(4) print(my_car2.show_products()) ```
Como reto personal, decid铆 implementar este patr贸n con Swift. Aqu铆 les dejo el c贸digo a los curiosos: ```js import Foundation class Singleton { static private var instance: Singleton? private let id: UUID private init() { self.id = UUID() } static public func getInstance() -> Singleton { if Singleton.instance == nil { Singleton.instance = Singleton() } return Singleton.instance! } func print() { print("Singleton id is: \(self.id)") } } ```
Como reto personal, decid铆 implementar este patr贸n con Swift. Aqu铆 les dejo el c贸digo a los curiosos: ```txt import Foundation class Singleton { static private var instance: Singleton? private let id: UUID private init() { self.id = UUID() } static public func getInstance() -> Singleton { if Singleton.instance == nil { Singleton.instance = Singleton() } return Singleton.instance! } func printId() { print("Singleton id is: \(self.id)") } } ```
Va mi soluci贸n al reto en JS: ```js class Product { constructor({ id, name, cost }) { this.#objectSetup({ id, name, cost }); } #privateData = { _id: 0, _name: "", _cost: 0, }; #objectSetup({ id, name, cost }) { if (!id || !name || !cost) { throw new Error("Missing data."); } this.#privateData._id = id; this.#privateData._name = name; this.#privateData._cost = cost; return { id: this.#privateData._id, name: this.#privateData._name, cost: this.#privateData._cost, }; } get id() { return this.#privateData._id; } get name() { return this.#privateData._name; } get cost() { return this.#privateData._cost; } get product() { return { id: this.#privateData._id, name: this.#privateData._name, cost: this.#privateData._cost, }; } } ``````js class ShoppingCart { static #instance = undefined; constructor() {} #privateProducts = []; static getInstance() { if (!ShoppingCart.#instance) { const newInstance = new ShoppingCart(); ShoppingCart.#instance = newInstance; } return ShoppingCart.#instance; } addProduct(product) { if (product instanceof Product) { this.#privateProducts.push(product); return product; } else { throw new Error("Not a valid product."); } } deleteById(id) { if (typeof id === "number") { const productIndex = this.#privateProducts.findIndex( (product) => product.id === id ); if (!productIndex) { throw new Error("Product not found to delete."); } else { const deletedProduct = this.#privateProducts.splice(productIndex, 1); return deletedProduct; } } } get products() { return this.#privateProducts; } } ```
Mi implementacion al reto. Entendi mucho como funcionan las relaciones con las clases. ```js class ShoppingCart{ static instance = undefined; static products = undefined; constructor() { ShoppingCart.products = [] } static createShoppingCart() { if(!this.instance) { this.instance = new ShoppingCart(); } return this.instance; } addProduct(product){ ShoppingCart.products.push(product) } deleteById(ID = Number){ const index = ShoppingCart.products.findIndex(product=> product.id === ID) if(index != -1){ ShoppingCart.products.splice(index, 1); return `Deleted product` } else{return 'Product not Found';} } getInstance(){ return ShoppingCart.instance; } getProducts() { return ShoppingCart.products; } } class Product{ static name = String; static id = Number; static cost= Number; constructor(ident, costo, nombre) { this.name = nombre; this.id = ident; this.cost = costo; this.exportProduct(this.name, this.id, this.cost); } exportProduct(name, id, cost) { const producto = {name, id, cost} return producto } getName(){ return this.name; } getCost(){ return this.cost; } getId(){ return this.id; } } //creando las instancias const laptop1 = new Product(377, 250, 'Laptop HP') const laptop2 = new Product(336, 450, 'Laptop asus') const laptop3 = new Product(535, 250, 'Laptop Razer') const carrito = ShoppingCart.createShoppingCart() carrito.addProduct(laptop1) carrito.addProduct(laptop2) carrito.addProduct(laptop3) carrito.deleteById(377) console.log(carrito.getProducts()); ```class ShoppingCart{聽 聽 static instance = undefined;聽 聽 static products = undefined; 聽 聽 constructor()聽 聽 {聽 聽 聽 聽 ShoppingCart.products = \[]聽 聽 }聽 聽 static createShoppingCart()聽 聽 {聽 聽 聽 聽 if(!this.instance)聽 聽 聽 聽 {聽 聽 聽 聽 聽 聽 this.instance = new ShoppingCart();聽 聽 聽 聽 }聽 聽 聽 聽 return this.instance;聽 聽 }聽 聽 addProduct(product){聽 聽 聽 聽 ShoppingCart.products.push(product)聽 聽 } 聽 聽 deleteById(ID = Number){聽 聽 聽 聽 const index = ShoppingCart.products.findIndex(product=> product.id === ID)聽 聽 聽 聽 if(index != -1){聽 聽 聽 聽 聽 聽 ShoppingCart.products.splice(index, 1);聽 聽 聽 聽 聽 聽 return `Deleted product`聽 聽 聽 聽 }聽 聽 聽 聽 else{return 'Product not Found';}聽 聽 } 聽 聽 getInstance(){聽 聽 聽 聽 return ShoppingCart.instance;聽 聽 }聽 聽 getProducts()聽 聽 {聽 聽 聽 聽 return ShoppingCart.products;聽 聽 }} class Product{ 聽 聽 static name = String;聽 聽 static id = Number;聽 聽 static cost= Number; 聽 聽 constructor(ident, costo, nombre)聽 聽 {聽 聽 聽 聽 this.name = nombre;聽 聽 聽 聽 this.id = ident;聽 聽 聽 聽 this.cost = costo; 聽 聽 聽 聽 this.exportProduct(this.name, this.id, this.cost);聽 聽 } 聽 聽 exportProduct(name, id, cost)聽 聽 {聽 聽 聽 聽 const producto = {name, id, cost}聽 聽 聽 聽 return producto聽 聽 } 聽 聽 getName(){聽 聽 聽 聽 return this.name;聽 聽 }聽 聽 getCost(){聽 聽 聽 聽 return this.cost;聽 聽 }聽 聽 getId(){聽 聽 聽 聽 return this.id;聽 聽 }}//creando las instancias const laptop1 = new Product(377, 250, 'Laptop HP')const laptop2 = new Product(336, 450, 'Laptop asus')const laptop3 = new Product(535, 250, 'Laptop Razer') const carrito = ShoppingCart.createShoppingCart()carrito.addProduct(laptop1)carrito.addProduct(laptop2)carrito.addProduct(laptop3)carrito.deleteById(377)console.log(carrito.getProducts());
Justo, termine de hacer el codigo y realmente aprend铆 mucho en la practica : class Product {聽 聽private id: number;聽 聽private name: string;聽 聽private cost: number; 聽 聽constructor(id: number, name:string, cost:number){聽 聽 聽 this.id = id;聽 聽 聽 this.cost = cost;聽 聽 聽 this.name = name;聽 聽} 聽 聽getName():string{聽 聽 聽 return this.name聽 聽} 聽 聽getCost():number{聽 聽 聽 return this.cost聽 聽} 聽 聽getId():number{聽 聽 聽 return this.id聽 聽}} class ShoopingCar {聽 聽 private static instance: ShoopingCar;聽 聽 private products: Array\<Product>; 聽 聽 private constructor(){} 聽 聽 add(product:Product){聽 聽 聽 聽this.products.push(product);聽 聽 } 聽 聽 deletedById(id:number){聽 聽 聽 聽this.products.splice(id, 1);聽 聽 } 聽 聽 static getInstance(): ShoopingCar{聽 聽 聽 聽 if(!ShoopingCar.instance){聽 聽 聽 聽 聽 聽 ShoopingCar.instance = new ShoopingCar();聽 聽 聽 聽 }聽 聽 聽 聽 return ShoopingCar.instance聽 聽 } } const car1 = ShoopingCar.getInstance();const car2 = ShoopingCar.getInstance(); console.log(car1 === car2);
Mi soluci贸n al reto. ```js class Product { constructor(id, name, cost) { this.id = id; this.name = name; this.cost = cost; } getName() { return this.name; } getCost() { return this.cost; } getId() { return this.id; } } class ShoppingCart { static instance = undefined; constructor() { this.products = []; } add(product) { this.products.push(product); } deleteById(id) { this.products = this.products.filter((value) => value.getId() !== id); } static getInstance() { if(!ShoppingCart.instance) { ShoppingCart.instance = new ShoppingCart(); } return ShoppingCart.instance; } } function app() { const shoppingCart1 = ShoppingCart.getInstance(); const shoppingCart2 = ShoppingCart.getInstance(); const shoppingCart3 = ShoppingCart.getInstance(); const product1 = new Product(10, "Caf茅", 20.0); const product2 = new Product(2, "Laptop", 8600.0); shoppingCart1.add(product1); shoppingCart2.add(product2); console.log(shoppingCart1, shoppingCart2, shoppingCart3); } app(); ```
```js // Class using the singleton pattern class ShoppingCar { private static instance: ShoppingCar; private products: Array<Product> = []; private constructor () { } public static getInstance(): ShoppingCar { if (!ShoppingCar.instance) { ShoppingCar.instance = new ShoppingCar(); } return ShoppingCar.instance; } public add(product: Product) { this.products.push(product); } public deleteById(id: number) { const index = this.products.findIndex(product => product.getGetId() === id); if (index !== -1) { this.products.splice(index, 1); } else { console.log(`Product with id ${id} not found.`); } } } // Normal Class class Product { private id: number; private name: string; private cost: number; constructor (id: number, name: string, cost: number) { this.id = id; this.name = name; this.cost = cost; } public getName () { return this.name; } public getCost () { return this.cost; } public getGetId () { return this.id; } } // Examples let cart1 = ShoppingCar.getInstance(); let cart2 = ShoppingCar.getInstance(); let isSingleton12 = cart1 === cart2; console.log(`Cart1 and Cart2 are references of the same object? : ${isSingleton12}`); let cart3 = ShoppingCar.getInstance(); let cart4 = ShoppingCar.getInstance(); let isSingleton34 = cart3 === cart4; cart4.add(new Product(1, "Aguacate", 85)); cart4.add(new Product(5, "Lechoza", 115)); cart4.add(new Product(29, "Chinola", 43)); console.log(`Cart3 and Cart4 are references of the same object? : ${isSingleton34}`); cart3.deleteById(1); console.log(`After removing one element from just Cart3... are Cart3 and Cart4 still references of the same object? : ${isSingleton34}`); console.log(`Are Cart1, Cart2, Cart3 and Cart4 references of the same object? : ${isSingleton12 && isSingleton34}`); ```// Class using the singleton patternclass ShoppingCar { 聽 聽 private static instance: ShoppingCar;聽 聽 private products: Array\<Product> = \[]; 聽 聽 private constructor () { } 聽 聽 public static getInstance(): ShoppingCar {聽 聽 聽 聽 if (!ShoppingCar.instance) {聽 聽 聽 聽 聽 聽 ShoppingCar.instance = new ShoppingCar();聽 聽 聽 聽 }聽 聽 聽 聽 return ShoppingCar.instance;聽 聽 } 聽 聽 public add(product: Product) {聽 聽 聽 聽 this.products.push(product);聽 聽 } 聽 聽 public deleteById(id: number) {聽 聽 聽 聽 const index = this.products.findIndex(product => product.getGetId() === id);聽 聽 聽 聽 if (index !== -1) {聽 聽 聽 聽 聽 聽 this.products.splice(index, 1);聽 聽 聽 聽 } else {聽 聽 聽 聽 聽 聽 console.log(`Product with id ${id} not found.`);聽 聽 聽 聽 }聽 聽 } } // Normal Classclass Product {聽 聽 private id: number;聽 聽 private name: string;聽 聽 private cost: number; 聽 聽 constructor (id: number, name: string, cost: number) {聽 聽 聽 聽 this.id = id;聽 聽 聽 聽 this.name = name;聽 聽 聽 聽 this.cost = cost;聽 聽 } 聽 聽 public getName () { return this.name; }聽 聽 public getCost () { return this.cost; }聽 聽 public getGetId () { return this.id; }} // Examples let cart1 = ShoppingCar.getInstance();let cart2 = ShoppingCar.getInstance(); let isSingleton12 = cart1 === cart2; console.log(`Cart1 and Cart2 are references of the same object? : ${isSingleton12}`); let cart3 = ShoppingCar.getInstance();let cart4 = ShoppingCar.getInstance(); let isSingleton34 = cart3 === cart4; cart4.add(new Product(1, "Aguacate", 85));cart4.add(new Product(5, "Lechoza", 115));cart4.add(new Product(29, "Chinola", 43)); console.log(`Cart3 and Cart4 are references of the same object? : ${isSingleton34}`); cart3.deleteById(1); console.log(`After removing one element from just Cart3... are Cart3 and Cart4 still references of the same object? : ${isSingleton34}`); console.log(`Are Cart1, Cart2, Cart3 and Cart4 references of the same object? : ${isSingleton12 && isSingleton34}`);
```js class Product { #data static #ALL_PRODUCTS = []; constructor({ id, name, cost }) { this.#data = new Map(); this.#data.set('id', id); this.#data.set('name', name); this.#data.set('cost', cost); this.#data.forEach((value, key) => { if (!value) { throw new Error(`El valor para '${key}' no puede estar vac铆o.`); } }); const obj = {}; this.#data.forEach((value, key) => { obj[key] = value; }); Product.#ALL_PRODUCTS.push(obj); } getName() { return this.#data.get('name'); } getCost() { return this.#data.get('cost'); } getId() { return this.#data.get('id'); } static getProducts() { return Product.#ALL_PRODUCTS } } const coke = new Product({id: 235463 , name: 'Coke' , cost: 50.000 }) const apple = new Product({id: 245641, name: 'Apple' , cost: 80.000 }) const banana = new Product({id: 34354132 , name: 'Banana' , cost: 20.000 }) const coconut = new Product({id: 2424545 , name: 'Coconut' , cost: 10.000 }) const meat = new Product({id: 25452 , name: 'Meat' , cost: 30.000 }) const pineapple = new Product({id: 2452 , name: 'Pineapple' , cost: 980.000 }) class ShoppingCar { #productsAvailable = Product.getProducts() #userId static #USER_CARS = new Map(); constructor(userId) { this.#userId = userId this.productsSelect = [] } static newUser(userId) { if (!ShoppingCar.#USER_CARS.has(userId)) { const newCar = new ShoppingCar(userId); ShoppingCar.#USER_CARS.set(userId, newCar); return newCar; } else { return ShoppingCar.#USER_CARS.get(userId); } } #addProduct(type, product) { this.#productsAvailable.forEach((element, index) => { if (element[type] === product) { this.productsSelect.push(this.#productsAvailable.splice(index, 1)[0]) } }) } addProductByName(product) { this.#addProduct('name', product); } addProductById(product) { this.#addProduct('id', product); } #deleteProduct(type, product){ this.productsSelect.forEach((element, index) => { if (element[type] === product) { this.#productsAvailable.push(this.productsSelect.splice(index, 1)[0]) } }) } deleteProductByName(product) { this.#deleteProduct('name', product) } deleteProductById(product) { this.#deleteProduct('id', product) } } const user1 = ShoppingCar.newUser('112424254') const user2 = ShoppingCar.newUser('36') const user3 = ShoppingCar.newUser('112424254') user1.addProductByName('Coke') user1.addProductByName('Meat') user1.addProductById(2452) user1.deleteProductById(2452) console.log(user1) ```GG
Les dejo mi ejercicio en TypeScript: ```js interface IProduct { id: number; name: string; cost: number; } class Product { private product: IProduct = { id: 0, name: '', cost: 0 } constructor( product: IProduct){ this.product = product } getName(): string { return this.product.name; } getCost(): number { return this.product.cost; } getId(): number { return this.product.id; } } class ShoppingCar { private static instance: ShoppingCar; private products: Product[] = []; private constructor(){ } static getInstance(): ShoppingCar { if(!ShoppingCar.instance){ ShoppingCar.instance = new ShoppingCar(); } return ShoppingCar.instance } addProduct( product: Product) { this.products.push(product); } deleteById( id: number) { const productExist = !!this.products.find((product) => product.getId() === id); if (productExist) { this.products = this.products.filter((prod) => prod.getId() !== id);; } else { console.log(id," doesnt exist"); } } getShoppingCar(){ return this.products; } } const product1: Product = new Product({ id: 1, name: 'laptop', cost: 1000 }) const product2: Product = new Product({ id: 2, name: 'ps5', cost: 700 }) const product3: Product = new Product({ id: 3, name: 'keyboard', cost: 50 }) const shoppingCar = ShoppingCar.getInstance(); shoppingCar.addProduct(product1); shoppingCar.addProduct(product2); shoppingCar.addProduct(product3); shoppingCar.addProduct(product2); shoppingCar.addProduct(product2); shoppingCar.addProduct(product1); shoppingCar.deleteById(2); console.log(shoppingCar.getShoppingCar()); const shoppingCar2 = ShoppingCar.getInstance(); console.log(shoppingCar2.getShoppingCar()); console.log('Shopping Car 1 y Shopping Car 2 son iguales? ', shoppingCar2 === shoppingCar); ```interface IProduct { id: number; name: string; cost: number;} class Product { private product: IProduct = { id: 0, name: '', cost: 0 } constructor( product: IProduct){ this.product = product } getName(): string { return this.product.name; } getCost(): number { return this.product.cost; } getId(): number { return this.product.id; }} class ShoppingCar { private static instance: ShoppingCar; private products: Product\[] = \[]; private constructor(){ } static getInstance(): ShoppingCar { if(!ShoppingCar.instance){ ShoppingCar.instance = new ShoppingCar(); } return ShoppingCar.instance } addProduct( product: Product) { this.products.push(product); } deleteById( id: number) { const productExist = !!this.products.find((product) => product.getId() === id); if (productExist) { this.products = this.products.filter((prod) => prod.getId() !== id);; } else { console.log(id," doesnt exist"); } } getShoppingCar(){ return this.products; } } const product1: Product = new Product({ id: 1, name: 'laptop', cost: 1000 }) const product2: Product = new Product({ id: 2, name: 'ps5', cost: 700 }) const product3: Product = new Product({ id: 3, name: 'keyboard', cost: 50 }) const shoppingCar = ShoppingCar.getInstance(); shoppingCar.addProduct(product1); shoppingCar.addProduct(product2); shoppingCar.addProduct(product3); shoppingCar.addProduct(product2); shoppingCar.addProduct(product2); shoppingCar.addProduct(product1); shoppingCar.deleteById(2); console.log(shoppingCar.getShoppingCar()); const shoppingCar2 = ShoppingCar.getInstance(); console.log(shoppingCar2.getShoppingCar()); console.log('Shopping Car 1 y Shopping Car 2 son iguales? ', shoppingCar2 === shoppingCar);
Les dejo mi ejercicio en typeScript interface IProduct { id: number; name: string; cost: number;} class Product { private product: IProduct = { id: 0, name: '', cost: 0 } constructor( product: IProduct){ this.product = product } getName(): string { return this.product.name; } getCost(): number { return this.product.cost; } getId(): number { return this.product.id; }} class ShoppingCar { private static instance: ShoppingCar; private products: Product\[] = \[]; private constructor(){ } static getInstance(): ShoppingCar { if(!ShoppingCar.instance){ ShoppingCar.instance = new ShoppingCar(); } return ShoppingCar.instance } addProduct( product: Product) { this.products.push(product); } deleteById( id: number) { const productExist = !!this.products.find((product) => product.getId() === id); if (productExist) { this.products = this.products.filter((prod) => prod.getId() !== id);; } else { console.log(id," doesnt exist"); } } getShoppingCar(){ return this.products; } } const product1: Product = new Product({ id: 1, name: 'laptop', cost: 1000 }) const product2: Product = new Product({ id: 2, name: 'ps5', cost: 700 }) const product3: Product = new Product({ id: 3, name: 'keyboard', cost: 50 }) const shoppingCar = ShoppingCar.getInstance(); shoppingCar.addProduct(product1); shoppingCar.addProduct(product2); shoppingCar.addProduct(product3); shoppingCar.addProduct(product2); shoppingCar.addProduct(product2); shoppingCar.addProduct(product1); shoppingCar.deleteById(2); console.log(shoppingCar.getShoppingCar()); const shoppingCar2 = ShoppingCar.getInstance(); console.log(shoppingCar2.getShoppingCar()); console.log('Shopping Car 1 y Shopping Car 2 son iguales? ', shoppingCar2 === shoppingCar);
Les dejo mi implementaci贸n con TS. **product.ts** ```ts export interface ProductType { id: number; name: string; cost: number; } class Product implements ProductType { id: number; name: string; cost: number; constructor ({ id, name, cost }: ProductType) { this.id = id; this.name = name; this.cost = cost; } static getName(product: ProductType) { return product.name; } static getCost(product: ProductType) { return product.cost; } static getId(product: ProductType) { return product.id; } } export default Product; ```**shopingCart.ts**```ts import Product, { ProductType } from "./product"; export interface ShoppingCartInstance { add(product: ProductType): void; deleteById(product: ProductType): void; showProducts(): void; } const searchElementById = findFn => products => products.find(findFn); class ShoppingCart { private static instance: ShoppingCart; private static products: Product[] = []; constructor() {} static getInstance() { if (!ShoppingCart.instance) { ShoppingCart.instance = new ShoppingCart(); } return ShoppingCart.instance; } public add(product: ProductType) { const newProduct = new Product(product); ShoppingCart.products.push(newProduct); } public deleteById(id: ProductType['id']) { const element = searchElementById((value) => (value.id === id))(ShoppingCart.products); const index = ShoppingCart.products.indexOf(element); if (index !== -1) { ShoppingCart.products.splice(index, 1); } else { console.log('El producto con el ID especificado no se encontr贸 en el carrito.'); } } public showProducts() { ShoppingCart.products.forEach((product) => { console.log(product); }); } } export default ShoppingCart; ``` **clientApp.ts**```ts import { ProductType } from "./product"; import ShoppingCart, { ShoppingCartInstance } from "./shopingCart"; const clientApp = () => { const milk: ProductType = { name: 'Milk', cost: 12, id: 1 }; const eggs: ProductType = { name: 'Eggs', cost: 3, id: 2 }; const ham: ProductType = { name: 'Ham', cost: 20, id: 3 }; const shopingInstance = ShoppingCart.getInstance(); shopingInstance.add(milk); shopingInstance.add(eggs); shopingInstance.add(ham); shopingInstance.showProducts(); console.log('--------------'); shopingInstance.deleteById(2); shopingInstance.showProducts(); console.log('--------------'); }; clientApp(); ```
![](https://static.platzi.com/media/user_upload/2-50581a75-eb5e-410f-b1fe-d1464949dfe7.jpg) ![](https://static.platzi.com/media/user_upload/1-5886255b-2123-4ee1-bae5-0003ce98bfea.jpg)
Les comparto mi soluci贸n. 馃榿 Product.ts ![](https://static.platzi.com/media/user_upload/2-9d34684a-68b7-4069-8a16-64398bb49c18.jpg) ![](https://platzi.com/new-home/clases/6933-patrones-diseno-creacionales/60865-singleton-pros-y-contras/)```ts interface ProductAtributes { id: number; name: string; cost: number; } export class Product { #id: number; #name: string; #cost: number; public constructor({ id, name, cost }: ProductAtributes) { this.#id = id; this.#name = name; this.#cost = cost; } public get name(): string { return this.#name; } public get cost(): number { return this.#cost; } public get id(): number { return this.#id; } } ```ShoppingCart.ts ![](https://static.platzi.com/media/user_upload/1-011030a4-94b8-40a2-8bdc-f9b30b616bfc.jpg) ```ts import { Product } from './Product.ts'; export class ShoppingCart { #products: Product[] = []; static #instance: ShoppingCart; private constructor() {} public getProducts(): Product[] { return this.#products; } public add(product: Product): void { this.#products.push(product); } public deleteById(id: number): void { const INDEX_DELETED = this.#products.findIndex( (product) => product.id === id, ); if (~INDEX_DELETED /* INDEX_DELETED !== -1 */) { this.#products.splice(INDEX_DELETED, 1); } } public static getInstance(): ShoppingCart { if (!this.#instance) { this.#instance = new ShoppingCart(); } return this.#instance; } } ```
Este es mi reto ```js class Product { private id: number; private name: string; private cost: number; constructor(id: number, name: string, cost: number) { this.id = id; this.name = name; this.cost = cost; } getId() { return this.id; } getName() { return this.name; } getCost() { return this.cost; } } class ShoppingCar { private static instance: ShoppingCar; private products: { product: Product; quantity: number; }[] = []; private constructor() {} static getInstance() { if (!ShoppingCar.instance) { ShoppingCar.instance = new ShoppingCar(); } return ShoppingCar.instance; } add(product: Product) { let productIndex = this.products.findIndex( (item) => item.product.getId() === product.getId() ); if (productIndex !== -1) { this.products[productIndex] = { ...this.products[productIndex], quantity: this.products[productIndex].quantity + 1, }; } else { this.products.push({ product, quantity: 1 }); } } deleteById(id: number) { let productIndex = this.products.findIndex( (item) => item.product.getId() === id ); if (productIndex !== -1) { this.products = this.products.filter(({ product }) => product.getId() !== id); } } } function appShoppingCar() { const shoppingCar = ShoppingCar.getInstance(); const product1 = new Product(1, "Product 1", 100); const product2 = new Product(2, "Product 2", 200); shoppingCar.add(product1); shoppingCar.add(product1); shoppingCar.add(product2); shoppingCar.deleteById(product1.getId()); } appShoppingCar(); ```

隆Hola!

Dej茅 mi soluci贸n al reto en TypeScript y en Java en mi repositorio en GitHub, tambi茅n dej茅 un tutorial con el link al repositorio, pero para este reto en Java, se encuentra aqu铆.

El concepto de 鈥渦n solo punto de acceso global鈥 tambi茅n es conocido como Single Source of Truth (煤nica fuente de verdad).

Soluci贸n 馃槃鈥

.
.
.
.

class Product {
  private id: number;
  private name: string;
  private cost: number;

  constructor(id: number, name: string, cost: number) {
    this.id = id;
    this.name = name;
    this.cost = cost;
  }

  public getId(): number {
    return this.id;
  }

  public getName(): string {
    return this.name;
  }

  public getCost(): number {
    return this.cost;
  }
}

class ShoppingCart {
  private static instance: ShoppingCart;
  private products: Product[] = [];

  private constructor() {}

  public addProduct(product: Product) {
    this.products.push(product);
  }

  public deleteById(id: number) {
    const index = this.products.findIndex((item) => item.getId() === id);
    if (index !== -1) {
      this.products.splice(index, 1);
    }
  }

  public static getInstance(): ShoppingCart {
    if (!ShoppingCart.instance) {
      ShoppingCart.instance = new ShoppingCart();
    }
    return ShoppingCart.instance;
  }

  public getProducts(): Product[] {
    return this.products;
  }
}

function shoppingApp() {
  const cart1 = ShoppingCart.getInstance();
  const cart2 = ShoppingCart.getInstance();
  const prod1 = new Product(1, "Apple", 21);
  const prod2 = new Product(2, "Orange", 29);
  const prod3 = new Product(3, "Strawberry", 94);

  cart1.addProduct(prod1);
  cart1.addProduct(prod2);
  cart2.addProduct(prod3);

  console.log(cart1 === cart2);
  console.log(cart1.getProducts());
  console.log(cart2.getProducts());

  cart1.deleteById(3);
  console.log(cart1.getProducts());
  console.log(cart2.getProducts());
}

shoppingApp();

Mi soluci贸n. Solo permite crear una instancia del carrito, por usuario

export class Product {
  constructor(
    private _id: number,
    private _name: string,
    private _cost: number
  ) {}

  get id() {
    return this._id;
  }

  get name() {
    return this._name;
  }

  get cost() {
    return this._cost;
  }
}

export class ShoppingCar {
  private static instances: { [client: string]: ShoppingCar } = {};
  private products: Product[];

  private constructor() {
    this.products = [];
  }

  static getIntance(client: string): ShoppingCar {
    if (!ShoppingCar.instances[client]) {
      ShoppingCar.instances[client] = new ShoppingCar();
    }
    return ShoppingCar.instances[client];
  }

  add(product: Product) {
    this.products.push(product);
  }

  deleteById() {}

  getProducts() {
    return this.products;
  }
}

const ClientApp = () => {
  console.info('馃殌ClientApp:\n');

  /**
   * A pesar de que se intentan crear 4 carror, el sistema solo permite
   * crear un carro por cliente, lo que quiere decir que los 2 carros de
   * Pedro, son el mismo
   */
  const pedroCar = ShoppingCar.getIntance('Pedro');

  const mariaCar = ShoppingCar.getIntance('Maria');

  const pedroCar2 = ShoppingCar.getIntance('Pedro');

  const mariaCar2 = ShoppingCar.getIntance('Maria');

  // Se comparan los carros para validar que solo hay 2
  console.info('pedroCar === pedroCar2:', pedroCar === pedroCar2);
  console.info('mariaCar === mariaCar2:', mariaCar === mariaCar2);

  console.info('pedroCar === mariaCar:', pedroCar === mariaCar);

  // Se crean los productos a agregar
  const camisa = new Product(1, 'Camisa', 1500);
  const pantalon = new Product(2, 'Pantalon', 2000);
  const medias = new Product(3, 'Medias', 300);

  // Agrega productos al carro de Pedro
  pedroCar.add(camisa);
  pedroCar.add(pantalon);
  pedroCar.add(medias);

  // Agrega productos al carro de Mar铆a
  mariaCar.add(medias);

  // Ambos carros son el mismo
  console.info('pedroCar:', pedroCar.getProducts());
  console.info('pedroCar2:', pedroCar2.getProducts());

  // Ambos carros son el mismo
  console.info('mariaCar:', mariaCar.getProducts());
  console.info('mariaCar2:', mariaCar2.getProducts());
};

ClientApp();

Mi c贸digo de TS 馃憤:

class Product {
    private id: number;
    private name: string;
    private price: number;

    constructor(id: number, name: string, price: number) {
        this.id = id;
        this.name = name;
        this.price = price;
    }

    setId(id: number) {
        this.id = id;
    }

    setName(name: string) {
        this.name = name;
    }

    setPrice(price: number) {
        this.price = price;
    }

    getId() {
        return this.id;
    }

    getName() {
        return this.name;
    }

    getPrice() {
        return this.price;
    }
}

/* 
    We create our singleton class, the idea behind having one, is that therere never 2 of these.
    Just one per app or client
*/
class ShoppingCart {
    private static instance: ShoppingCart;
    private products: Product[] = [];

    private constructor() {}

    static getInstance() {
        if(!ShoppingCart.instance) {
            ShoppingCart.instance = new ShoppingCart();
        }
        return ShoppingCart.instance;
    }

    setCart(products: Product[]) {
        this.products = products;
    }

    getCart() {
        return this.products;
    }

    add(product: Product) {
        this.products.push(product);
    }

    addGroup(products: Product[]) {
        // pushes each element of the array 
        products.forEach(prod => this.products.push(prod));
    }

    remove(id: number) {
        this.products = this.products.filter((product) => product.getId() !== id);
    }
}

function app() {
    const cart1 = ShoppingCart.getInstance();
    const cart2 = ShoppingCart.getInstance();

    const products: Product[] = [
        new Product(1, "D贸nde", 100),
        new Product(2, "est谩", 200),
        new Product(3, "Dios", 300)
    ];

    cart1.addGroup(products);
    cart1.remove(1);

    // We never added anything to cart2, but it has the same instance as cart1,
    // so both are equals
    console.log(cart1 === cart2); // true
}

app();