Estoy tratando de diseñar una API que implique reservar una transacción al sistema. El sistema generará una ID de transacción que identifica de forma exclusiva la transacción.

Me gustaría definir la clase Transacción como inmutable, así:

public class Transaction {
    private final double quantity;
    private final BigDecimal price;

    public Order(double quantity, BigDecimal price) {
        this.quantity = quantity;
        this.price = price;
    }

    public double getQuantity() {
        return quantity;
    }

    public BigDecimal getPrice() {
        return price;
    }
}

El cliente llama a la API para crear una nueva transacción:

public void storeTransaction(Transaction t)

Pero si hago esto, ¿cómo puedo almacenar la ID de transacción generada?

1. Opción 1

Puedo agregar un estado mutable a la clase de transacción:

public class Transaction {
    private final double quantity;
    private final BigDecimal price;
    private String transactionID;

    public Order(double quantity, BigDecimal price) {
        this.quantity = quantity;
        this.price = price;
    }

    public double getQuantity() {
        return quantity;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public String getTransactionID() {
        return transactionID;
    }

    public void setTransactionID(String id) {
        transactionID = id;
    }
}

Pero esto hará que la clase Transaction sea mutable.

Opción 2

Puedo seguir usando la Transacción inmutable y exponer la API de esta manera:

public String storeTransaction(Transaction t)

Entonces, en lugar de guardar la identificación de la transacción en la clase Transacción, podría devolverla a nuestro usuario API. Pero esto tampoco me parece perfecto porque el usuario debe mantener una relación ID-> Transacción.

¿Cuál es la mejor práctica para diseñar este tipo de escenario?

0
ZZZ 10 may. 2019 a las 01:22

3 respuestas

La mejor respuesta

Puede generar la identificación en su constructor:

public class Transaction {
    private final double quantity;
    private final BigDecimal price;
    private String transactionID;

    public Order(double quantity, BigDecimal price) {
        this.transactionID = this.generateID();
        this.quantity = quantity;
        this.price = price;
    }
}

Ahora solo implemente un método generateID() para completar los detalles.

1
Code-Apprentice 9 may. 2019 a las 22:35

Su método storeTransaction() podría devolver la transacción guardada que también contenía la identificación.

public Transaction storeTransaction(Transaction t) {
    ...
}

Y su clase Transaction podría tener dos constructores, uno con la identificación de la transacción (para cuando se conoce) y otro sin él.

Su método storeTransaction() podría guardar la transacción sin una identificación presente o si una identificación estaba presente:

  1. lanzar una excepción si desea mantener sus transacciones inmutables en su base de datos o
  2. actualice la transacción existente si no necesita inmutabilidad en la base de datos.

El método storeTransaction() devolvería un nuevo objeto Transacción que contiene todos los detalles de la transacción guardada (si no arrojó una excepción, por supuesto).

1
Jason 9 may. 2019 a las 22:31

Bueno, finalizarlo no lo hace tan inmutable. Es bastante fácil cambiar un campo final en Java, incluso más fácil que acceder a un campo privado. Por lo tanto, crearía un campo mutable, pero su configurador solo funciona si el campo actualmente es nulo. Por lo tanto, solo puede configurarlo una vez (cuando se genera). Si el campo no es nulo, puede lanzar un IllegalStateException

-1
Florian 9 may. 2019 a las 22:40