A Declarative Evolution Framework for Object-Oriented Design Patterns Tom Mens Tom Tourwé {tom.mens | tom.tourwe}@vub.ac.be Programming Technology Lab Vrije Universiteit Brussel
Overview Introduction to design patterns Specification of design patterns and their instances Evolution of design pattern instances Evolution conflicts Tool support Conclusion Future work
Design patterns Offer successful and proven solutions for a design problem that occurs over and over again Improve understandability, maintainability, extensibility, reusability, etc. Are used in most object-oriented frameworks Gain increasing popularity Impose specific structure on implementation Define hot spots of an object-oriented framework Dictate relationships and collaborations between a set of classes/methods
Example: Observer instance in MVC update View PluggableListViewByItem PluggableListViewOfMany changed Model dependents
Pattern specification and constraint definition Use declarative meta programming patternInstance(MVC, ObserverDP). role(MVC, observer, [View]). role(MVC, concreteObserver, [PluggableListViewByItem]). role(MVC, concreteObserver, [PluggableListViewOfMany). role(MVC, subject, [Model]). role(MVC, updateMethod, [#update]). role(MVC, changeMethod, [#changed]) patternConstraint(?instance, ObserverDP) if role(?instance, subject, ?subject), role(?instance, changeMethod, ?changeselector), role(?instance, updateMethod,?updateselector), concreteMethod(?subject, ?changeselector), calls(?subject,?changeselector,?updateselector) declarative specification of the design pattern instance declarative constraint imposed by the design pattern on every instance
Automated transformations Refactorings High-level structural transformations that can be applied to a framework in a behavior-preserving way E.g., extractSuperclass, addParameter Design Pattern Refactorings Refactorings specific for a particular design pattern Are composed of a number of ordinary refactorings Applied to design pattern instances Make sure the constraints imposed by the pattern are adhered to E.g., addConcreteObserver, addUpdateMethod All refactorings are specified declaratively
Example evolutions role(MVC, changeMethod, [#changed:]). View Model update changed PluggableListViewByItem PluggableListViewOfMany update PluggableList extractSuperclass refactoring update: aSymbol addChangeMethod design pattern refactoring role(MVC, changeMethod, [#changed:]). role(MVC, updateMethod, [#update:]). changed: update PluggableListViewByItem PluggableListViewOfMany
Evolution conflicts Changes to the software Applied manually insufficient knowledge of design patterns (instances) can lead to violation of constraints Via automated (design pattern) refactorings problems when changes by different developers must be merged Structural merge conflicts Behavioural merge conflicts All conflicts can be detected using a declarative approach
Structural merge conflict View Model update changed changed: update and update: are implemented differently! update: aSymbol PluggableList update PluggableListViewOfMany PluggableListViewByItem update: aSymbol update: aSymbol
Constraint violations View Model update changed changed: update: aSymbol update QSOULPluggableListView Problems with QSOULPluggableListView (1) it does not implement update: (2) it is no subclass of PluggableList PluggableList update update: aSymbol PluggableListViewOfMany PluggableListViewByItem
Declarative conflict detection Explicitly log all refactorings applied and the software entities they work on Compare them one by one Different changes to one and the same software entity may lead to a conflict extractSuperclass View PluggableListView PLVByItem PLVOfMany update addChangeMethod View PLVByItem PLVOfMany update: changed: same hierarchy same role
Tool Support Specification facilities Browsing facilities User-friendly interface on top of declarative medium Browsing facilities All software entities (classes/methods/…) that participate in a given DP instance All DP instances in which a given software entity (class/method/…) participates Support for evolution and merging Offer list of refactorings that can be applied Provide warnings for possible conflicts Suggest solutions where possible
Tool Support
Conclusion Automated support for software evolution Through disciplined evolution of design pattern instances used in the framework Via explicit declarative specification and automated transformation of those instances Detection of evolution conflicts Structural & behavioural conflicts; constraint violation Using explicit high-level knowledge of the design and its evolution
Future Work Extensive validation on industrial cases Tool support & integration in existing IDEs Scalability of the approach Allow for different design pattern variants Many design patterns exist & new ones are constantly discovered Metapatterns as an abstraction of design patterns Formal basis for conflict detection Define conditions under which particular conflicts occur Requires formalisation of metapatterns