mercredi 29 juillet 2020

Abstract builder

So I have an abstract Transaction class, which has multiple implementations (Payment, File).

I would like to have a builder for the Transaction (abstract) + the implementor.

I did this:

public abstract class TransactionBuilder
{
    protected final Transaction transaction;
    
    public TransactionBuilder(Transaction transaction)
    {
        this.transaction = transaction;
    }
    
    public TransactionBuilder setSignature(byte[] signature)
    {
        this.transaction.setSignature(signature);
        return this;
    }
    
    public TransactionBuilder setPreviousHash(String previousHash)
    {
        this.transaction.setPreviousHash(previousHash);
        return this;
    }
    
    public abstract Transaction build();
}

Example for the PaymentBuilder class:

public class PaymentBuilder extends TransactionBuilder
{
    public PaymentBuilder(String from, String to, double amount)
    {
        super(new Payment(from, to, amount));
    }
    
    public PaymentBuilder addAmount(double amount)
    {
        ((Payment) this.transaction).amount += amount;
    }
    
    @Override
    public Payment build()
    {
        return (Payment) this.transaction;
    }
}

Every field has a getter/setter, Transaction:

public abstract class Transaction
{
    //Used for serialization
    private String type;
    
    private String previousTransactionHash;
    private String hash;
    private String signature;
    
    private String fromAddress;
    private String toAddress;
    
    private Instant timeStamp;
    
    public Transaction(String type, String from, String to)
    {
        this.type = type;
        this.fromAddress = from;
        this.toAddress = to;
        this.timeStamp = Instant.now();

        setHash();
    }

How I use:

Payment payment = new PaymentBuilder(from, to, amount)
                .setPreviousHash(previousHash)
                .build();

But when I call setSignature() I get "Type mismatch: cannot convert from Transaction to Payment" so I need to cast it to a Payment, how can I avoid that? Can I?

Aucun commentaire:

Enregistrer un commentaire