POO-ITBA / 2024_01

Consultas 1C 2024
0 stars 0 forks source link

Recuperatorio 2022 1C - Ejercicio 3 #15

Closed lmoliveto closed 2 months ago

lmoliveto commented 3 months ago

Hola! En el enum creé dos métodos: uno para setear la promoción actual y otro para calcular los puntos. Y guardo el valor original de la promoción y el actual en variables de instancia, para así no perder el original y aplicar sobre él las nuevas promociones. Y desde CoffeeCard invoco primero a la función para setear la actual promoción y luego a la función para calcular los puntos. En la solución hace todo con un método sobre el valor original de la promoción.

Otra diferencia que hay entre mi código y el de la respuesta es que yo no guardé el valor inicial del id en CoffeeRewards. Cuando aumenta para la próxima CoffeeCard lo hace sobre la misma variable.

Quería saber si está mal haberlo hecho de esta forma.


public enum CardType{
    WELCOME(10, 0),
    GREEN(30, 5),
    GOLD(50, 10);

    private final int originalPointPerDollar, extraPoints;
    private int currentPointPerDollar;

    CardType(int originalPointPerDollar, int extraPoints){
        this.originalPointPerDollar = originalPointPerDollar;
        this.currentPointPerDollar = originalPointPerDollar;
        this.extraPoints = extraPoints;
    }

    public int calculatePoints(int amount){
        return amount * currentPointPerDollar + extraPoints;
    }

    public void setPromotion(Function<Double, Double> promotion){
        currentPointPerDollar = promotion(originalPointPerDollar);
    }
}

public class CoffeeCard{
    private final String client;
    private final CardType type;
    private int points;
    private final int id;
    private final CoffeeRewards coffeeRewards;

    public Card(String client, CardType type, int id, CoffeeRewards coffeeRewards){
        this.client = client;
        this.type = type;
        this.id = id;
        this.coffeeRewards = coffeeRewards;
    }

    public void purchase(Double amount){
        type.setPromotion(coffeeRewards.getPromotion());
        points += type.calculatePoints(amount);
    }

    @Override
    public String toString(){
        return "CoffeeCard %d from %s with %d points".formatted(id, client, points);
    }
}

public class CoffeeRewards{
    private static int id = 1001;
    private Function<Double, Double> promotion;

    public CoffeeRewards(Function<Double, Double> promotion){
        this.promotion = promotion;
    }

    public CoffeeCard buildCard(String client, CardType type){
        return new CoffeeCard(client, type, id++, this);
    }

    public void setPointsPromotion(Function<Double, Double> newPromotion){
        promotion = newPromotion;
    }

    public Function<Double, Double> getPromotion(){
        return promotion;
    }
}
fmeola commented 3 months ago

Hola @lmoliveto Tenemos que evitar estar seteando estado interno en un enum. No es un buen diseño que el enum tenga una variable de instancia que vos seteás desde afuera. Además el hecho de hacer

type.setPromotion(coffeeRewards.getPromotion());
points += type.calculatePoints(amount);

te indica que en realidad podría ser un único método publico que hace las dos cosas. Mejor recibilo por parámetro como está planteado en la solución.

Respecto a la numeración está bien. La diferencia que veo es que tenés el 1001 directamente (como un magic number) mientras que en la solución declara una constante. Acordate que si tiene el modificador static y final es porque está definiendo una constante.

Lo demás lo veo muy bien.

lmoliveto commented 3 months ago

Entonces está bien tener el magic number? O sería mejor tener una constante por separado para inicializar la variable que después aumento?

fmeola commented 3 months ago

No, siempre es mejor tener una constante