A common problem found in code reviews of inexperienced programmers is the use of a procedural paradigm of coding even though they are working with an object-oriented language. Typically, the code looks something like
doAction1ToData(some data structure)
doAction2ToData(some data structure)
doActionnToData(some data structure)
Instead of writing objects that encapsulate and hide the data, the data is passed from method to method. This is hardly different from a procedural language such as C or FORTRAN. The data which flows through these methods essentially becomes a global variable. It is very difficult to isolate the changes that happen to the data.
I believe the blame for some of this lies in teaching computer programming as formulating algorithms. Do this. Do that. Break “that” into steps. Also, procedural programming is adequate for small coding tasks and so programmers are used to that style. When it comes to larger projects, they are unable to think in terms of objects and interactions between the objects. Unfortunately, because of this flaw, the code stops being maintainable due to the complexity introduced.
One way to do that is to start refactoring the pieces of data that are accessed by various methods. Create classes that combine data and methods. Reduce the visibility of data elements. Be unafraid to break up classes. Keep learning about more object-oriented refactoring techniques.