The first thing to add is of course a way to add products and transactions as these form the core of the application. With the initial version I am aiming for a very basic form which just allows storing and retrieving data.
With the initial implementation of the Product and Transaction done, I will briefly explain how everything went, the thought process behind it and what I already know must be added in the future.
I started development on the Product, and gave it three fields to identify it:
- brand name
- product name
The barcode is my ‘primary key’ and will uniquely identify a product, nevertheless having an actual name associated with it will make things easier. But this is all that makes up a product so far. The Product is also just a data object, which is completely constant. Once you created it, you can no longer change anything about it. I foresee that this will cause some problems, just imagine making a typo which you spot too late.
Adding products to the system means I need some place to store them. Of course you can always store them in the actual application, but this would easily cause problems later on. My idea was to already start consider it as a server-like application, which is why I created a product service to store all of the products. In time this could be expanded and scaled up, such that we can utilize micro-services, splitting each small service.
A transaction is very similar. Though initially I wanted to make a transaction consist of a list of products and their price, I postponed this untill later because of the effort it would require to implement a way to do this in the console. For now I just wanted to have a working base and fiddling too much with user interface stuff is not something I currently want to waste too much time on. So instead each transaction expresses the purchase of a single product. This made a transaction stupidly simple and consists of:
Similar as with the products, I created a transaction service to store and retrieve transactions.
I did run into some problems when I wanted to test the product service. I did create mock products, but for some reason the methods where not called on that object. It took me a long time to figure out what was causing this, but eventually I did discover it. The method to add a product to the product service takes in a product as its argument. By doing this, the actual object gets copied (using the default copy constructor). This means that the methods are called on the newly created object and not on the mock.
Whats even worse is that since the mock object doesn’t set any value for its members, but only associates return values with method calls, the new objects is initialised to the default values for all of its members, breaking some of the tests.
Using a pointer to a product does fix this, but then all of the production code has to be changed as well, and the objects need to be created with the ‘new’ keyword to prevent them from being destroyed when they get out of scope. This looks a bit dirty to me, and I would prefer to have another way to handle this, such as a product builder, or directly in the product service. But until I have made up my mind on that part, I decided to keep on using the actual objects.
Note that switching to pointers will become critical as currently the transaction also holds a copy of the object. Instead they should all be pointing to the exact same product instead of making tons of copies of it.
Things that will have to be changed on the product are:
- I want to get rid of the barcode, I don’t feel it will add a lot of value, and some products may not have a barcode you are aware of (such as vegetables, fruit, ..).
- A product will need a certain size, altough this could also cause problems with products that are not perfectly uniform (vegetables, fruit, …).
- I still want to add nutrition facts.
- Allow certain changes on the product.
Things to be changed on the transaction are:
- A transaction should cover more than just a single product.
- It should specify the unit price and a quantity.
- Then the transaction should also be able to calculate the total transaction cost.
- Allow certain changes on the product.
Some other improvements that are required is to make the UI more error-resistant. At the moment as soon as you do something different, like creating a transaction with a product that does not exist, will simply crash the application.
There still is a lot to be done, and currently my top priority is to make sure that all the data is being stored. As this also posed to be very annoying that I had to redo a lot of work each time I wanted to improve the UI a bit.