Sometimes it's hard to create good designs when the infrastructure you have to work with forces bad design decisions on you. On one system I worked on, the infrastructure was setup to reduce the period of time that a database transaction was open. The developers didn't want a transaction to start when a window opened and only committed when the window was finally closed. To avoid this, they developed an infrastructure that would record the changes to an object. When it was time to commit the object, it would begin a transaction, replay the changes, and commit the transaction in rapid succession. The problem is that it recorded the changes without actually changing the domain object. It would just record which properties were changed and what values they were changed to. The problem is that the domain objects never actually had the up-to-date information. To get the current values, you had to ask the transaction manager. This meant that operations that should have been methods on the domain object were pushed to the user interface and became UI methods since the UI knew about the transaction manager. This design decision has caused no end of problems with the design of the system.
The problem is that it's difficult to replace the infrastructure since the entire system depends on it. So many facilities were built on top of that mechanism that it's become impractical to replace it. There are some areas where major design decisions can be changed later and there are some areas where design changes become so rooted that it's impossible to change them. It helps to think about the infrastructure ahead of time and be ready to replace it early when it starts to show its warts. In the end, though, the best approach may be to either live with it or try to design a parallel mechanism that works better. If you're lucky, then over time you can migrate to the new mechanism.Download