0Pricing
Clean Architecture & Design Patterns in Practice · Lección

Puertos de entrada y salida

Comprenda cómo los puertos de entrada y salida (interfaces) definen los límites de comunicación entre los casos de uso y las capas externas.

Puertos de entrada y salida es una lección gratuita de Clean Architecture & Design Patterns in Practice en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Clean Architecture & Design Patterns in Practice, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Clean Architecture & Design Patterns in Practice incluye 4 lecciones en total.

Partes de esta lección aún no han sido traducidas y se muestran en inglés.

What are Input & Output Ports?

In Clean Architecture, "Ports" are crucial interfaces that define how different layers communicate. They act like contracts.

Think of them as the "sockets" of your application's core logic. They specify what goes in (Input) and what comes out (Output).

Defining Input Ports

An Input Port is an interface defined by the Use Case layer. It declares the methods that an external layer (like a UI controller) can call to interact with the Use Case.

  • It's the "what you can do" contract for the Use Case.
  • It ensures the Use Case doesn't know about the UI or external callers.

Input Port: User Login

Here's a simple Input Port for a user login feature. It defines the operations the Use Case expects.

public interface UserLoginInputPort {
  void login(String username, String password);
}

public class UserLoginUseCase implements UserLoginInputPort {
  @Override
  public void login(String username, String password) {
    // Business logic for login
    System.out.println("Attempting login for: " + username);
    if (username.equals("admin") && password.equals("pass")) {
      System.out.println("Login successful!");
    } else {
      System.out.println("Login failed.");
    }
  }

  public static void main(String[] args) {
    UserLoginInputPort loginService = new UserLoginUseCase();
    loginService.login("admin", "pass");
    loginService.login("user", "123");
  }
}

Defining Output Ports

An Output Port is also an interface, defined by the Use Case layer. It declares the methods that the Use Case will call to deliver results or interact with external services (like a database or UI presenter).

  • It's the "what I need to tell you" contract.
  • It keeps the Use Case unaware of specific implementations (e.g., how results are displayed).

Output Port: Login Presenter

This Output Port defines how the login result should be presented or handled. The Use Case calls these methods, but doesn't know how they are implemented.

public interface UserLoginOutputPort {
  void presentLoginSuccess(String username);
  void presentLoginFailure(String message);
}

public class ConsolePresenter implements UserLoginOutputPort {
  @Override
  public void presentLoginSuccess(String username) {
    System.out.println("Welcome, " + username + "!");
  }

  @Override
  public void presentLoginFailure(String message) {
    System.out.println("Error: " + message);
  }

  public static void main(String[] args) {
    UserLoginOutputPort presenter = new ConsolePresenter();
    presenter.presentLoginSuccess("Alice");
    presenter.presentLoginFailure("Invalid credentials.");
  }
}

How Use Cases Use Ports

The Use Case (or Interactor) depends on these port interfaces. It takes an Input Port as its public method and receives an Output Port through its constructor or method parameters.

This means the Use Case only knows about abstractions, not concrete implementations.

Use Case Connecting Ports

Here, our UserLoginUseCase now uses both ports. Notice it doesn't know if it's talking to a web UI, a mobile app, or a console!

public interface UserLoginInputPort {
  void login(String username, String password);
}

public interface UserLoginOutputPort {
  void presentLoginSuccess(String username);
  void presentLoginFailure(String message);
}

public class UserLoginUseCase implements UserLoginInputPort {
  private final UserLoginOutputPort outputPort;

  public UserLoginUseCase(UserLoginOutputPort outputPort) {
    this.outputPort = outputPort;
  }

  @Override
  public void login(String username, String password) {
    if (username.equals("admin") && password.equals("pass")) {
      outputPort.presentLoginSuccess(username);
    } else {
      outputPort.presentLoginFailure("Invalid credentials.");
    }
  }

  public static void main(String[] args) {
    // In real app, this would be wired by a framework
    UserLoginOutputPort presenter = new ConsolePresenter(); // From Scene 5
    UserLoginInputPort loginService = new UserLoginUseCase(presenter);

    loginService.login("admin", "pass");
    loginService.login("user", "wrong");
  }
}

class ConsolePresenter implements UserLoginOutputPort {
  @Override
  public void presentLoginSuccess(String username) {
    System.out.println("Welcome, " + username + "!");
  }

  @Override
  public void presentLoginFailure(String message) {
    System.out.println("Error: " + message);
  }
}

Ports and the Dependency Rule

The use of Ports perfectly adheres to the Dependency Rule. The Use Case layer (core business logic) depends on interfaces (the Ports).

The outer layers (like UI or databases) then implement these interfaces, providing the concrete details without the core knowing about them.

Why Use Ports?

Ports offer powerful advantages:

  • Decoupling: The Use Case is isolated from UI, database, or external services.
  • Testability: You can easily mock or stub these interfaces for robust unit testing of Use Cases.
  • Flexibility: You can swap out implementations (e.g., change database) without touching core logic.
  • Clarity: They clearly define the boundaries and interactions of your application's core.

Quick Check: Port Roles

Consider the roles of Input and Output Ports in Clean Architecture.

Recap: Ports as Boundaries

We learned that Input Ports are interfaces defining what a Use Case expects, acting as entry points.

Output Ports are interfaces defining what a Use Case delivers or needs from external services.

Together, they enforce the Dependency Rule, ensuring our core business logic remains independent, testable, and flexible.

Preguntas frecuentes

¿La lección «Puertos de entrada y salida» es gratis?

Sí — el texto completo de «Puertos de entrada y salida» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Clean Architecture & Design Patterns in Practice, actualiza a CoddyKit PRO. El curso de Clean Architecture & Design Patterns in Practice incluye 4 lecciones en total.

¿Qué aprenderé en «Puertos de entrada y salida»?

Comprenda cómo los puertos de entrada y salida (interfaces) definen los límites de comunicación entre los casos de uso y las capas externas. Practicas Clean Architecture & Design Patterns in Practice con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Clean Architecture & Design Patterns in Practice?

No se requiere experiencia previa. Clean Architecture & Design Patterns in Practice en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.

¿Cuánto tiempo toma la lección «Puertos de entrada y salida»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Clean Architecture & Design Patterns in Practice?

Sí. Cada lección de Clean Architecture & Design Patterns in Practice incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. Diseño de entidades de negocio
  2. Implementación de casos de uso (interactores)
  3. Puertos de entrada y salida
  4. Aplicación de reglas de negocio con invariantes
← Volver a Clean Architecture & Design Patterns in Practice