Patrones de Diseño para la Arquitectura de Software

Pregunta Respuesta
1. ¿Qué es un patrón de diseño en la arquitectura de software? Es una solución reutilizable para problemas comunes que surgen durante el diseño de software.
2. ¿Cuál es el propósito del patrón Singleton? Asegurar que una clase tenga una única instancia y proporcionar un punto de acceso global a ella.
3. ¿Cómo implementas el patrón Singleton en Java?
public class Singleton {
    private static Singleton instance;

    private Singleton() { }

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
4. ¿Qué es el patrón Factory Method? Un patrón que define una interfaz para crear objetos, pero deja que las subclases decidan qué clase instanciar.
5. ¿Cómo implementas el patrón Factory Method en Python?
class Product:
    def operation(self):
        pass

class ConcreteProduct(Product):
    def operation(self):
        return "ConcreteProduct"

class Creator:
    def factory_method(self):
        pass

    def some_operation(self):
        product = self.factory_method()
        return f"Creator: {product.operation()}"

class ConcreteCreator(Creator):
    def factory_method(self):
        return ConcreteProduct()
6. ¿Qué es el patrón Observer? Es un patrón que define una relación de dependencia uno a muchos entre objetos, de modo que cuando un objeto cambia de estado, todos sus dependientes son notificados y actualizados automáticamente.
7. ¿Cómo se aplica el patrón Observer en C#?
using System;
using System.Collections.Generic;

public interface IObserver
{
    void Update(string message);
}

public class ConcreteObserver : IObserver
{
    public void Update(string message)
    {
        Console.WriteLine($"Observer received message: {message}");
    }
}

public class Subject
{
    private List observers = new List();

    public void Attach(IObserver observer)
    {
        observers.Add(observer);
    }

    public void Notify(string message)
    {
        foreach (var observer in observers)
        {
            observer.Update(message);
        }
    }
}
8. ¿Qué es el patrón Decorator? Es un patrón que permite agregar funcionalidades a un objeto de manera dinámica sin alterar su estructura.
9. ¿Cómo se aplica el patrón Decorator en TypeScript?
interface Coffee {
    cost(): number;
}

class SimpleCoffee implements Coffee {
    cost(): number {
        return 5;
    }
}

class MilkDecorator implements Coffee {
    private coffee: Coffee;

    constructor(coffee: Coffee) {
        this.coffee = coffee;
    }

    cost(): number {
        return this.coffee.cost() + 2;
    }
}
10. ¿Qué es el patrón Strategy? Es un patrón que define una familia de algoritmos, encapsula cada uno de ellos y los hace intercambiables.
11. ¿Cómo se implementa el patrón Strategy en Java?
public interface Strategy {
    void execute();
}

public class ConcreteStrategyA implements Strategy {
    public void execute() {
        System.out.println("Strategy A");
    }
}

public class Context {
    private Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public void doAction() {
        strategy.execute();
    }
}
12. ¿Qué es el patrón Proxy? Es un patrón que proporciona un sustituto o marcador de posición para otro objeto para controlar el acceso a este último.
13. ¿Cómo se implementa el patrón Proxy en Python?
class RealSubject:
    def request(self):
        return "RealSubject: Handling request."

class Proxy:
    def __init__(self, real_subject):
        self._real_subject = real_subject

    def request(self):
        return f"Proxy: {self._real_subject.request()}"
14. ¿Qué es el patrón Builder? Es un patrón que separa la construcción de un objeto complejo de su representación, de modo que el mismo proceso de construcción puede crear diferentes representaciones.
15. ¿Cómo se aplica el patrón Builder en C#?
public class Product
{
    private List parts = new List();

    public void Add(string part)
    {
        parts.Add(part);
    }
}

public abstract class Builder
{
    public abstract void BuildPartA();
    public abstract void BuildPartB();
    public abstract Product GetResult();
}

public class ConcreteBuilder : Builder
{
    private Product product = new Product();

    public override void BuildPartA()
    {
        product.Add("PartA");
    }

    public override void BuildPartB()
    {
        product.Add("PartB");
    }

    public override Product GetResult()
    {
        return product;
    }
}
16. ¿Qué es el patrón Chain of Responsibility? Es un patrón que permite pasar solicitudes a lo largo de una cadena de objetos receptores, donde cada receptor puede procesar la solicitud o pasarla al siguiente receptor en la cadena.
17. ¿Cómo se aplica el patrón Chain of Responsibility en TypeScript?
interface Handler {
    setNext(handler: Handler): Handler;
    handle(request: string): string;
}

class ConcreteHandlerA implements Handler {
    private nextHandler: Handler;

    setNext(handler: Handler): Handler {
        this.nextHandler = handler;
        return handler;
    }

    handle(request: string): string {
        if (request === 'A') {
            return "Handled by A";
        } else if (this.nextHandler) {
            return this.nextHandler.handle(request);
        }
        return "Not handled";
    }
}
18. ¿Qué es el patrón Adapter? Es un patrón que permite a una interfaz incompatible con otra interfaz funcionar en conjunto, adaptando una interfaz a la que el cliente espera.
19. ¿Cómo se aplica el patrón Adapter en Java?
public interface Target {
    void request();
}

public class Adaptee {
    public void specificRequest() {
        System.out.println("Specific request");
    }
}

public class Adapter implements Target {
    private Adaptee adaptee;

    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    public void request() {
        adaptee.specificRequest();
    }
}
20. ¿Qué es el patrón Composite? Es un patrón que permite a los clientes tratar de manera uniforme objetos individuales y composiciones de objetos.
21. ¿Cómo se implementa el patrón Composite en Python?
class Component:
    def operation(self):
        pass

class Leaf(Component):
    def operation(self):
        return "Leaf"

class Composite(Component):
    def __init__(self):
        self.children = []

    def add(self, component):
        self.children.append(component)

    def operation(self):
        return [child.operation() for child in self.children]
22. ¿Qué es el patrón Command? Es un patrón que encapsula una solicitud como un objeto, permitiendo parametrizar clientes con diferentes solicitudes, encolar solicitudes y soportar operaciones de deshacer.
23. ¿Cómo se aplica el patrón Command en C#?
public interface ICommand
{
    void Execute();
}

public class ConcreteCommand : ICommand
{
    public void Execute()
    {
        Console.WriteLine("Command executed");
    }
}

public class Invoker
{
    private ICommand command;

    public void SetCommand(ICommand command)
    {
        this.command = command;
    }

    public void ExecuteCommand()
    {
        command.Execute();
    }
}
24. ¿Qué es el patrón Template Method? Es un patrón que define el esqueleto de un algoritmo en una operación, dejando algunos pasos a las subclases.
25. ¿Cómo se aplica el patrón Template Method en Java?
public abstract class AbstractClass {
    public void templateMethod() {
        stepOne();
        stepTwo();
    }

    protected abstract void stepOne();
    protected abstract void stepTwo();
}

public class ConcreteClass extends AbstractClass {
    protected void stepOne() {
        System.out.println("Step One");
    }

    protected void stepTwo() {
        System.out.println("Step Two");
    }
}
26. ¿Qué es el patrón Memento? Es un patrón que permite capturar y externalizar el estado interno de un objeto sin violar la encapsulación, de modo que el objeto pueda ser restaurado a dicho estado más tarde.
27. ¿Cómo se aplica el patrón Memento en Python?
class Memento:
    def __init__(self, state):
        self._state = state

    def get_state(self):
        return self._state

class Originator:
    def __init__(self, state):
        self._state = state

    def create_memento(self):
        return Memento(self._state)

    def restore(self, memento):
        self._state = memento.get_state()

class Caretaker:
    def __init__(self):
        self._memento = None

    def save_memento(self, memento):
        self._memento = memento

    def get_memento(self):
        return self._memento
28. ¿Qué es el patrón State? Es un patrón que permite a un objeto cambiar su comportamiento cuando su estado interno cambia, pareciendo que el objeto ha cambiado de clase.
29. ¿Cómo se aplica el patrón State en C#?
public interface IState
{
    void Handle(Context context);
}

public class ConcreteStateA : IState
{
    public void Handle(Context context)
    {
        context.State = new ConcreteStateB();
    }
}

public class ConcreteStateB : IState
{
    public void Handle(Context context)
    {
        context.State = new ConcreteStateA();
    }
}

public class Context
{
    public IState State { get; set; }
}
30. ¿Qué es el patrón Iterator? Es un patrón que proporciona una forma de acceder a los elementos de un objeto agregado secuencialmente sin exponer su representación subyacente.
31. ¿Cómo se aplica el patrón Iterator en Java?
import java.util.Iterator;
import java.util.ArrayList;
import java.util.List;

public class IteratorPattern {
    public interface Iterator {
        boolean hasNext();
        T next();
    }

    public class ConcreteIterator implements Iterator {
        private List items;
        private int position;

        public ConcreteIterator(List items) {
            this.items = items;
            this.position = 0;
        }

        public boolean hasNext() {
            return position < items.size();
        }

        public String next() {
            return items.get(position++);
        }
    }
}
32. ¿Qué es el patrón Flyweight? Es un patrón que usa el compartimiento de objetos para soportar un gran número de objetos de grano fino de manera eficiente.
33. ¿Cómo se aplica el patrón Flyweight en Python?
class Flyweight:
    def __init__(self, intrinsic_state):
        self._intrinsic_state = intrinsic_state

    def operation(self, extrinsic_state):
        return f"Intrinsic: {self._intrinsic_state}, Extrinsic: {extrinsic_state}"

class FlyweightFactory:
    def __init__(self):
        self._flyweights = {}

    def get_flyweight(self, key):
        if key not in self._flyweights:
            self._flyweights[key] = Flyweight(key)
        return self._flyweights[key]
34. ¿Qué es el patrón Proxy? Es un patrón que proporciona un sustituto o marcador de posición para otro objeto para controlar el acceso a este último.
35. ¿Cómo se aplica el patrón Proxy en Java?
public interface Subject {
    void Request();
}

public class RealSubject implements Subject {
    public void Request() {
        System.out.println("RealSubject: Handling request.");
    }
}

public class Proxy implements Subject {
    private RealSubject realSubject;

    public void Request() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        realSubject.Request();
    }
}
36. ¿Qué es el patrón Bridge? Es un patrón que separa una abstracción de su implementación, de modo que ambas puedan variar independientemente.
37. ¿Cómo se aplica el patrón Bridge en C#?
public interface Implementor
{
    void Operation();
}

public class ConcreteImplementorA : Implementor
{
    public void Operation()
    {
        Console.WriteLine("ConcreteImplementorA Operation");
    }
}

public class Abstraction
{
    protected Implementor implementor;

    public Abstraction(Implementor implementor)
    {
        this.implementor = implementor;
    }

    public void Operation()
    {
        implementor.Operation();
    }
}
38. ¿Qué es el patrón Mediator? Es un patrón que define un objeto que encapsula cómo interactúan un conjunto de objetos, promoviendo el desacoplamiento.
39. ¿Cómo se aplica el patrón Mediator en TypeScript?
interface Mediator {
    notify(sender: object, event: string): void;
}

class ConcreteMediator implements Mediator {
    private colleague1: Colleague1;
    private colleague2: Colleague2;

    setColleague1(colleague: Colleague1) {
        this.colleague1 = colleague;
    }

    setColleague2(colleague: Colleague2) {
        this.colleague2 = colleague;
    }

    notify(sender: object, event: string): void {
        if (sender === this.colleague1) {
            console.log("Mediator reacts on Colleague1 event.");
        }
    }
}

class Colleague1 {
    private mediator: Mediator;

    constructor(mediator: Mediator) {
        this.mediator = mediator;
    }

    doSomething() {
        this.mediator.notify(this, "event1");
    }
}
40. ¿Qué es el patrón Visitor? Es un patrón que permite definir nuevas operaciones sobre una estructura de objetos sin cambiar los objetos sobre los que opera.
41. ¿Cómo se aplica el patrón Visitor en Python?
class Element:
    def accept(self, visitor):
        pass

class ConcreteElementA(Element):
    def accept(self, visitor):
        visitor.visit_concrete_element_a(self)

class Visitor:
    def visit_concrete_element_a(self, element):
        print("Visited ConcreteElementA")

class ConcreteVisitor(Visitor):
    def visit_concrete_element_a(self, element):
        print("ConcreteVisitor visited ConcreteElementA")
42. ¿Qué es el patrón Chain of Responsibility? Es un patrón que permite pasar una solicitud a lo largo de una cadena de manejadores, donde cada manejador puede procesar la solicitud o pasarla al siguiente manejador en la cadena.
43. ¿Cómo se aplica el patrón Chain of Responsibility en C#?
public abstract class Handler
{
    protected Handler successor;

    public void SetSuccessor(Handler successor)
    {
        this.successor = successor;
    }

    public abstract void HandleRequest(string request);
}

public class ConcreteHandlerA : Handler
{
    public override void HandleRequest(string request)
    {
        if (request == "A")
        {
            Console.WriteLine("ConcreteHandlerA handled request A.");
        }
        else if (successor != null)
        {
            successor.HandleRequest(request);
        }
    }
}
44. ¿Qué es el patrón Builder? Es un patrón que permite construir un objeto complejo paso a paso. Permite crear diferentes representaciones de un objeto utilizando el mismo proceso de construcción.
45. ¿Cómo se aplica el patrón Builder en Java?
public class Product {
    private String partA;
    private String partB;

    public void setPartA(String partA) {
        this.partA = partA;
    }

    public void setPartB(String partB) {
        this.partB = partB;
    }
}

public abstract class Builder {
    protected Product product = new Product();

    public abstract void buildPartA();
    public abstract void buildPartB();
    public Product getResult() {
        return product;
    }
}

public class ConcreteBuilder extends Builder {
    public void buildPartA() {
        product.setPartA("Part A");
    }

    public void buildPartB() {
        product.setPartB("Part B");
    }
}

public class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    public void construct() {
        builder.buildPartA();
        builder.buildPartB();
    }
}
46. ¿Qué es el patrón Abstract Factory? Es un patrón que proporciona una interfaz para crear familias de objetos relacionados sin especificar sus clases concretas.
47. ¿Cómo se aplica el patrón Abstract Factory en Python?
class AbstractFactory:
    def create_product_a(self):
        pass

    def create_product_b(self):
        pass

class ConcreteFactory1(AbstractFactory):
    def create_product_a(self):
        return ProductA1()

    def create_product_b(self):
        return ProductB1()

class ConcreteFactory2(AbstractFactory):
    def create_product_a(self):
        return ProductA2()

    def create_product_b(self):
        return ProductB2()
48. ¿Qué es el patrón Prototype? Es un patrón que permite crear nuevos objetos copiando un prototipo existente, en lugar de crear nuevos objetos desde cero.
49. ¿Cómo se aplica el patrón Prototype en Java?
public abstract class Prototype implements Cloneable {
    public abstract Prototype clone();
}

public class ConcretePrototype extends Prototype {
    private String field;

    public ConcretePrototype(String field) {
        this.field = field;
    }

    public String getField() {
        return field;
    }

    public void setField(String field) {
        this.field = field;
    }

    @Override
    public ConcretePrototype clone() {
        try {
            return (ConcretePrototype) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}
50. ¿Qué es el patrón Composite? Es un patrón que permite componer objetos en estructuras de árbol para representar jerarquías parte-todo. Permite tratar objetos individuales y compuestos de manera uniforme.