Menu
Coddy logo textTech

Constructores de fábrica

Parte de la sección Programación Orientada a Objetos del Journey de Dart de Coddy. Lección 14 de 110.

Un constructor de fábrica es un constructor especial que no siempre crea una instancia nueva. A diferencia de los constructores habituales, un constructor de fábrica puede devolver una instancia existente, un subtipo o incluso null (si admite valores nulos). Se declara mediante la palabra clave factory.

class Logger {
  static final Logger _instance = Logger._internal();
  
  // Constructor nombrado privado
  Logger._internal();
  
  // Constructor factory
  factory Logger() {
    return _instance;
  }
}

Logger log1 = Logger();
Logger log2 = Logger();
print(identical(log1, log2)); // true

En este ejemplo, el constructor de fábrica siempre devuelve la misma instancia. No importa cuántas veces llames a Logger(), obtienes el objeto idéntico. Este patrón se usa comúnmente para implementar singletons.

Los constructores de fábrica se diferencian de los constructores normales en un aspecto clave: no tienen acceso a this porque es posible que ni siquiera creen una instancia nueva. En su lugar, deben devolver explícitamente un objeto:

class Shape {
  factory Shape(String type) {
    if (type == 'circle') return Circle();
    if (type == 'square') return Square();
    return Rectangle();
  }
}

class Circle extends Shape { Circle() : super._(); }
class Square extends Shape { Square() : super._(); }
class Rectangle extends Shape { Rectangle() : super._(); }

Los constructores de fábrica son útiles cuando necesitas controlar la creación de instancias, como devolver objetos almacenados en caché, implementar grupos de objetos o decidir qué subtipo instanciar en función de los parámetros de entrada.

challenge icon

Desafío

Fácil

Construyamos un sistema de notificaciones que use constructores de fábrica para crear diferentes tipos de notificaciones basándose en una entrada de cadena simple.

Crearás dos archivos para organizar tu código:

  • notification.dart: Define una clase Notification que sirva como base para todos los tipos de notificación. Tu clase debe tener:
    • Un campo String message
    • Un constructor con nombre privado Notification._internal que inicialice el mensaje
    • Un constructor de fábrica Notification(String type, String message) que devuelva diferentes subtipos de notificación según el parámetro type:
      • Si type es 'email', devuelve un EmailNotification
      • Si type es 'sms', devuelve un SMSNotification
      • De lo contrario, devuelve un PushNotification
    • Un método send() que imprima Sending: [message]

En el mismo archivo, crea tres subclases que extiendan Notification:

  • EmailNotification: Sobrescribe send() para imprimir Email: [message]
  • SMSNotification: Sobrescribe send() para imprimir SMS: [message]
  • PushNotification: Sobrescribe send() para imprimir Push: [message]

Cada subclase necesita un constructor que reciba un message y lo pase a la clase padre mediante super._internal(message).

  • main.dart: Importa tu clase de notificación y crea tres notificaciones usando el constructor de fábrica:
    • Una notificación por correo electrónico con el mensaje 'Welcome!'
    • Una notificación SMS con el mensaje 'Your code is 1234'
    • Una notificación push con el mensaje 'New update available'
    Llama a send() en cada notificación en el orden indicado anteriormente.

Salida esperada:

Email: Welcome!
SMS: Your code is 1234
Push: New update available

Pruébalo tú mismo

import 'notification.dart';

void main() {
  // TODO: Crea una notificación de email con el mensaje 'Welcome!'
  
  // TODO: Create an SMS notification with message 'Your code is 1234'
  
  // TODO: Create a push notification with message 'New update available'
  
  // TODO: Llama a send() en cada notificación en orden
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de Dart online