I have a question about interfaces and their use, first I tell them about my problem
Here is an example with two pieces of particular actions (these objects are what I want to pass as parameters but in a generic way)
public class AccionUno{
private BigInteger idAccionUno;
private Date fechaDeElaboracion;
private String observaciones;
private String necesidadesDeInformacion;
private String guiaAsignada;
//getters y setters
}
public class AccionDos{
private BigInteger idAccionDos;
private List<String> hechos;
private String descripcion
//getters y setters
}
Here is an example of the interface and the problem lies in how to abstract a parameter of a generic type that represents all my actions
public interface Accionable{
public void registrarAccion(Accion accion);
public void borrarAccion(Accion accion);
public void editarAccion(Accion accion);
public Accion consultarAccion(Accion accion);
}
And I would like to implement them in the following way
public class AccionUnoImplementacion implements Accionable{
public void registrarAccion(Accion accion){
//Registrar accion uno
}
public void borrarAccion(Accion accion){
//Borrar accion uno
}
public void editarAccion(Accion accion){
//Editar accion uno
}
public Accion consultarAccion(Accion accion){
//Consultar accion uno
}
}
public class AccionDosImplementacion implements Accionable{
public void registrarAccion(Accion accion){
//Registrar accion dos
}
public void borrarAccion(Accion accion){
//Borrar accion dos
}
public void editarAccion(Accion accion){
//Editar accion dos
}
public Accion consultarAccion(Accion accion){
//Consultar accion dos
}
}
I tried to do it by overwriting the specific parameters for example
public void registrarAccion(AccionUno accion);
public void registrarAccion(AccionDos accion);
But the problem with that is that already to make it common I have to break the principle of segregation of interfaces since each client that occupies this interface must implement the n methods even if you only need one
Also try generic with this link
The justification for the solution I'm looking for is to comply with the open / close principle because if it could be achieved, I would not care how many actions are added, everything specific to each implementation would be well separated from the abstraction of what a action can do
Having said the above, I would like to know if there is any way to:
EDIT According to what you mention in the comments, I came to this solution, so I do not know what they think or if they have some kind of failure or some improvement, could something similar with interfaces be achieved? as the Duck typing of Ruby
A Parent Class called Action, NOTESE NOT ONLY GET AND SET, CLASSES CONTAIN ENCAPSULATION LOGIC FOR EACH ONE
public class Accion {
private int idAccion;
private String observaciones;
//getters y setters
/*
Inicio Logica de encapsulación de esta clase
*/
private boolean sonObservacionesNulas() {
if (observaciones != null) {
return sonObservacionesVacias();
}
return true;
}
private boolean sonObservacionesVacias() {
return observaciones.trim().isEmpty();
}
/*
Fin Logica de encapsulacion de esta clase
*/
}
A daughter class called AccionUno that extends Action
public class AccionUno extends Accion {
private Set<String> necesidades;
//getters y setters
/*
Inicio Logica de encapsulacion de esta clase
*/
public boolean sonNecesidadesValidas() {
return sonNecesidadesNulas();
}
private boolean sonNecesidadesNulas() {
if (necesidades != null) {
return sonNecesidadesVacias();
}
return true;
}
private boolean sonNecesidadesVacias() {
return necesidades.isEmpty();
}
/*
Fin Logica de encapsulacion de esta clase
*/
}
A daughter class called AccionDos that extends Action
public class AccionDos extends Accion {
private Integer numeroDePersonasBeneficiadas;
private String hechos;
//getters y setters
/*
Inicio Logica de encapsulacion de esta clase
*/
public boolean sonHechosValidas() {
return sonHechosNulos();
}
private boolean sonHechosNulos() {
if (hechos != null) {
return sonHechosVacias();
}
return true;
}
private boolean sonHechosVacias() {
return hechos.trim().isEmpty();
}
/*
Fin Logica de encapsulacion de esta clase
*/
}
A generic interface that receives the parent class Action as a parameter
public interface Accionable<T extends Accion> {
public void registrarAccion(T accion);
public Accion consultatAccion(T accion);
public void validarAccion(T accion);
}
An implementation class corresponding to the ActionDos
public class AccionDosImplementacion implements Accionable<AccionDos> {
@Override
public void registrarAccion(AccionDos accion) {
System.out.println("#################################");
System.out.println("Logica especifica para registrar una accion DOS en bd");
accion.setIdAccion(1);
accion.setNumeroDePersonasBeneficiadas(2);
if (accion.getNumeroDePersonasBeneficiadas() >= 2) {
System.out.println("Haz esto");
} else {
System.out.println("Esto otro");
}
accion.setHechos("hechos");
accion.setObservaciones("observaciones");
System.out.println("Registrar accion en tabla especifica de accion DOS");
}
@Override
public Accion consultatAccion(AccionDos accion) {
System.out.println("Buscar en base de datos accionDos en particular");
return accion;
}
@Override
public void validarAccion(AccionDos accion) {
System.out.println("Buscar en base de datos accionDOS en particular para validar");
System.out.println("Validar accion");
System.out.println("#################################");
}
}
An implementation class corresponding to the Action One
public class AccionUnoImplementacion implements Accionable<AccionUno> {
@Override
public void registrarAccion(AccionUno accion) {
System.out.println("#################################");
System.out.println("Logica especifica para registrar una accion uno en bd");
accion.setIdAccion(1);
Set<String> necesidades = new HashSet<>();
necesidades.add("necesidadUno");
necesidades.add("necesidadDos");
accion.setNecesidades(necesidades);
accion.setObservaciones("observaciones");
System.out.println("Registrar accion en tabla especifica de accion uno");
}
@Override
public Accion consultatAccion(AccionUno accion) {
System.out.println("Buscar en base de datos accion en particular");
return accion;
}
@Override
public void validarAccion(AccionUno accion) {
System.out.println("Buscar en base de datos accion en particular para validar");
System.out.println("Validar accion");
System.out.println("#################################");
}
}
Customer
public class BeanAccionN {
public static void main(String[] args) {
//Empiezan comportamiento polimorfico con AccionUno
Accionable accionable = new AccionUnoImplementacion();
Accion accion = new AccionUno();
registrar(accion, accionable);
consultar(accion, accionable);
validar(accion, accionable);
//Empiezan comportamiento polimorfico con AccionDos
accionable = new AccionDosImplementacion();
accion = new AccionDos();
registrar(accion, accionable);
consultar(accion, accionable);
validar(accion, accionable);
}
private static void registrar(Accion accion, Accionable accionable) {
accionable.registrarAccion(accion);
}
private static void validar(Accion accion, Accionable accionable) {
accionable.validarAccion(accion);
}
private static void consultar(Accion accion, Accionable accionable) {
accionable.consultatAccion(accion);
}
}