Este es el comienzo de una serie de blogs sobre patrones de diseño. En este blog, discutiremos el primer tipo de patrón de diseño, los Patrones Creacionales. Aquí se analizarán los tipos que se incluyen en los patrones creacionales con algunos ejemplos del mundo real. Usaré Java como mi idioma de selección.
Los patrones de diseño desempeñan un papel crucial en el desarrollo de software, proporcionando soluciones comprobadas a problemas comunes y promoviendo las mejores prácticas. Son como planos prediseñados que puedes personalizar para resolver un problema de diseño recurrente en tu código.
En la programación orientada a objetos, los patrones de diseño creacional juegan un papel importante ya que hacen posible que la instanciación de objetos se separe de su utilización, aumentando así la flexibilidad y escalabilidad de la creación de objetos. Esta publicación de blog se centrará en cinco tipos principales de patrones de diseño creacional: Método de fábrica, Fábrica abstracta, Constructor, Prototipo y Singleton. Para mostrar cómo funciona cada uno, usaremos ejemplos del mundo real en Java.
1. Método de fábrica
El patrón Factory Method define una interfaz para crear un objeto pero permite que las subclases alteren el tipo de objetos que se crearán. Este patrón admite un acoplamiento flexible en Java para evitar la necesidad de vincular clases específicas de la aplicación al código.
Escenario de la vida real: considere una empresa de logística que transporta mercancías utilizando varios vehículos, como camiones y barcos. El tipo de vehículo depende del modo de transporte requerido.
// Product Interface interface Transport { void deliver(); } // Concrete Products class Truck implements Transport { @Override public void deliver() { System.out.println("Deliver by land in a truck."); } } class Ship implements Transport { @Override public void deliver() { System.out.println("Deliver by sea in a ship."); } } // Creator abstract class Logistics { public abstract Transport createTransport(); public void planDelivery() { Transport transport = createTransport(); transport.deliver(); } } // Concrete Creators class RoadLogistics extends Logistics { @Override public Transport createTransport() { return new Truck(); } } class SeaLogistics extends Logistics { @Override public Transport createTransport() { return new Ship(); } } // let's call the main class public class Main { public static void main(String[] args) { Logistics logistics = new RoadLogistics(); logistics.planDelivery(); logistics = new SeaLogistics(); logistics.planDelivery(); } }
2. Fábrica abstracta
El patrón Abstract Factory proporciona una interfaz para crear familias de objetos relacionados o dependientes sin especificar sus clases concretas. Es útil cuando el sistema necesita ser independiente de cómo se crean sus objetos.
Escenario de la vida real: imagina una tienda de muebles que vende diferentes tipos de juegos de muebles, como victorianos y modernos. Cada conjunto incluye productos como sillas y sofás.
// Abstract Products interface Chair { void sitOn(); } interface Sofa { void lieOn(); } // Concrete Products class VictorianChair implements Chair { @Override public void sitOn() { System.out.println("Sitting on a Victorian chair."); } } class ModernChair implements Chair { @Override public void sitOn() { System.out.println("Sitting on a Modern chair."); } } class VictorianSofa implements Sofa { @Override public void lieOn() { System.out.println("Lying on a Victorian sofa."); } } class ModernSofa implements Sofa { @Override public void lieOn() { System.out.println("Lying on a Modern sofa."); } } // Abstract Factory interface FurnitureFactory { Chair createChair(); Sofa createSofa(); } // Concrete Factories class VictorianFurnitureFactory implements FurnitureFactory { @Override public Chair createChair() { return new VictorianChair(); } @Override public Sofa createSofa() { return new VictorianSofa(); } } class ModernFurnitureFactory implements FurnitureFactory { @Override public Chair createChair() { return new ModernChair(); } @Override public Sofa createSofa() { return new ModernSofa(); } } // Client code public class Main { private static void createFurniture(FurnitureFactory factory) { Chair chair = factory.createChair(); Sofa sofa = factory.createSofa(); chair.sitOn(); sofa.lieOn(); } public static void main(String[] args) { FurnitureFactory victorianFactory = new VictorianFurnitureFactory(); createFurniture(victorianFactory); FurnitureFactory modernFactory = new ModernFurnitureFactory(); createFurniture(modernFactory); } }
3. Constructor
El patrón Builder separa la construcción de un objeto complejo de su representación, permitiendo que el mismo proceso de construcción cree diferentes representaciones. Es particularmente útil para crear objetos con muchos atributos opcionales.
Escenario de la vida real: considere un sistema de pedido de pizzas en línea donde los clientes pueden personalizar sus pizzas con varios ingredientes, tamaños y tipos de corteza.
// Product class Pizza { private String dough = ""; private String sauce = ""; private String topping = ""; public void setDough(String dough) { this.dough = dough; } public void setSauce(String sauce) { this.sauce = sauce; } public void setTopping(String topping) { this.topping = topping; } @Override public String toString() { return "Pizza [dough=" dough ", sauce=" sauce ", topping=" topping "]"; } } // Builder Interface interface PizzaBuilder { void buildDough(); void buildSauce(); void buildTopping(); Pizza getPizza(); } // Concrete Builders class HawaiianPizzaBuilder implements PizzaBuilder { private Pizza pizza; public HawaiianPizzaBuilder() { this.pizza = new Pizza(); } @Override public void buildDough() { pizza.setDough("cross"); } @Override public void buildSauce() { pizza.setSauce("mild"); } @Override public void buildTopping() { pizza.setTopping("ham pineapple"); } @Override public Pizza getPizza() { return this.pizza; } } class SpicyPizzaBuilder implements PizzaBuilder { private Pizza pizza; public SpicyPizzaBuilder() { this.pizza = new Pizza(); } @Override public void buildDough() { pizza.setDough("pan baked"); } @Override public void buildSauce() { pizza.setSauce("hot"); } @Override public void buildTopping() { pizza.setTopping("pepperoni salami"); } @Override public Pizza getPizza() { return this.pizza; } } // Director class Waiter { private PizzaBuilder pizzaBuilder; public void setPizzaBuilder(PizzaBuilder pb) { pizzaBuilder = pb; } public Pizza getPizza() { return pizzaBuilder.getPizza(); } public void constructPizza() { pizzaBuilder.buildDough(); pizzaBuilder.buildSauce(); pizzaBuilder.buildTopping(); } } // Client code public class Main { public static void main(String[] args) { Waiter waiter = new Waiter(); PizzaBuilder hawaiianPizzaBuilder = new HawaiianPizzaBuilder(); PizzaBuilder spicyPizzaBuilder = new SpicyPizzaBuilder(); waiter.setPizzaBuilder(hawaiianPizzaBuilder); waiter.constructPizza(); Pizza pizza1 = waiter.getPizza(); System.out.println("Pizza built: " pizza1); waiter.setPizzaBuilder(spicyPizzaBuilder); waiter.constructPizza(); Pizza pizza2 = waiter.getPizza(); System.out.println("Pizza built: " pizza2); } }
4. Prototipo
El patrón Prototipo se utiliza para crear un nuevo objeto copiando un objeto existente, conocido como prototipo. Este patrón es útil cuando el costo de crear un nuevo objeto es elevado.
Escenario de la vida real: piensa en un editor gráfico donde puedas crear, duplicar y editar formas.
import java.util.HashMap; import java.util.Map; // Prototype abstract class Shape implements Cloneable { private String id; protected String type; abstract void draw(); public String getType() { return type; } public String getId() { return id; } public void setId(String id) { this.id = id; } public Object clone() { Object clone = null; try { clone = super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return clone; } } // Concrete Prototypes class Rectangle extends Shape { public Rectangle() { type = "Rectangle"; } @Override public void draw() { System.out.println("Drawing a Rectangle."); } } class Circle extends Shape { public Circle() { type = "Circle"; } @Override public void draw() { System.out.println("Drawing a Circle."); } } // Prototype Registry class ShapeCache { private static MapshapeMap = new HashMap(); public static Shape getShape(String shapeId) { Shape cachedShape = shapeMap.get(shapeId); return (Shape) cachedShape.clone(); } public static void loadCache() { Rectangle rectangle = new Rectangle(); rectangle.setId("1"); shapeMap.put(rectangle.getId(), rectangle); Circle circle = new Circle(); circle.setId("2"); shapeMap.put(circle.getId(), circle); } } // Client code public class Main { public static void main(String[] args) { ShapeCache.loadCache(); Shape clonedShape1 = ShapeCache.getShape("1"); System.out.println("Shape: " clonedShape1.getType()); Shape clonedShape2 = ShapeCache.getShape("2"); System.out.println("Shape: " clonedShape2.getType()); } }
5. Semifallo
El patrón Singleton garantiza que una clase tenga solo una instancia y proporciona un punto global de acceso a ella. Este patrón se usa comúnmente para registros, almacenamiento en caché y grupos de subprocesos.
Escenario de la vida real: imagine una cola de impresión donde solo una instancia debe administrar todos los trabajos de impresión.
class PrinterSpooler { private static PrinterSpooler instance; private PrinterSpooler() { // private constructor to prevent instantiation } public static PrinterSpooler getInstance() { if (instance == null) { instance = new PrinterSpooler(); } return instance; } public void print(String document) { System.out.println("Printing document: " document); } } // Client code public class Main { public static void main(String[] args) { PrinterSpooler spooler1 = PrinterSpooler.getInstance(); PrinterSpooler spooler2 = PrinterSpooler.getInstance(); spooler1.print("Document 1"); spooler2.print("Document 2"); System.out.println("Are both spoolers the same instance? " (spooler1 == spooler2)); } }
https://refactoring.guru/
https://www.javatpoint.com/design-patterns-in-java
https://www.digitalocean.com/community/tutorials/java-design-patterns-example-tutorial
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3