Last minute geek

last minute tech news from around the net

Sunday, Jun 24th

Last update01:00:00 AM

You are here: English WTF CodeSOD: Many Happy Returns

CodeSOD: Many Happy Returns

User Rating: / 0
PoorBest 

We've all encountered a situation where changing requirements caused some function that had a single native return type to need to return a second value. One possible solution is to put the two return values in some wrapper class as follows:

  class ReturnValues {
    private int    numDays;
    private String lastName;

    public ReturnValues(int i, String s) {
      numDays  = i;
      lastName = s;
    }

    public int    getNumDays()  { return numDays;  }
    public String getLastname() { return lastName; }
  }

It is trivial to add additional return values to this mechanism. If this is used as the return value to an interface function and you don't have access to change the ReturnValues object itself, you can simply subclass the ReturnValues wrapper to include additional fields as needed and return the base class reference.

Then you see something like this spread out over a codebase and wonder if maybe they should have been just a little less agile and that perhaps a tad more planning was required:

  class AlsoReturnTransactionDate extends ReturnValues {
    private Date txnDate;
    public AlsoReturnTransactionDate(int i, String s, Date td) {
      super(i,s);
      txnDate = td;
    }
    public Date getTransactionDate() { return txnDate; }
  }
  
  class AddPriceToReturn extends AlsoReturnTransactionDate {
    private BigDecimal price;
    public AddPriceToReturn(int i, String s, Date td, BigDecimal px) {
      super(i,s,td);
      price = px;
    }
    public BigDecimal getPrice() { return price; }
  }

  class IncludeTransactionData extends AddPriceToReturn {
    private Transaction txn;
    public IncludeTransactionData(int i, String s, Date td, BigDecimal px, Transaction t) {
      super(i,s,td,px);
      txn = t;
    }
    public Transaction getTransaction() { return txn; }
  }

  class IncludeParentTransactionId extends IncludeTransactionData {
    private long id;
    public IncludeParentTransactionId(int i, String s, Date td, BigDecimal px, Transaction t, long id) {
      super(i,s,td,px,t);
      this.id = id;
    }
    public long getParentTransactionId() { return id; }
  }

  class ReturnWithRelatedData extends IncludeParentTransactionId {
    private RelatedData rd;
    public ReturnWithRelatedData(int i, String s, Date td, BigDecimal px, Transaction t, long id, RelatedData rd) {
      super(i,s,td,px,t,id);
      this.rd = rd;
    }
    public RelatedData getRelatedData() { return rd; }
  }

  class ReturnWithCalculatedFees extends ReturnWithRelatedData {
    private BigDecimal calcedFees;
    public ReturnWithCalculatedFees(int i, String s, Date td, BigDecimal px, Transaction t, long id, RelatedData rd, BigDecimal cf) {
      super(i,s,td,px,t,id,rd);
      calcedFees = cf;
    }
    public BigDecimal getCalculatedFees() { return calcedFees; }
  }

  class ReturnWithExpiresDate extends ReturnWithCalculatedFees {
    private Date expiresDate;
    public ReturnWithExpiresDate(int i, String s, Date td, BigDecimal px, Transaction t, long id, RelatedData rd, BigDecimal cf, Date ed) {
      super(i,s,td,px,t,id,rd,cf);
      expiresDate = ed;
    }
    public Date getExpiresDate() { return expiresDate; }
  }

  class ReturnWithRegulatoryQuantities extends ReturnWithExpiresDate {
    private RegulatoryQuantities regQty;
    public ReturnWithRegulatoryQuantities(int i, String s, Date td, BigDecimal px, Transaction t, long id, RelatedData rd, BigDecimal cf, Date ed, RegulatoryQuantities rq) {
      super(i,s,td,px,t,id,rd,cf,ed);
      regQty = rq;
    }
    public RegulatoryQuantities getRegulatoryQuantities() { return regQty; }
  }

  class ReturnWithPriorities extends ReturnWithRegulatoryQuantities {
    private Map<String,Double> priorities;
    public ReturnWithPriorities(int i, String s, Date td, BigDecimal px, Transaction t, long id, RelatedData rd, BigDecimal cf, Date ed, RegulatoryQuantities rq, Map<String,Double> p) {
      super(i,s,td,px,t,id,rd,cf,ed,rq);
      priorities = p;
    }
    public Map<String,Double> getPriorities() { return priorities; }
  }

  class ReturnWithRegulatoryValues extends ReturnWithPriorities {
    private Map<String,Double> regVals;
    public ReturnWithRegulatoryValues(int i, String s, Date td, BigDecimal px, Transaction t, long id, RelatedData rd, BigDecimal cf, Date ed, RegulatoryQuantities rq, Map<String,Double> p, Map<String,Double> rv) {
        super(i,s,td,px,t,id,rd,cf,ed,rq,p);
        regVals = rv;
    }
    public Map<String,Double> getRegulatoryValues() { return regVals; }
  }

The icing on the cake is that everywhere the added values are used, the base return type has to be cast to at least the level that contains the needed field.

[Advertisement] Continuously monitor your servers for configuration changes, and report when there's configuration drift. Get started with Otter today!

Read all
Comment Policy:
We pre-moderate any comments and welcome all kinds of thoughts, supportive, dissenting, critical or otherwise. We delete or censor comments that are:

* abusive
* off-topic
* contain personal attacks, or against any company or organization
* promote hate of any kind
* use excessively foul language
* is blatantly spam or advertising

We do not discriminate based on the person who is posting, and we never censor comments for political or ideological reasons. We never delete an appropriate comment because we disagree with its viewpoint or ideology, and we never publish an inappropriate comment because we agree with or support its viewpoint or ideology.


Attention spammers: we manually approve all comments. Spamming and blatant advertising will NOT be published on this site and is deleted immediately, you've been warned, do not waste your time here.

Add comment

Security code
Refresh