Question

I wrote a binary calculator & binary teaching program in the Rust programming language. I was taking an iterative approach in that I decided to first get a basic "learn binary" game started. This game displays a hex or decimal number to the console and requires the player to enter the number in binary 1s and 0s as a means to help students learn binary.

I then decided to add binary calculator functionality to the program by creating a welcome screen and menu where the user selects between 1. Learn Binary 2. Binary Calculator and 3. Exit.

I then implemented the Binary Calculator functionality.

However, After I did this, I realized that within my Binary Calculator module, a "back to main menu" option was missing - so once a user entered the calculator, he/she would have to exit the program entirely to get to the Learn Binary game and vice versa.

However, in order to implement a "back to menu" feature, I'm realizing that I now have to abstract a loop out into the main function or one function lower, and now each function in succession needs to return some data so that this loop can know when to exit. I'm ending up having to change and add different return types to functions which is having a domino effect and has become more time consuming than expected.

This is just one small example, but I find myself facing this sort of thing often - is this typical in software engineering? Is it normal to have to go back and change a bunch of stuff when new features are added or is it a better idea to think all of this type of thing through ahead of time?

Note that my program is largely procedural but uses a couple OOP constructs as necessary.

Was it helpful?

Solution

Yes, this is normal.

The conventional wisdom these days is that it is overall more efficient to build what you need first, without first considering all consequences on all possible later features or requirements. This means that you are willing to revise some design decisions you made earlier (and you are comfortable in making such changes without fear of regression because your functionality is semi-automatically verified by an extensive test suite).

Thinking about the global design of all modules first would probably have saved you this detour, but thinking about problems in advance turns out to be surprisingly hard in general - usually it is easier to find out what you need at point X if you've already progressed to point X-1. Therefore, there is a trade-off between the cost of planning ahead (spending time on considering many alternatives, most of which never get built) and the cost of plunging forward (requiring additional work to change design decisions that would have been cheaper to fix earlier). You've probably heard the words "agile" and "waterfall". That's exactly what this trade-off is about.

Licensed under: CC-BY-SA with attribution
scroll top