  During software evolution, inexperienced developers may introduce design
anti-patterns when they modify their software systems to fix bugs or to add new
functionalities based on changes in requirements. Developers may also use
design patterns to promote software quality or as a possible cure for some
design anti-patterns. Thus, design patterns and design anti-patterns are
introduced, removed, and mutated from one another by developers.
  Many studies investigated the evolution of design patterns and design
anti-patterns and their impact on software development. However, they
investigated design patterns or design anti-patterns in isolation and did not
consider their mutations and the impact of these mutations on software quality.
Therefore, we report our study of bidirectional mutations between design
patterns and design anti-patterns and the impacts of these mutations on
software change- and fault-proneness.
  We analyzed snapshots of seven Java software systems with diverse sizes,
evolution histories, and application domains. We built Markov models to capture
the probability of occurrences of the different design patterns and design
anti-patterns mutations. Results from our study show that (1) design patterns
and design anti-patterns mutate into other design patterns and/or design
anti-patterns. They also show that (2) some change types primarily trigger
mutations of design patterns and design anti-patterns (renaming and changes to
comments, declarations, and operators), and (3) some mutations of design
anti-patterns and design patterns are more faulty in specific contexts. These
results provide important insights into the evolution of design patterns and
design anti-patterns and its impact on the change- and fault-proneness of
software systems.
