简体   繁体   中英

Generifying generic object Java

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?

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 ]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM