This weekend I'll be adding some posts on what's happened to the design and implementation over the past months.
Saturday, May 16, 2009
Busy as a....ooh shiny!
So yeah. I've been neglecting this little corner of the interweb. On the other hand, I can show you a reason why (other than WoW being utterly addictive).

This weekend I'll be adding some posts on what's happened to the design and implementation over the past months.
This weekend I'll be adding some posts on what's happened to the design and implementation over the past months.
Monday, February 16, 2009
Rupiz: Core Concepts
At the core of Rupiz are one interface and two classes:
Amount
Note that anything that implements Amount must be comparable to any other implementation of Amount. This lets us mix implementations without worrying about their details.
The implementation I'm using for Rupiz will be backed by an instance of BigDecimal with a scale of 2 decimal digits.
Transaction
The major design decision with the Transaction class was whether to make it immutable. For now, I'm leaning towards immutability mainly because it's a value object and it will be put into ordered sets, at which point modifying the object is a Very Bad Thing.
Account
Account is pretty straightforward. It keeps track of the transactions that involve the account and provides methods to move amounts in and out of the acount.
With these classes complete, I can begin working on the actual application.
The source for the classes above can be downloaded here.
Amount
public interface Amount extends Comparable<Amount>{
public Amount add(Amount value);
public Amount subtract(Amount value);
@Override
public int compareTo(Amount amount);
}
Note that anything that implements Amount must be comparable to any other implementation of Amount. This lets us mix implementations without worrying about their details.
The implementation I'm using for Rupiz will be backed by an instance of BigDecimal with a scale of 2 decimal digits.
Transaction
public class Transaction implements Comparable<Transaction>{
public final Amount amount;
public final Account source;
public final Account destination;
public final String description;
public final LocalDate dateStamp;
public Transaction(Amount amt, Account src, Account dest) {
this("", amt, src, dest, new LocalDate());
}
public Transaction(Amount amt, Account src,Account dest, LocalDate date){
this("", amt, src, dest, date);
}
public Transaction(String desc, Amount amt, Account src, Account dest) {
this(desc, amt, src, dest, new LocalDate());
}
public Transaction(String desc, Amount amt, Account src, Account dest, LocalDate date) {
description = desc;
amount = amt;
source = src;
destination = dest;
dateStamp = date;
}
@Override
public int compareTo(Transaction trans) {
int value = dateStamp.compareTo(trans.dateStamp);
if(value != 0)
return value;
value = source.getDescription().compareTo(trans.source.getDescription());
if(value != 0)
return value;
value = destination.getDescription().compareTo(trans.destination.getDescription());
if(value != 0)
return value;
value = amount.compareTo(trans.amount);
if(value != 0)
return value;
return description.compareTo(trans.description);
}
}
The major design decision with the Transaction class was whether to make it immutable. For now, I'm leaning towards immutability mainly because it's a value object and it will be put into ordered sets, at which point modifying the object is a Very Bad Thing.
Account
public class Account {
private String description;
private Amount amount;
private Set<Transaction> transactions;
// Global source account for deposits from unspecified sources
static Account globalSource = new Account("Opening Balances",
new DecimalAmount(new BigDecimal("0.00"))) {...};
// Constructors snipped
// Setters & Getters snipped
public Amount depositFor(Amount amount, String description) {
return depositForOn(amount, description, new LocalDate());
}
public Amount depositForOn(Amount amount, String description, LocalDate date) {
return globalSource.transferToForOn(amount, this, description, date);
}
public Amount transferToFor(Amount amount, Account destination, String description) {
return transferToForOn(amount, destination, description, new LocalDate());
}
public Amount transferToForOn(Amount amount, Account destination,
String description, LocalDate date) {
Transaction trans = new Transaction(description, amount,
this, destination, date);
destination.amount = destination.amount.add(amount);
amount = amount.subtract(amount);
transactions.add(trans);
destination.transactions.add(trans);
return amount;
}Account is pretty straightforward. It keeps track of the transactions that involve the account and provides methods to move amounts in and out of the acount.
With these classes complete, I can begin working on the actual application.
The source for the classes above can be downloaded here.
Labels:
rupiz
Sunday, January 25, 2009
Rupiz: A basic design
What do we need for the back end of a personal finance application?
So for our model, we will have an Account class that holds a BigDecimal for the current balance. This Account will have methods deposit(Amount) and withdraw(Amount) that both return an implementation of Amount representing the updated account balance. To track our account balance changes, we will have a Transaction interface with implementations BasicTransaction and CompoundTransaction, where CompoundTransaction will allow us to group a number of transactions together. We will maintain a List<Transaction> for each account we're dealing with.
For our GUI, we will need a way to show our list of Transactions for a given account. A JTable will do nicely until we add support for compound transactions. Our JTable will need columns for Date, Description, Transaction Type, Source/Destination, Amount, and whether the transaction has been reconciled.
- Some way to represent Accounts. An Account has a description, current balance, and some methods to modify the current balance.
- We want to encapsulate modifications to accounts in Transactions, which would have a description, source account, destination account, and amount. In addition, we will want a version of Transaction that holds a number of subtransactions.
- We want users of our Account class to not care how the account is implemented (in particular how the current balance is represented). To make this possible, we will define an Amount interface to hide these details. To start, we will use an implementation that uses BigDecimal to hold the amount info. If we want to change this later, we can do so easily and without a lot of search-and-replacing.
So for our model, we will have an Account class that holds a BigDecimal for the current balance. This Account will have methods deposit(Amount) and withdraw(Amount) that both return an implementation of Amount representing the updated account balance. To track our account balance changes, we will have a Transaction interface with implementations BasicTransaction and CompoundTransaction, where CompoundTransaction will allow us to group a number of transactions together. We will maintain a List<Transaction> for each account we're dealing with.
For our GUI, we will need a way to show our list of Transactions for a given account. A JTable will do nicely until we add support for compound transactions. Our JTable will need columns for Date, Description, Transaction Type, Source/Destination, Amount, and whether the transaction has been reconciled.
Labels:
rupiz
A new year, a new project
Happy new year! I figured this year I'd resolve to finish a programming project that's been kicking around the back of my head for a while now and has had an abortive start or two.
For the past year, I've been using GnuCash as my way of keeping track of my spending. While it's a very well written program, it has one minor irritant. I split my purchases into categories to better track where my money goes, but that makes reconciliation tricky at the end of the month. While I could preface the description for each transaction with the store, I'd rather be able to group transactions and be able to treat the group as a whole as a single entity during reconciliation.
So, with no pomp and somewhat random circumstance, I will be using this blog as a way to guilt me into working on a personal finance app I'm going to call Rupiz (Roo-peez).
For the past year, I've been using GnuCash as my way of keeping track of my spending. While it's a very well written program, it has one minor irritant. I split my purchases into categories to better track where my money goes, but that makes reconciliation tricky at the end of the month. While I could preface the description for each transaction with the store, I'd rather be able to group transactions and be able to treat the group as a whole as a single entity during reconciliation.
So, with no pomp and somewhat random circumstance, I will be using this blog as a way to guilt me into working on a personal finance app I'm going to call Rupiz (Roo-peez).
Labels:
rupiz
Subscribe to:
Posts (Atom)