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.
Introduccion
Dónde estamos y hacia dónde vamos
Patrones creacionales
Singleton
Singleton 101
Implementación de Singleton en JS
Contrastemos: Singleton con TS
Singleton: pros y contras
Factory
Factory 101
Diagrama de implementación de Factory
Implementación de Factory en JS
Contrastemos: Factory en TS
Factory: pros y contras
Abstract Factory
Abstract Factory 101
Diagrama de implementación de Abstract Factory
Implementación de Abstract Factory en JS
Contrastemos: Abstract Factory en TS
Abstract Factory: pros y contras
Builder
Builder 101
Diagrama de implementación de Builder
Implementación de Builder en JS
Contrastemos: Builder en TS
Builder: pros y contras
Prototype
Prototype 101
Diagrama de implementación de Prototype
Implementación de Prototype en JS
Contrastemos: Prototype en TS
Prototype: pros y contras
Conclusiones
¿Qué sigue sobre patrones de diseño?
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Aportes 15
Preguntas 0
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.
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());
})();
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();
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());
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();
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()
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, '#######')
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();
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()}`);
});
El concepto de “un solo punto de acceso global” también es conocido como Single Source of Truth (única fuente de verdad).
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())
})()
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?
o inicia sesión.