Carlos Obregón
Java Champion with 15 years of experience in software programming
Marzo 2021
*Un poco simplificado
*Un poco simplificado
@Test
@DisplayName("Vínculo Interno, empieza con /")
void invariantesVínculoInterno() {
assertAll("Invariantes",
() -> assertEquals(URL_INTERNO, this.vínculoInterno.getUrl()),
() -> assertEquals(TEXTO_VÍNCULO, this.vínculoInterno.getTexto()),
() -> assertEquals(TARGET_VACÍO, this.vínculoInterno.getTarget())
);
}
@Test
@DisplayName("Vínculo Externo, empieza con http")
void invariantesVínculoExterno() {
assertAll("Invariantes",
() -> assertEquals(URL_EXTERNO, this.vínculoExterno.getUrl()),
() -> assertEquals(TEXTO_VÍNCULO, this.vínculoExterno.getTexto()),
() -> assertEquals(TARGET_BLANK, this.vínculoExterno.getTarget())
);
}
@Test
@DisplayName("Invariantes de un Vínculo Email, contiene @")
void invariantesVínculoEmail() {
assertAll("Invariantes",
() -> assertEquals(String.format("mailto:%s", EMAIL), this.vínculoEmail.getUrl()),
() -> assertEquals(TEXTO_VÍNCULO, this.vínculoEmail.getTexto()),
() -> assertEquals(TARGET_BLANK, this.vínculoEmail.getTarget())
);
}
@Test
@DisplayName("Invariantes de un Vínculo Teléfono, empieza con +")
void invariantesVínculoTeléfono() {
assertAll("Invariantes",
() -> assertEquals(String.format("tel:%s", TELÉFONO), this.vínculoTeléfono.getUrl()),
() -> assertEquals(TEXTO_VÍNCULO, this.vínculoTeléfono.getTexto()),
() -> assertEquals(TARGET_VACÍO, this.vínculoTeléfono.getTarget())
);
}
<a href="${vínculo.url}" target="${vínculo.target}">${vínculo.texto}</a>
*Después veremos la mejor manera de lograrlo
*Después veremos la mejor manera de lograrlo
public interface Vínculo {
String getUrl();
String getTexto();
String getTarget();
}
public abstract class AbstractVínculo implements Vínculo {
private final String url;
private final String texto;
public AbstractVínculo(final String url, final String texto) {
this.url = Objects.requireNonNull(url);
this.texto = Objects.requireNonNull(texto);
}
@Override
public final String getUrl() {
return url;
}
@Override
public final String getTexto() {
return texto;
}
}
public abstract class AbstractVínculoInterno extends AbstractVínculo {
public AbstractVínculoInterno(final String url, final String texto) {
super(url, texto);
}
public final String getTarget() {
return "";
}
}
public final class VínculoInterno extends AbstractVínculoInterno {
public VínculoInterno(final String url, final String texto) {
super(url, texto);
}
}
public final class VínculoTeléfono extends AbstractVínculoInterno {
public VínculoTeléfono(final String url, final String texto) {
super(String.format("tel:%s", url), texto);
}
public VínculoTeléfono(final String url) {
this(url, url);
}
}
public abstract class AbstractVínculoExterno extends AbstractVínculo {
public AbstractVínculoExterno(final String url, final String texto) {
super(url, texto);
}
public final String getTarget() {
return "_blank";
}
}
public final class VínculoExterno extends AbstractVínculoExterno {
public VínculoInterno(final String url, final String texto) {
super(url, texto);
}
}
public final class VínculoEmail extends AbstractVínculoExterno {
public VínculoEmail(final String url, final String texto) {
super(String.format("mailto:%s", url), texto);
}
public VínculoEmail(final String url) {
this(url, url);
}
}
public final class Coordenada {
private final double latitud;
private final double longitud;
public Coordenada(double latitud, double longitud) {
this.latitud = validoDentroDelRango(latitud, -90.0, 90.0);
this.longitud = validoDentroDelRango(longitud, -180.0, 180.0);
}
public double getLatitud() {
return latitud;
}
public double getLongitud() {
return longitud;
}
// código
}
public final class Ubicación extends Coordenada {
// más parámetros
public Ubicación(double latitud, double longitud) {
super(latitud, longitud);
// más código
}
}
Ubicación ubicación = new Ubicación(4.6056727, -74.0642803);
ubicación.latitud();
ubicación.longitud();
public final class Ubicación {
private final Coordenada coordenada;
public Ubicación(double latitud, double longitud) {
// reutilización del código de Coordenada
this.coordenada = new Coordenada(latitud, longitud);
}
// delegación
public double latitud() {
return coordenada.getLatitud();
}
public double longitud() {
return coordenada.getLongitud();
}
}
Ubicación ubicación = new Ubicación(4.6056727, -74.0642803);
ubicación.latitud();
ubicación.longitud();
public interface Vínculo {
String getUrl();
String getTexto();
String getTarget();
public static Vínculo de(final String url, final String texto) {
if (url.startsWith("/")) {
return new VínculoInterno(url, texto);
}
if (url.startsWith("http")) {
return new VínculoExterno(url, texto);
}
if (url.startsWith("+")) {
return texto.isBlank() ? new VínculoTeléfono(url) : new VínculoTeléfono(url, texto);
}
if (url.contains("@")) {
return texto.isBlank() ? new VínculoEmail(url) : new VínculoEmail(url, texto);
}
throw new AssertionError(String.format("URL con formato no reconocido: %s", url));
}
}
public sealed interface Vínculo permits AbstractVínculo {
String getUrl();
String getTexto();
String getTarget();
}
public abstract sealed class AbstractVínculo implements Vínculo
permits AbstractVínculoInterno, AbstractVínculoExterno {
private String url;
private String texto;
public AbstractVínculo(final String url, final String texto) {
this.url = Objects.requireNonNull(url);
this.texto = Objects.requireNonNull(texto);
}
@Override
public final String getUrl() {
return url;
}
@Override
public final String getTexto() {
return texto;
}
}
public sealed abstract class AbstractVínculoInterno
extends AbstractVínculo permits VínculoInterno, VínculoTeléfono {
public AbstractVínculoInterno(final String url, final String texto) {
super(url, texto);
}
public final String getTarget() {
return "";
}
}
public sealed abstract class AbstractVínculoExterno
extends AbstractVínculo permits VínculoExterno, VínculoEmail {
public AbstractVínculoExterno(final String url, final String texto) {
super(url, texto);
}
public final String getTarget() {
return "_blank";
}
}
By Carlos Obregón
Introducción a Principios SOLID y Patrones de Diseño: Herencia, Interfaces y Clases Abstractas en Java