馃攲 Adapter


Ejemplo Practico

Supongamos que tienes un sistema de figuras geom茅tricas 2D y deseas extenderlo para manejar figuras 3D. Las figuras 3D tienen m茅todos distintos para dibujar y moverse (por ejemplo, 3dDraw() y 3dMove()). Podr铆as crear un adaptador que permita manejar estas figuras 3D como si fueran figuras 2D, proporcionando as铆 una interfaz uniforme en el editor de figuras.

Este patr贸n es especialmente 煤til en sistemas donde no puedes controlar el c贸digo fuente de las clases que necesitas usar, facilitando la integraci贸n y la extensibilidad sin modificar el comportamiento existente.

SistemaImplementaci贸n a Agregar
imageimage

Transformaci贸n

Ahora que sabemos cual es el problema y no podemos modificar nada, vamos a crear un adaptador entre los dos sistemas. El adapter termina heredando los meotodos de la interfaz que se quiere adaptar.

SistemaImplementaci贸n a Agregar
imageimage

Una vez que entendemos este concepto, vamos a identificar los respectivos roles futuras explicaciones.

Estructura

image

Ejemplo: Integraci贸n de figuras 3D en un sistema de figuras 2D

Escenario: Supongamos que tienes un sistema de edici贸n gr谩fico que hasta ahora ha trabajado solo con figuras 2D (como c铆rculos y rect谩ngulos), y necesitas extenderlo para soportar figuras 3D (como esferas y cubos). El sistema de figuras 2D utiliza m茅todos como draw() y move(). Las figuras 3D, en cambio, tienen m茅todos como draw3D() y move3D().

Objetivo: Queremos que las figuras 3D sean tratadas como figuras 2D por el editor gr谩fico, sin cambiar la interfaz de usuario ni el c贸digo del cliente que maneja las figuras 2D.

Descripci贸n de los componentes:

  1. Target (Figura2D):

    • Esta es la interfaz que el cliente espera usar. Define m茅todos como draw() y move().
  2. Client (Editor):

    • Utiliza objetos que implementan la interfaz Figura2D. Este cliente quiere usar figuras 3D pero sin alterar su forma de interactuar con figuras 2D.
  3. Adapter (Adaptador3D):

    • Implementa la interfaz Figura2D y adapta la interfaz de las figuras 3D al mundo de las figuras 2D.
    • Contiene una instancia de Figura3D y traduce las llamadas de los m茅todos draw() y move() de la interfaz Figura2D a draw3D() y move3D() respectivamente.
  4. Adaptee (Figura3D):

    • Clase que define una interfaz que necesita ser adaptada para ser utilizada por el cliente. En este caso, Figura3D tiene m茅todos como draw3D() y move3D() que son incompatibles directamente con el sistema existente de figuras 2D.

Funcionamiento:

  • Cuando el Editor (cliente) necesita dibujar o mover una figura, llama a draw() o move() en la interfaz Figura2D.
  • El Adaptador3D recibe estas llamadas y las traduce a draw3D() y move3D() del objeto Figura3D.
  • La Figura3D realiza las acciones necesarias y el resultado se refleja en la interfaz del usuario como si se estuviese manejando una figura 2D convencional.

Este enfoque permite que el sistema original de figuras 2D se extienda a nuevas dimensiones sin alterar el c贸digo cliente existente, garantizando que los nuevos tipos de figuras se integren de manera transparente y manteniendo la cohesi贸n y modularidad del sistema.

Ejemplo Practico

Usted ha implementado una clase Media player, para reproducir archivos de audio y video en formatos que usted ha dise帽ado. Cada Media se puede reproducir con el mensaje play(). Para continuar con el desarrollo, usted desea incorporar la posibilidad de reproducir Video Stream. Para ello, dispone de la clase VideoStream que pertenece a una libreri虂a de terceros y usted no puede ni debe modificarla. El desaf铆o que se le presenta es hacer que la clase MediaPlayer pueda interactuar con la clase VideoStream. La situaci贸n se resume en el siguiente diagrama UML:

image

Tareas:

  • Modifique el diagrama de clases UML para considerar los cambios necesarios. Si utiliza patrones de dise帽o indique los roles en las clases utilizando estereotipos.
  • Implemente en Java

Diagrama

image

El uml lo corregi pero el codigo no

AudioMedia
public class Audio extends Media{
	
	public String play() {
		String nombre = "audio";
		return nombre;
	}
}
public class Media {
	public String play() {
		String nombre = "media";
		return nombre;
	}
}
VideoFileVideoStream
public class VideoFile extends Media{
	public String play() {
		String nombre = "video file";
		return nombre;
	}
}
public class VideoStream extends VideoFile{
	public String reproduce() {
		String nombre = "video stream";
		return nombre;
	}
}

adapterVideoStream

public class adapterVideoStream extends VideoFile{
	private VideoStream vs = new VideoStream();
	
	public String play() {
		return vs.reproduce();
	}
}

MediaPlayer

public class MediaPlayer {
	private List<Media> media = new ArrayList<Media>(); 
	
	public void play() {
		System.out.println("Play");
	}
	
	public void agregarMedia(Media m) {
		this.media.add(m);
	}
	
	public String concatenarNombresMedia() {
        String nombresConcatenados = "";
        for (int i = 0; i < media.size(); i++) {
            nombresConcatenados += media.get(i).play(); 
            if (i < media.size() - 1) {
                nombresConcatenados += ", "; 
            }
        }
        return nombresConcatenados;
    }
}

Test

public class MediaPlayerTest {
	
	MediaPlayer mp;
	Audio a;
	VideoFile vf;
	VideoStream vs;
	AdapterVideoStream adapter;
	
	@BeforeEach
	void setUp() throws Exception {
		mp = new MediaPlayer();
		a = new Audio();
		vf = new VideoFile();
		adapter = new AdapterVideoStream();
		
		mp.agregarMedia(a);
		mp.agregarMedia(vf);
		mp.agregarMedia(adapter);
	}
	
    @Test
    public void testNombreCompleto() {
    	assertEquals("audio, video file, video stream", mp.concatenarNombresMedia());
    }
}