lundi 14 décembre 2015

How to couple an instance member to a instance method?

I have a class structure like :

public interface DBReader {
    public Map<String, String> read(String primaryKey, String valueOfPrimaryKey,
        boolean scanIndexForward, boolean consistentRead, int maxPageSize);

   public int getA(String ___);
   public int getB(String ___);
   public int getC(String ___);
}



public class DynamoDBReader implements DBReader {

        private DynamoDB dynamoDB;
        private String tableName;
        private Table table;
        private int throughput;

        private DynamoDBReader(Builder builder) {
            this.throughput = builder.throughput;
            this.tableName = builder.tableName;
            this.dynamoDB = builder.dynamoDB;

            this.table = dynamoDB.getTable(builder.tableName);
            if (table == null) {
                throw new InvalidParameterException(String.format("Table %s doesn't exist.", tableName));
            }
        }

        @Override
        public int getA(String ____) {
                read(_________);
            }
            return ________;
        }

        @Override
        public int getB(String ____) {
                read(_________);
            }
            return ________;
        }

        @Override
        public int getC(String ____) {
                read(_________);
            }
            return ________;
        }


        @Override
        public Map<String, String> read(String primaryKey, String valueOfPrimaryKey, boolean scanIndexForward,
        boolean consistentRead, int maxPageSize) {
            QuerySpec spec = new QuerySpec()
                .withHashKey(primaryKey, valueOfPrimaryKey)
                .withScanIndexForward(scanIndexForward)
                .withConsistentRead(consistentRead)
                .withMaxPageSize(maxPageSize);
            ItemCollection<QueryOutcome> items = table.query(spec);
            Iterator<Item> itemIterator = items.firstPage().iterator();
            Map<String, String> itemValues = new HashMap<String, String>();
            while (itemIterator.hasNext()) {
                Item item = itemIterator.next();
            }
            return itemValues;
        }
    }

  @VisibleForTesting
    protected void setTable(Table table) {
        this.table = table;
    }

    /**
     * Returns a new builder.
     */
    public static Builder builder() {
        return new Builder();
    }

    public static class Builder {
        private String tableName;
        private int throughput;
        private DynamoDB dynamoDB;

        private Builder() { }

        public Builder tableName(String tableName) {
            this.tableName = tableName;
            return this;
        }

        public Builder throughput(int throughput) {
            this.throughput = throughput;
            return this;
        }

        public Builder dynamoDB(DynamoDB dynamoDB) {
            this.dynamoDB = dynamoDB;
            return this;
        }

        public DynamoDBReader build() {
            if (tableName == null) {
                throw new InvalidParameterException("Table name can't be null.");
            }
            if (throughput <= 0) {
                throw new InvalidParameterException("Throughput should be > 0.");
            }
            if (dynamoDB == null) {
                throw new InvalidParameterException("dynamoDB can't be null.");
            }
            return new DynamoDBReader(this);
        }
    }
}

Problem : getA(), getB(), getC() are only valid for specific tableNames. For a table getA() is Valid but getB() and getC() wont make any sense.

How to couple method names with table name so that someone with a table name knows which function is valid.

Solution to create subclasses for different getters doesn't look a great idea to me.

Aucun commentaire:

Enregistrer un commentaire