英文:
Abstract builder
问题
所以我有一个抽象的Transaction类,它有多个实现(Payment、File)。
我想为Transaction(抽象)+实现者创建一个构建器。
我做了这个:
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();
}
PaymentBuilder类的示例:
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;
}
}
每个字段都有getter/setter,Transaction类如下:
public abstract class Transaction
{
//用于序列化
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();
}
如何使用:
Payment payment = new PaymentBuilder(from, to, amount)
.setPreviousHash(previousHash)
.build();
但是,当我调用setSignature()时,我收到“类型不匹配:无法从Transaction转换为Payment”,所以我需要将其转换为Payment,如何避免这种情况?能避免吗?
英文:
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?
答案1
得分: 1
你可以将你的抽象构建器做成通用的,其中通用类型是它生成的交易类型。
public abstract class TransactionBuilder<T extends Transaction> {
...
public abstract T build();
}
public class PaymentBuilder extends TransactionBuilder<Payment> {
@Override
public Payment build() {
...
}
}
英文:
You could make your abstract builder generic, with the generic type being the type of transaction it produces.
public abstract class TransactionBuilder<T extends Transaction> {
...
public abstract T build();
}
public class PaymentBuilder extends TransactionBuilder<Payment> {
@Override
public Payment build() {
...
}
}
答案2
得分: 0
感谢 @khelwood,我最终使我的抽象构建器通用化:
TransactionBuilder:
public abstract class TransactionBuilder<T extends Transaction>
{
protected final T transaction;
public TransactionBuilder(T transaction)
{
this.transaction = transaction;
}
public TransactionBuilder<T> setSignature(byte[] signature)
{
this.transaction.setSignature(signature);
return this;
}
public TransactionBuilder<T> setPreviousHash(String previousHash)
{
this.transaction.setPreviousHash(previousHash);
return this;
}
public abstract T build();
}
PaymentBuilder:
public class PaymentBuilder extends TransactionBuilder<Payment>
{
public PaymentBuilder(String from, String to, double amount)
{
super(new Payment(from, to, amount));
}
public PaymentBuilder addAmount(double amount)
{
this.transaction.amount += amount;
}
@Override
public Payment build()
{
return this.transaction;
}
}
英文:
Thanks to @khelwood, I ended up making my abstract builder generic:
TransactionBuilder:
public abstract class TransactionBuilder<T extends Transaction>
{
protected final T transaction;
public TransactionBuilder(T transaction)
{
this.transaction = transaction;
}
public TransactionBuilder<T> setSignature(byte[] signature)
{
this.transaction.setSignature(signature);
return this;
}
public TransactionBuilder<T> setPreviousHash(String previousHash)
{
this.transaction.setPreviousHash(previousHash);
return this;
}
public abstract T build();
}
PaymentBuilder:
public class PaymentBuilder extends TransactionBuilder<Payment>
{
public PaymentBuilder(String from, String to, double amount)
{
super(new Payment(from, to, amount));
}
public PaymentBuilder addAmount(double amount)
{
this.transaction.amount += amount;
}
@Override
public Payment build()
{
return this.transaction;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论