Need guidance on programming technique

If I want to code where press and release a button lights a led on press and press and release the same button turns the led off on release then I divide into 3 parts, button, led, and logic.

The button code handles the physical button including debouncing and keeps a status variable or bit updated.
It would be near the top of loop() to check often. Button is considered to have changed state when it has not changed state in 5 ms or longer. If you just go by pin HIGH or LOW, a sloppy button will bounce 10+ times just making solid contact when your code is running loops per milli. You want debouncing for hardware compatibility.

The button code has no led code in it. It communicates ON/OFF button state only through a variable or bit.
Any other sensor that can be reduced to ON/OFF, the code for it can work the same as the button.

The led code turns the led ON/OFF according to a variable set by some other code.
Other ON/OFF output devices can be connected and coded in the same way.

The logic code reads states and times and sets variables to run outputs.
The logic code should only deal with abstracts, it should not read or write pins or do any direct hardware interaction, just change states needed to keep a running evaluation and action engine going.
I've used states within states when parsing numbers as a special case of text parse and lex. Do what you gotta.

This way allows modular code that can be written to standard and pre-tested in mini-sketches then copied directly into the current revision for integration testing. You can't do that with different functions interlaced in the same logic structures, not without a lot of line editing.