This work was partially funded by the RNTL initiative (LUTIN project) 1 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
2 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 ?
3 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 ? –…
4 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
5 Prototype Pattern Editor Graphic PictureText
6 An anti-pattern for Prototype public Graphic addElement (Icon i) { if ( /* i is a text icon */ ) return new Text(); else return new Picture(); }
7 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
8 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
9 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 static accesses 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.
10 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
11 High-Level Predicates hiddenClass (c) // class c is hidden name namesOf(c) client client c 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)
12 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(); }
13 Access Graph
14 Result of annotation process public class Editor { private /* */ edit.Line /* */ aLine; private /* */ edit.Text /* */ aText; private /* */ edit.Picture /* */ aPicture; public Editor () { aLine = new /* */ edit.Line /* */(); aText = new /* */ edit.Text /* */(); aPicture = new /* */ edit.Picture /* */(); } public void display() { /* */ aLine.draw() /* */; /* */ aText.draw() /* */; /* */ aPicture.draw() /* */; }
15 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)} ns n n a
16 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
17 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 }
18 // this interface is introduced interface Graphic { public Graphic clone(); public void draw(); } // code for clone() is added to concrete classes
19 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 ?
20 Practical issues Best way to distribute LUTIN ? –Installation issues –Integrate into Stratego build farm ? Future of Dryad ?
21 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 …) ?