I was part of a team working for a client who develops apps for insurance companies. We were involved in the maintenance of a web app and a desktop app used for insurance enrollment and insurance records management.
I started to understand what Object-Oriented programming is.
(When I applied for this job, I claimed to know OOP. But I later realized that I really did not know OOP. I only knew about what a class is, what an interface is, what an abstract class is, what polymorphism is, but I did not not yet have a full understanding about their purpose.)
This is where I started to understand the Dependency Inversion Principle, the use of the Factory design pattern, and other things.
I learned that programmers at this level of their carreer needs lots of guidance/mentoring from their seniors, most especially when the project is in a complex state already, and if the seniors don't want the juniors to mess with the code.
(When I become a senior developer someday, I intend to guide/mentor my teammates who are in the beginning years of their carreer... provided of course that they also share some of their knowledge with me. )
Also, I think it will be helpful to give from time-to-time some readings or lectures about the domain of the system being maintained by the programmers, so that it will not be very hard for them to understand the parts of the codebase where knowledge of the domain is needed.
This is the time where I, and my teammates, plunged into the Clean Code book because one of our team leads made us read one chapter of the book each week, and spend about an hour each week discussing that chapter.
Unfortunately, for reasons unknown to me, our discussions stopped after a few meetings. We did not finish the book. We only discussed up to chapter five, if I remember it correctly. And I read up to chapter 8 only of the book.
But I learned a lot from the chapters which I read.
This is where I experienced writing unit tests after-the-fact, that is, after the production code is already written. — It was hard.
There were parts of the system that were somewhat easy to test. But there were parts that were hard to test. Those parts that were hard to tests? — those that used
DateTime.Now, and static methods, and extension methods of C# (which basically are still static methods), those parts that use (what I now know as) Service Locator — I skipped testing them . Of course I first tried to look for ways on how to test those things...
I think the time I spent writing those tests was a waste of time , partly because there were parts of the system that I skipped testing (because I did not know how to test them), and partly because I did not have the goal of using the tests to make the design of the system better at a later time, which is supposed to be one of the reasons for writing tests for an existing software. (I did not yet know that books such as "Working Effectively with Legacy Code" existed during that time.)
Don't get me wrong here. I don't hate unit testing. During that time, I already have an appreciation on the benefits of having unit tests — it had been three years already since I first heard about unit testing and TDD during that time.
I think I should have told my team leads about my opinion that writing those tests was just a waste of time. Had I told them about it, they might have explained to me why those tests should be written, and they might have helped me look for ways to write tests for the untestables that I encountered. But I was very timid during that time and was afraid to express my opinions.
But despite that experience, I'm not against writing tests. I am even a TDD advocate today through the influence of Uncle Bob Martin. But writing tests after the production code is already written requires a somewhat different skillset than doing TDD. I was, and is still, not skillfull on writing tests after-the-fact. But I'm trying to be good at it also.