Software engineers are responsible for adding new and unforeseen complexity to established, carefully thought out systems.
It tends to be a reflex when told to add complexity, that we special case the complexity and fall through to the system you had before. This works in many cases and is great if the complexity being added is a footnote that you don’t intend to come back to.
Complexity that is essential to the long term success of your product needs to be “native.”
However, if it is a new direction your product is taking, or a major piece of functionality you anticipate growing, then that reflex is a dangerous one. Try and think of the new complexity in terms of the whole native vs third party debate. When something is native it integrates flawlessly into the existing system, when it is third party it has a few touch points and exists separately. Complexity that is essential to the long term success of your product needs to be “native.”
How do I make complexity “native” in my system? Well it’s simple, instead of taking the existing system and sticking the new feature in, imagine a new system that the feature is a living breathing part of, then fit the old system inside it. By committing to this “one way” of doing things in your system (or at least as few as you can), you reduce fragmentation and make things easy to understand and improve upon.