210 likes | 394 Views
Refactoring to Object-Oriented Design Patterns Mikal Ziane (LIP6 and Université Paris 5) Nicolas Pierron (LIP6 and LRDE) Context KBSE OO Design Patterns Detecting unwanted coupling Refactoring Perspectives and practical issues. Context. LIP6 /Network and Distributed Systems Dpt
E N D
Refactoring to Object-OrientedDesign Patterns Mikal Ziane (LIP6 and Université Paris 5) Nicolas Pierron (LIP6 and LRDE) • Context • KBSE • OO Design Patterns • Detecting unwanted coupling • Refactoring • Perspectives and practical issues This work was partially funded by the RNTL initiative (LUTIN project)
Context • LIP6 /Network and Distributed Systems Dpt • MoVe team • UML/MDA people • Petri net people • Other people • People working with me • 2 PhD students defended in November • 1 PhD student starting (MDA stuff, hopefully DS) • 1 co-advised with ETS (Quebec) on DS UML ?
Knowledge-based software engineering • Software development tools are really poor • Communication with developers: at a very low level • Exhibit and integrate developers’ know-how into assistant tools • One source of know-how: design patterns • Other areas of interest: • Semi-automatic refinement (B, DS over B) • Generation of user interfaces • Control transformations in pi-calculus ? • …
Design Patterns • Quite successful in disseminating design experience • Use a "form that PEOPLE can use effectively" • Pattern = name + problem + solution • NOT meant to be formalized • Tool support is superficial • The "problem" part is not supported • There are more and more patterns • It is hard to find which pattern solves a problem • Over-engineering is common => Tool support to match design problems with patterns is required
Picture Text Prototype Pattern Graphic Editor
An anti-pattern for Prototype public Graphic addElement (Icon i) { if ( /* i is a text icon */ ) return new Text(); else return new Picture(); }
What design problems ? • Two challenges in software engineering: • Complexity • Changes • Many design patterns prevent propagation of changes • They aim at decoupling clients from services • They introduce various kinds of indirections • Use patterns only when needed
When are patterns needed ? • Agile programming: • keep software simple • Refactor when maintenance cost increases or might increase • What entities will be stable/unstable in the near future ? • Our proposal: • hide unstable entities from more stable clients using decoupling constraints • Express decoupling in terms of static access rights • Generalization of OO encapsulation
Static Accesses • Full name: unambiguously references a program element • Occurrence of Access: occurrence of name n in some namespace ns. • Uses:relation on NameSpaces x Names. (ns, n) Uses ns mentions n at least one. • notation : uses (ns,n) • Only staticaccesses are considered: o.m() accesses o and the method m of the static type of o. • Dynamic accesses: • heavily used in design patterns • changes in the set of subtypes are managed by the compiler.
Access constraints • hidden (ns, n) not uses (ns, n) • More complex constraints defined in: • first-order logic • or hybrid modal logic. • Developers are expected to use high-level predicates which hide logical expressions
High-Level Predicates • hiddenClass (c) // class c is hidden name namesOf(c) client clientc hidden (client, name) • hiddenSubclasses (class) // the subclasses (or implementers) // of class are hidden c subclasses(class), hiddenClass(c) • virtualPackage(elements) name namesOf(c), client, client elements hidden (client, name)
Example public class Editor { private Line aLine; private Text aText; private Picture aPicture; public Editor() { aLine = new Line(); aText = new Text(); aPicture = new Picture(); } public void display () { aLine.draw(); aText.draw(); aPicture.draw(); }
Result of annotation process public class Editor { private /*<V>*/ edit.Line /* </V>*/ aLine; private /*<V>*/ edit.Text /* </V>*/ aText; private /*<V>*/ edit.Picture /*</V>*/ aPicture; public Editor () { aLine = new /*<V>*/ edit.Line /*</V>*/(); aText = new /*<V>*/ edit.Text /*</V>*/(); aPicture = new /*<V>*/ edit.Picture /*</V>*/(); } public void display() { /*<V>*/ aLine.draw() /*</V>*/; /*<V>*/ aText.draw() /*</V>*/; /*<V>*/ aPicture.draw() /*</V>*/; } }
Transformations • Introduce indirections to remove unwanted accesses • Introduce indirection = apply some kind of fold • Folds: • define a new abstraction (class, method, interface) or recognize an existing one • replace offending term by instance of abstraction • Effect of folds on access graph: uses (ns, n) {uses (ns, a), uses (a, n)} a ns ns n n
Kinds of folds • classical fold • extract-method ; move-method • dynamic statement fold • use polymorphic method • the second access relies on dynamic binding • data fold • displace data (and related computations) to another class • type fold • type inferencing interface hiding concrete classes
Expected result (work in progress) public class Editor { private Graphic aLine; // better : use collection private Graphic aText; private Graphic aPicture; public Editor( Graphic a, Graphic b, Graphic c) { aLine = a.clone(); // better : collection parameter aText = b.clone(); // this example is too artificial aPicture = c.clone(); } public void display () { aLine.draw(); // not transformed ! aText.draw(); // but infer that Graphic has aPicture.draw(); // a draw() method }
// this interface is introduced interface Graphic { public Graphic clone(); public void draw(); } // code for clone() is added to concrete classes
Results, Implications and Future Work • Results • Constraint checking (Stratego + Prolog) works on significant test applications (e.g. JLex) • Several folds implemented using stratego • Implications • Now people know what terms must be refactored (to patterns, …) • Developers can check that the problem has been solved ! • Generate-and-test approach becomes possible • Future work • Finish implementation of transformations • Define folds more cleanly • Experiment on more patterns and applications • Control combinatorial explosion induced by naive generate-and-test • Try CLP • Abstract interpretation of transformations on the access graph ?
Practical issues • Best way to distribute LUTIN ? • Installation issues • Integrate into Stratego build farm ? • Future of Dryad ?
Other areas of interest • Semi-Automatic refinement from domain-specific specification languages • Domain specific B ?? • Apply Stratego, Elan(?) • to domain-specific model engineering (DS MDA, DSL TOOLS …) ?