英文:
Generifying generic object Java
问题
我有一个CrudRepository
,这是一个接口,我在我的Spring Boot应用程序中用它来执行针对DynamoDB的CRUD操作。
我的问题是,我有一个嵌套对象(用Java类表示)。
我创建了一个只包含所有DynamoDB对象共享的Id
的抽象类。
public abstract class DynamoDBEntry {
private String id;
@DynamoDBHashKey
@DynamoDBAutoGeneratedKey
public String getId() {
return id;
}
public DynamoDBEntry() {
}
}
然后我有两个子类,它们从这个类继承。
@DynamoDBTable(tableName = "BankCustomer")
public class Customer extends DynamoDBEntry {
...
}
@DynamoDBTable(tableName = "CustomerTransaction")
public class Transaction extends DynamoDBEntry {
...
}
我的问题出现在Crud存储库中,我想要泛型化嵌套属性。
到目前为止,我有一个类似这样的模式
通过在接口中指定Type
、Identifier
和Attribute
(嵌套对象)。
public interface CrudRepository<T, I, A> {
public I create(T t);
public I delete(I i);
public I update(I i, T t);
public T get(I identifier);
public List<T> getAll();
public List<A> getAllAttributes(I identifier);
public String createAttribute(A attribute);
}
但是我希望使用我的抽象类来实现更通用的方法,以便它可以适用于所有类型的类。
类似这样的方式:
public List<? extends DynamoDBEntry> getAllAttributes(I identifier);
public String createAttribute(A<? extends DynamoDBEntry> attribute);
是否可以实现这一点,对于这种情况下的最佳实践是什么?
英文:
I have a CrudRepository
, which is an interface, that I use to Create CRUD operations against DynamoDB in my Spring boot application.
My problem now is that I have a nested object (represented as Java Classes).
I have made an abstract class that only contains the Id
which is shared among all DynamoDB objects.
public abstract class DynamoDBEntry {
private String id;
@DynamoDBHashKey
@DynamoDBAutoGeneratedKey
public String getId() {
return id;
}
public DynamoDBEntry() {
}
}
I then have two subclasses which extends
from this class.
@DynamoDBTable(tableName = "BankCustomer")
public class Customer extends DynamoDBEntry {
...
}
@DynamoDBTable(tableName = "CustomerTransaction")
public class Transaction extends DynamoDBEntry {
...
}
My problem comes in my Crud repository where i want to generify the nested attributes.
So far i have a pattern like this
by specifying Type
Identifier
and Attribute
(nested objects) in an interface like this.
public interface CrudRepository<T, I, A> {
public I create(T t);
public I delete(I i);
public I update (I i, T t);
public T get(I identifier);
public List<T> getAll();
public List<A> getAllAttributes(I identifier);
public String createAttribute(A attribute);
}
But instead I wanted to use my Abstract Class to make a more generic aproach, so that it could be by all types of classes.
Something like this:
public List<? extends DynamoDBEntry> getAllAttributes(I identifier);
public String createAttribute(A<? extends DynamoDBEntry> attribute);
Could this be achieved, and what would be best practise in this case?
答案1
得分: 2
以下是您提供的代码的翻译部分:
public interface CrudRepository<T extends Type<?>, I extends Identifier<?>, A extends Attribute<? extends DynamoDBEntry>> {
public I create(T t);
public I delete(I i);
public I update(I i, T t);
public T get(I identifier);
public List<T> getAll();
public List<A> getAllAttributes(I identifier);
public String createAttribute(A attribute);
}
public class CustomerRepository implements CrudRepository<WTFisT, LongIdentifier, CustomerAttribute> {
private Map<Long, Customer> customers = new HashMap<>();
private Map<Long, WTFisT> wtfs = new HashMap<>();
@Override
public LongIdentifier create(WTFisT t) { wtfs.put(666L, t); return new LongIdentifier(666L); }
@Override
public LongIdentifier delete(LongIdentifier i) { return i; }
@Override
public LongIdentifier update(LongIdentifier i, WTFisT t) { wtfs.put(i.useId(), t); return i; }
@Override
public WTFisT get(LongIdentifier identifier) { return wtfs.get(identifier.useId()); }
@Override
public List<WTFisT> getAll() { return Arrays.asList(new WTFisT(), new WTFisT(), new WTFisT()); }
@Override
public List<CustomerAttribute> getAllAttributes(LongIdentifier identifier) {
return Arrays.asList(
new CustomerAttribute(new Customer("foo")),
new CustomerAttribute(new Customer("bar")),
new CustomerAttribute(new Customer("baz"))
);
}
@Override
public String createAttribute(CustomerAttribute attribute) { return attribute.useAttr().toString(); }
}
CrudRepository<WTFisT, LongIdentifier, CustomerAttribute> customerRepo = new CustomerRepository();
WTFisT wtfIsT = new WTFisT();
Customer aCustomer = new Customer("Tough");
LongIdentifier i = customerRepo.create(wtfIsT);
i = customerRepo.update(new LongIdentifier(999L), new WTFisT());
wtfIsT = customerRepo.get(i);
List<WTFisT> allWTFs = customerRepo.getAll();
List<CustomerAttribute> allCustomers = customerRepo.getAllAttributes(i);
String aString = customerRepo.createAttribute(new CustomerAttribute(aCustomer));
请注意,这只是代码的翻译部分,其中的变量名和数据结构名可能需要根据上下文进行调整。
英文:
> …
>
> „Something like this:“
>
> public List<? extends DynamoDBEntry> getAllAttributes(I identifier);
>
> public String createAttribute(A<? extends DynamoDBEntry> attribute);
>
> „Could this be achived, and what would be best practise in this case?“
>
> …
What your code examples specify is not 100% clear. For instance you show an example of what you intend use-site arguments for the A
type parameter to be. But you don't show anything for neither the T
nor the I
type parameters.
But making assumptions (guesses) based on my limited understanding, I put together this working example…
public interface CrudRepository<T extends Type< ? >, I extends Identifier< ? >, A extends Attribute< ? extends DynamoDBEntry > > {
public I create(T t);
public I delete(I i);
public I update (I i, T t);
public T get(I identifier);
public List<T> getAll();
public List<A> getAllAttributes(I identifier);
public String createAttribute(A attribute);
}
And an example implementation of that…
public class CustomerRepository implements CrudRepository< WTFisT, LongIdentifier, CustomerAttribute >{
private Map< Long, Customer > customers = new HashMap< > ( );
private Map< Long, WTFisT > wtfs = new HashMap< > ( );
@Override
public LongIdentifier create( WTFisT t ){ wtfs.put( 666L, t ); return new LongIdentifier( 666L ); }
@Override
public LongIdentifier delete( LongIdentifier i ){ return i; }
@Override
public LongIdentifier update ( LongIdentifier i, WTFisT t ){ wtfs.put( i.useId( ), t ); return i; }
@Override
public WTFisT get( LongIdentifier identifier ){ return wtfs.get( identifier.useId( ) ); }
@Override
public List< WTFisT > getAll( ){ return of( new WTFisT( ), new WTFisT( ), new WTFisT( ) ); }
@Override
public List< CustomerAttribute > getAllAttributes(LongIdentifier identifier){ return of( new CustomerAttribute( new Customer( "foo" ) ), new CustomerAttribute( new Customer( "bar" ) ), new CustomerAttribute( new Customer( "baz" ) ) ); }
@Override
public String createAttribute( CustomerAttribute attribute ){ return attribute.useAttr( ).toString( ); }
}
That could be used like…
CrudRepository< WTFisT, LongIdentifier, CustomerAttribute > customerRepo = new CustomerRepository( );
WTFisT wtfIsT = new WTFisT( );
Customer aCustomer = new Customer( "Tough" );
LongIdentifier i = customerRepo.create( wtfIsT );
i = customerRepo.update ( new LongIdentifier( 999L ), new WTFisT( ) );
wtfIsT = customerRepo.get( i );
List< WTFisT > allWTFs = customerRepo.getAll( );
List< CustomerAttribute > allCustomers = customerRepo.getAllAttributes( i );
String aString = customerRepo.createAttribute( new CustomerAttribute( aCustomer ) );
Then printing out the results of those calls…
LongIdentifier [ id: 666 ]
LongIdentifier [ id: 999 ]
WTFisT [ Anybody's guess ]
[WTFisT [ Anybody's guess ], WTFisT [ Anybody's guess ], WTFisT [ Anybody's guess ]]
[CustomerAttribute [ aCustomer: Customer [ id: foo ] ], CustomerAttribute [ aCustomer: Customer [ id: bar ] ], CustomerAttribute [ aCustomer: Customer [ id: baz ] ]]
Customer [ id: Tough ]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论