porrasmdz / proyectoGrupo8

Este es el repositorio del proyecto del curso de Programacion Orientada a Objetos del Grupo 8 del paralelo 2 en ESPOL.
0 stars 0 forks source link

LSP e ISP #1

Open kazp058 opened 2 years ago

kazp058 commented 2 years ago

En el código se identifica un error de LSP ya que se busca guardar en un archivo cada tipo de vehículo, al ser vehículo una clase padre de otras subclases de vehículos originalmente se ha escrito por cada clase una función para poder hacer el guardado del archivo, esto no es conveniente ni eficiente y puede generar errores al momento de querer reemplazar las instancia de Vehículo con su subtipo, ya que no generaría el mismo resultado, adicionalmente esta implementación original provocaría a futuro dificultades para mantener el código o hacer cambios.

Vehiculo:

public void saveFile(String filename) {
        try(PrintWriter pw = new PrintWriter(new FileOutputStream(new File(filename), true)))
        {        pw.println(this.id+","+"Vehiculo"+","+this.placa+","+this.marca+","+this.modelo+
                    ","+this.tipo_motor+","+this.anio+","+this.recorrido+","+this.color+
                    ","+this.tipo_combustible+","+this.precio);
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
        }
    }

Carro:

@Override
    public void saveFile(String filename)
    {
        try(PrintWriter pw = new PrintWriter(new FileOutputStream(new File(filename), true)))
        {
          pw.println(this.id+","+"Carro"+","+this.placa+","+this.marca+","+this.modelo+
                    ","+this.tipo_motor+","+this.anio+","+this.recorrido+","+this.color+
      ","+this.tipo_combustible+","+this.precio+","+this.vidrios+","+this.transmision);
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
        }
    }

Este patron se repite al resto de clases.

Para arreglar eso sugiero:

  1. Implementar una interfaz sobre la clase padre para concatenar los datos.
  2. Remover la sobreescritura del metodo saveFile en las clases hijas de Vehiculo.

Para el primer paso la creacion de la interfaz seria asi:

public interface Collectable {
    public abstract StringBuilder collectData();
    public abstract void saveFile(String filename, StringBuilder sb);
}

Ahora la implementacion de esta interfaz podria ocacionar problemas con el Principio de Segregacion de Interfaces, para evitar aquello se pueden separar las interfacez o simplemente restringuir la implementacion del metodo saveFile en la clase Vehiculos.

Para lo que Vehiculos luciria asi:

public class Vehiculo implements Collectable{
    @Override
    public StringBuilder collectData() {
        StringBuilder ou = new StringBuilder();
        ou.append(this.placa).append(",");
        ou.append(this.marca).append(",");
        ou.append(this.modelo).append(",");
        ou.append(this.tipo_motor).append(",");
        ou.append(this.anio).append(",");
        ou.append(this.recorrido).append(",");
        ou.append(this.color).append(",");
        ou.append(this.tipo_combustible).append(",");
        ou.append(this.precio);
        return ou;
    }

    public void saveFile(String filename, StringBuilder sb){
        try(PrintWriter pw = new PrintWriter(new FileOutputStream(new File(filename), true))){   
            pw.println(sb.toString());
        }
        catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
 }

Y la implementacion de las demas clases seria algo parecido a esto:

public class Moto extends Vehiculo
{
    @Override
    public StringBuilder collectData() {
        StringBuilder ou = new StringBuilder();
        ou.append(this.id).append(",");
        ou.append("Moto").append(",");

        ou.append(self.collectData()).append("\n");

        return ou;
    }
    public static void registrarMoto(Scanner entrada, String filename) {
        Vehiculo v = Vehiculo.crearVehiculo(entrada, filename);
        if (v !=null){
            Vehiculo mo = new Moto(v.getId(),v.getPlaca(),v.getMarca(),
                v.getModelo(),v.getTipo_motor(),v.getAnio(),v.getRecorrido(),
                v.getColor(),v.getTipo_combustible(),v.getPrecio());
                mo.saveFile(filename, mo.collectData());
        }
        else{
            System.out.println("Vehiculo ya registrado");
        }
    }  
}