Assuming you have the chance to start up wit a new ERP or S/4 SAP system - yes they are also still alive in an S/4 Hana - and you can work on an untouched SAPMV45A (as example). How would you do it? What is clean (for you)?
Here are some of my thoughts – but no final conclusion. Maybe you can add yours.
Direct implementation in ZZ include:
Direct access to all data objects
Complete include locked by one change
No unit tests
Direct access to all data objects, when doing it wrong (ok that's always the case when doing it wrong, but ... )
Direct implementation using includes, one (or more) per USEREXIT form :
Similar like direct implementation
several developers/projects can work in parallel
Looks a little bit like fake modularization, as include is not an own object
Tendency to grow wild. “May-be another include in or after the original include helps me with my problem?”
A return or check statement leaves the subroutine and not just the include
External performs to programs, that share the data object with tables/common part
Still direct access to data
Can have own screens
Implementation could be done by local classes and unit tests
External performs look like a misuse of the private objects, that are public by technical reasons.
Real OO with global interfaces/classes/BAdis
Advantages of OO: Encapsulation, Inheritance ..
“Modern” Exception handling
Development support by ADT
Cannot have screens
Frequent changes of public interface when starting with a reduced/minimal interface
One class/interface/BADI per main program / one instance per document/transaction