I've noticed a disturbing trend whereby a "mirror model" is created of some framework or system. For example, creating classes that mirror database entities or creating GUI models that mirror a GUI setup done with a specific vendor's GUI product. For instance, for form_X in the GUI, there is a corresponding class or method outside the GUI system called something like "form_X_model". Each GUI form has a "mirrored" form model. We need a good hard look at this. It is a violation of OnceAndOnlyOnce and incorrect relational normalization (essentially two tables with the same primary key).
I am not a die-hard fan of all-out YagNi, but in this case it is strong enough to apply because vendor swapping is a relatively infrequent change that requires a lot of up-front work to try to build a layer against. It's kind of an all-or-nothing commitment. You either actively pursue vendor swappability and pay an up-front tax with more indirection in the design, or give it up and go with the flow.
-top
A MirrorModel is created when OO attempts to directly model features of any other system, including another software system. This design is contra-indicated by many. OopNotForDomainModeling. BertrandMeyer's famous "Reality is a cousin twice removed" - OO models a model of some reality. I have read a few times that one must model the problem, not an instance of a problem (unless one wants a rigid and fragile system), but I can't recall where.
In the case you describe, 'form_X' is the reality of another software system (or a requirements description). Perhaps 'form_X' has a couple text-areas, a few buttons, a color, some initial text, radio-buttons, and checkboxes, as well as demand for certain events on user manipulations. By these suggestions, a user of OO shouldn't model 'form_X_model', but could reasonably have the concept of 'forms' and perhaps various form-features (text areas, buttons, functors or scripts on events, etc.) necessary to describe a form_X. This allows one to describe the 'problem instance' (the GUI in question) as runtime data, and to tweak as necessary. The ability to rapidly tweak data is critical because one must assume that requirements are incomplete, floating, etc.
MirrorModel is avoided by having at least one LayerOfIndirection in the modeling.
Too many layers of indirection and you end up Greenspunning an entirely new GeneralPurposeProgrammingLanguage (which, beside being redundant, is likely to be slow and buggy and have many gotchas unless you're a skilled LanguageDesigner in addition to your domain skills). Too few layers and the program is rigid and inflexible in the face of changes and moving targets. Somewhere in-between is a DomainSpecificLanguage. There's an interesting bit of symmetry and composability, there, in the understanding that creating models-of-models or models-of-models-of-models (or, generically, /(models-of-)*models/) is really about creating higher-level languages. Using language is about language-design. ApiIsLanguage. FrameworkIsLanguage.
Anyhow, BertrandMeyer seems to think being twice removed from reality (model-of-a-model) is appropriate.
Not sure I agree. I tend to favor a random spattering of once-removed (app-specific), twice-removed (~DSL), thrice-removed (~scripting language) injection via an unholy trio of AbstractConstructor/PluginArchitecture/PolicyInjection frameworks. I never model the domain. I never model the model of the domain. I just model as objects whichever primitive components I need at the time, drop them into an AbstractFactory, give that to my AbstractConstructor, and glue them together using using scripts and an object-graph-configuration language. The application is simply an object-graph described by external data.
OTOH, I suspect BertrandMeyer was just making the comment ("Reality is a cousin twice removed") a witty one to get the point across (that OopNotForDomainModeling but OopWorksForDomainModelModeling?) rather than a design mandate. (OO is still not that great for domain-model-modeling, though... not without support for DataflowProgramming or PublishSubscribeModel to take care of the front-end construction and maintenance issues. Yet another framework to add...)
Anyhow, a potential challenge in avoiding MirrorModel is MirrorModelContagion.
See also: SeparateDomainFromPresentation, ModelViewController, MirrorModelContagion