A friendly reminder: If this repo somehow helped you please star 🌟 it! Thank you! 😄
Is to create simple Cash Machine emulator.
Requirements (9/9 completed):
- create stand-alone console I/O Java program using any JDK;
- follow OOP paradigm;
- make program easily extendable;
- provide logging to the output file;
- divide program modules into packages;
- generate JavaDocs;
- write JUnit tests for public methods;
- make Ant
build.xml
; - make functional test.
Input commands:
- Cash deposit
Format: + <currency> <denomination> <amount>
Validation:
* <currency> 3 uppercase letters, any combination
* <value> any value in set ["1","5","10","50","100","500","1000","5000"]
* <number> positive integer
Reply: OK on success, ERROR on validation fail
- Cash withdraw
Format: - <currency> <amount>
Reply: line formatted as <denomination> <amount> followed by OK on success, ERROR if amount is unavailable
- Cash print
Format: ?
Reply: OK, ordered by currency -> value
ant build
ant test
ant run
Before coding, we should make a plan:
- How to handle commands;
- Deposit/Withdraw strategy;
- I/O common interface.
To handle the command problem I decided to go for behavioral design Command pattern which delegates command build to the command factory.
I recommend to check Jairo Alfaro's reply on StackOverflow since he gives a good example of the implementation in C#.
I decided to arrange data in a structure Map<String, TreeMap<Integer, Integer>>
since we basically have this kind of structure:
Since we have to pop up bigger banknotes first, we store Map<Integer, Integer>
in a reverse order. In Java, TreeMap<Integer, Integer>
stores keys in a natural order, so in our case we should apply Collections.reverseOrder()
on initialization.
The rest of the algorithm is a piece of cake. For the deposit we simply add cash to the denomination, for the withdrawal we subtract the amount of remove the denomination if the amount is exact. Also, handle the situation when amount is unavailable (denomination absence, etc.).
I created an I/O interface (InputReader
& OutputWriter
) and implemented corresponding reader and writer to work with streams. These classes can work both with System.in
/System.out
and FileInputStream
/FileOutputStream
so we can easily switch between file and console I/O.