Como curiosidad una prueba que hice ayer, estuve casi 3h de entrevistas, era refactorizar codigo y arreglar cosas.
Me dieron un codigo que tenia entre otras cosas un strategy pattern y dije, "pff esto es una mierda xq X,Y,Z, luego lo quito." Y el entrevistador: "si claro es la idea jajaja".
Entrevista junior: haz un patron de diseño
Entrevista senior: quita el patron de diseño
jajaj @Canary_r00lz si que es importante saberse los patrones... algunos son buenos, otros son malos. asi que hay que hacer los buenos, y evitar los malos. y sobretodo hay que entender como implementarlos.
Otro patron que me salió era que el código estaba en paralelo y tenia un sistema con canales, y dije de aplicar un worker pool de X manera, que eso era mi recomendación siempre para empezar y dejarse de cosas raras. el codgio estaba haciendo el paralelismo con alguna cosa rara de buffered channels y no era un worker pool, sino que era 1:1 y bloqueaba el main además...
Otro patron, buena practica, regla que me salio que se os tiene que quedar a fuego, que al entrevistador le gusto mucho es. Regla de oro: una interface con 1 metodo, puede ser una funcion. Esto es una regla / patron de la programación funcional, si tienes una interface asi puedes en su lugar pasarle una lambda y se usa mucho en todos los lenguajes python, js, java, c#... No siempre se cumple y a veces te interesa tener la interface, por ejemplo un Reader/Writer, pero por lo general es un patron que hay que saber.
Os dejo unos codigo snippet en python de ejemplo
strategy pattern enumfrom enum import Enum
class Strategy(Enum):
AGGRESSIVE = "aggressive"
DEFENSIVE = "defensive"
BALANCED = "balanced"
class Request:
id: int
strategy: Strategy
def __init__(self, id: int, strategy: Strategy):
self.id = id
self.strategy = strategy
def run(self):
if self.strategy == Strategy.AGGRESSIVE:
print(f"Request {self.id} is aggressive")
elif self.strategy == Strategy.DEFENSIVE:
print(f"Request {self.id} is defensive")
elif self.strategy == Strategy.BALANCED:
print(f"Request {self.id} is balanced")
def main():
r = Request(id=1, strategy=Strategy.AGGRESSIVE)
r.run()
if __name__ == "__main__":
main()
strategy con interface de 1 metodofrom abc import ABC, abstractmethod
class Strategy(ABC):
@abstractmethod
def execute(self, request_id: int) -> None:
pass
class AggressiveStrategy(Strategy):
def execute(self, request_id: int) -> None:
print(f"Request {request_id} is aggressive")
class DefensiveStrategy(Strategy):
def execute(self, request_id: int) -> None:
print(f"Request {request_id} is defensive")
class BalancedStrategy(Strategy):
def execute(self, request_id: int) -> None:
print(f"Request {request_id} is balanced")
class Request:
def init(self, id: int, strategy: Strategy):
self.id = id
self.strategy = strategy
def run(self):
self.strategy.execute(self.id)
def main():
r = Request(id=1, strategy=AggressiveStrategy())
r.run()
if name == "main":
main()
strategy con 1 lambda en lugar de 1 interface y clasesfrom typing import Callable
class Request:
def __init__(self, id: int, strategy: Callable[[int], None]):
self.id = id
self.strategy = strategy
def run(self):
self.strategy(self.id)
def main():
strategies = {
"aggressive": lambda request_id: print(f"Request {request_id} is aggressive"),
"defensive": lambda request_id: print(f"Request {request_id} is defensive"),
"balanced": lambda request_id: print(f"Request {request_id} is balanced"),
}
r = Request(id=1, strategy=strategies["aggressive"])
r.run()
if __name__ == "__main__":
main()
y bueno, la respuesta buena no os la digo, os la dejo para deberes, cual es la mejor implementación del patron de diseño "strategy" para resolver esto. pero bueno, los ejemplos que he puesto os deberían dar una pista.