Generifying generic object Java

huangapple go评论65阅读模式
英文:

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存储库中,我想要泛型化嵌套属性。

到目前为止,我有一个类似这样的模式

通过在接口中指定TypeIdentifierAttribute(嵌套对象)。

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 = &quot;BankCustomer&quot;)
public class Customer extends DynamoDBEntry {
...
}
@DynamoDBTable(tableName = &quot;CustomerTransaction&quot;)
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&lt;T, I, A&gt; {

    public I create(T t);

    public I delete(I i);

    public I update (I i, T t);

    public T get(I identifier);

    public List&lt;T&gt; getAll();

    public List&lt;A&gt; 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&lt;? extends DynamoDBEntry&gt; getAllAttributes(I identifier);

public String createAttribute(A&lt;? extends DynamoDBEntry&gt; 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&lt;T extends Type&lt; ? &gt;, I extends Identifier&lt; ? &gt;, A extends Attribute&lt; ? extends DynamoDBEntry &gt; &gt; {
public I create(T t);
public I delete(I i);
public I update (I i, T t);
public T get(I identifier);
public List&lt;T&gt; getAll();
public List&lt;A&gt; getAllAttributes(I identifier);
public String createAttribute(A attribute);
}

And an example implementation of that…

public class CustomerRepository implements CrudRepository&lt; WTFisT, LongIdentifier, CustomerAttribute &gt;{ 
private Map&lt; Long, Customer &gt; customers = new HashMap&lt; &gt; ( );
private Map&lt; Long, WTFisT &gt; wtfs = new HashMap&lt; &gt; ( );
@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&lt; WTFisT &gt; getAll(  ){ return of( new WTFisT( ), new WTFisT( ), new WTFisT( ) ); }
@Override
public List&lt; CustomerAttribute &gt; getAllAttributes(LongIdentifier identifier){ return of( new CustomerAttribute( new Customer( &quot;foo&quot; ) ), new CustomerAttribute( new Customer( &quot;bar&quot; ) ), new CustomerAttribute( new Customer( &quot;baz&quot; ) ) ); }
@Override
public String createAttribute( CustomerAttribute attribute ){ return attribute.useAttr( ).toString( ); }    
}

That could be used like…

  CrudRepository&lt; WTFisT, LongIdentifier, CustomerAttribute &gt; customerRepo = new CustomerRepository( );
WTFisT wtfIsT = new WTFisT( );
Customer aCustomer = new Customer( &quot;Tough&quot; );
LongIdentifier i = customerRepo.create( wtfIsT );
i = customerRepo.update ( new LongIdentifier( 999L ), new WTFisT( ) );
wtfIsT = customerRepo.get( i );
List&lt; WTFisT &gt; allWTFs = customerRepo.getAll( );
List&lt; CustomerAttribute &gt; 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&#39;s guess ]
[WTFisT [ Anybody&#39;s guess ], WTFisT [ Anybody&#39;s guess ], WTFisT [ Anybody&#39;s guess ]]
[CustomerAttribute [ aCustomer: Customer [ id: foo ] ], CustomerAttribute [ aCustomer: Customer [ id: bar ] ], CustomerAttribute [ aCustomer: Customer [ id: baz ] ]]
Customer [ id: Tough ]

huangapple
  • 本文由 发表于 2020年9月11日 17:40:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/63844532.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定