software practices lab. -- the university of british columbia 1 explicit programming kris de volder...

28
1 Software Practices Lab. -- The University of British Columbia Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail Murphy

Post on 18-Dec-2015

215 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

1Software Practices Lab. -- The University of British Columbia

Explicit Programming

Kris De Volder

Joint work with:Avi Bryant, Andrew Catton and Gail

Murphy

Page 2: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

2Software Practices Lab. -- The University of British Columbia

The Problem

A single design concept often results in a verbose amount

of scattered and tangled code

Hard to recover high-level design concepts from codeConceptual design is lost

Explicit Programming:

We want to make design concepts more explicit in the code

Page 3: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

3Software Practices Lab. -- The University of British Columbia

The Problem: Verbose Example

public class Student { // JavaBean property private int studentNR; // constrained JavaBean property private String firstName; // bound JavaBean property private String lastName;}

JavaBeanDesign Concepts are Clear

public class Student {// JavaBean propertyprivate int studentNR;

// constrained JavaBean propertyprivate String firstName;

// bound JavaBean propertyprivate String lastName;

private PropertyChangeSupport changes = new PropertyChangeSupport(this);

public void addPropertyChangeListener(String propertyName, PropertyChangeListener l) { changes.addPropertyChangeListener(propertyName, l); }

public void removePropertyChangeListener(String propertyName, PropertyChangeListener l) { changes.removePropertyChangeListener(propertyName, l); }

private VetoableChangeSupport vetos = new VetoableChangeSupport(this);

public void addVetoableChangeListener(String propertyName,VetoableChangeListener l) { vetos.addVetoableChangeListener(propertyName, l); } public void removeVetoableChangeListener(String propertyName,VetoableChangeListener l) { vetos.removeVetoableChangeListener(propertyName, l); }

public int getStudentNR() { return personID; }

public String getFirstName() { return firstName; }

public String getLastName() { return lastName; }

public void setStudenNR(int newValue) { personID = newValue; }

public void setLastName(String newValue) { String old = getLastName(); changes.firePropertyChange("lastName", old, newValue);

lastName = newValue; }

public void setFirstName(String newValue) {

String old = getLastName(); vetos.fireVetoableChange("firstName", old, newValue);

changes.firePropertyChange(”firstName", old, newValue); firstName = newValue; }

}

public class Student {// JavaBean propertyprivate int studentNR;

// constrained JavaBean propertyprivate String firstName;

// bound JavaBean propertyprivate String lastName;

private PropertyChangeSupport changes = new PropertyChangeSupport(this);

public void addPropertyChangeListener(String propertyName, PropertyChangeListener l) { changes.addPropertyChangeListener(propertyName, l); }

public void removePropertyChangeListener(String propertyName, PropertyChangeListener l) { changes.removePropertyChangeListener(propertyName, l); }

private VetoableChangeSupport vetos = new VetoableChangeSupport(this);

public void addVetoableChangeListener(String propertyName,VetoableChangeListener l) { vetos.addVetoableChangeListener(propertyName, l); } public void removeVetoableChangeListener(String propertyName,VetoableChangeListener l) { vetos.removeVetoableChangeListener(propertyName, l); }

public int getStudentNR() { return personID; }

public String getFirstName() { return firstName; }

public String getLastName() { return lastName; }

public void setStudenNR(int newValue) { personID = newValue; }

public void setLastName(String newValue) { String old = getLastName(); changes.firePropertyChange("lastName", old, newValue);

lastName = newValue; }

public void setFirstName(String newValue) {

String old = getLastName(); vetos.fireVetoableChange("firstName", old, newValue);

changes.firePropertyChange(”firstName", old, newValue); firstName = newValue; }

}

implementation

Verbose ImplementationDesign Concepts are Obscured

Page 4: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

4Software Practices Lab. -- The University of British Columbia

The Problem: Scattered Example

+ PrintVisitor

Tree

Node Leaf

Tree

Node Leafimplementation

TreeVisitor

PrintVisitor

accept accept

accept Implementation ofDesign Concept

Scattered=>

Hard to Recover Conceptual

Design

Page 5: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

5Software Practices Lab. -- The University of British Columbia

ELIDE: A tool that supports EP for Java• Allows a developer to introduce new modifiers on

classes, fields and methods• Semantics of modifiers defined in terms of code

transformations implemented in Java.

Explicit Programming and ELIDE

EXPLICIT PROGRAMMING:• Capture design concepts explicitly in code by

– incrementally introducing design-specific vocabulary in the code where the concept occurs.

modularizes implementation details:details in the transformation implementation, not in the code itself

Page 6: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

6Software Practices Lab. -- The University of British Columbia

Different Separation of Concerns Mechanisms

Trying to “solve” this problem

transformation anchor

With Elide

Transformation definitions

=

With Explicit Calls

calls to public interface

With Aspects

advice/introduce

Aspect

Page 7: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

7Software Practices Lab. -- The University of British Columbia

Elide Example: Java Bean Concept

Elide implementation of “Student bean”

public class Person{

property<> int personID;

constrainedProperty<> String firstName;

boundProperty<> String lastName;}

public class Person{

property<> int personID;

constrainedProperty<> String firstName;

boundProperty<> String lastName;}

When the meaning of the Elide modifiers is known the conceptual structure is immediately clear.

Page 8: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

8Software Practices Lab. -- The University of British Columbia

ELIDE modifier definition…

Example definition of property<> modifier:

public class Property extends BeanTransform {

... Helper methods ...

... Code transformations ...

}

• Code transformations implemented in Java• Coarse grained Java parse trees• API similar to java.lang.reflect

Modifier semantics

definedby a set of code

transformermethods

Use inheritance to structure the implementation ofsimilar modifiers

Page 9: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

9Software Practices Lab. -- The University of British Columbia

ELIDE modifier example continued…

public class Property extends BeanTransform {

satisfies<fieldAccess> public void makePrivate(FieldNode target) { ... } satisfies<methodDef> requires<fieldDef> public void addAccessor(FieldNode target) { ... } satisfies<methodDef> requires<fieldDef> public void addMutator(FieldNode target) { ... }

}

A single modifier can consist of multiple transformations:

Page 10: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

10Software Practices Lab. -- The University of British Columbia

ELIDE modifier example continued…

public class Property extends BeanTransform {

satisfies<fieldAccess> public void makePrivate(FieldNode target) { target.makePrivate(); }

...}

The AST FieldNode to which the property<> modifier is attached.

An ELIDE modifier to control transformation execution order:this transformation must go before any that requires<fieldAccess>

ELIDE API: similar to java.lang.reflect + some mutation operations

Page 11: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

11Software Practices Lab. -- The University of British Columbia

Back to… Modifier Definition Example

satisfies<methodDef> requires<fieldDef>public void addAccessor(FieldNode target) { String name = target.getName(); String casedName = Utils.methodCase(name);

target.getDeclaringClass().extend( %{ public #{target.getType(name)}# get#{casedName}#()

{ return #{name}#;

} }%);}

Access declaration context

Quasiquote

unquoted expression

and extend it with…

From the definition of property<>

Page 12: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

12Software Practices Lab. -- The University of British Columbia

Crosscutting modifier example: visited<...>

visited<TreeVisitor> class SomeTreeClass { ...}

Modifiers can be parameterized with extra arguments.In this example: which kind of visitor can visit this class.

• Makes visitor concept more explicit.• Declares what kind of visitor is “visiting” this class• Expands to appropriate accept and visit methods in SomeTreeClass and TreeVisitor class.

• Creates Visitor class (if needed)

This modifier

Adds methods in two different classes !

Page 13: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

13Software Practices Lab. -- The University of British Columbia

“Scattered” modifier example: visited<...>

public class Visited extends Transform {

}

visited<TreeVisitor> class SomeTreeClass

/** add accept method to visited class */satisfies<methodDefinition>public void addAccept(ClassNode targ,String visitorName) {...}

/** add visit method to visitor class */satisfies<methodDefinition>public void addVisit(ClassNode targ, String visitorName) {...}

modifier argument

/** auxiliary method get/create visitor class*/...

Page 14: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

14Software Practices Lab. -- The University of British Columbia

A crosscutting modifier example: visited<...>

satisfies<methodDefinition> public void addAccept(ClassNode target, String visitorName){ target.extend( %{ public void accept(#{visitorName}# visitor) { visitor.visit(this); } }%);}

Adding accept method to Visited class

Page 15: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

15Software Practices Lab. -- The University of British Columbia

A crosscutting modifier example: visited<...>

satisfies<methodDefinition>public void addVisit(ClassNode target, String visitorName){ ClassNode visitor = getVisitorClass(target, visitorName);

visitor.extend( %{ public abstract void visit(#{target.getShortName()}# element); }%);}

Adding visit method to Visitor class.

Find or create the visitor class …

and extend it with …

Page 16: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

16Software Practices Lab. -- The University of British Columbia

“Scattered” modifier example: visited<...>

private ClassNode getVisitorClass (ClassNode target, String visitorName) { PackageNode pkg = target.getPackage(); ClassNode visitor = pkg.getClass(visitorName); if( visitor == null ) { visitor = NodeFactory.createClass( %{

public abstract class #{visitorName}# { } }%); pkg.add(visitor); } return visitor;}

Aux. method: find the visitor class. When it does not already exist, create it.

create new class node

and add it to the package

Page 17: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

17Software Practices Lab. -- The University of British Columbia

ELIDE modifier examples: DBC

invariant<%{anExp}%> class SomeClass …– Declare class invariant– Inserts appropriate checks in all public methods,

throws runtime exceptions if violated.

precond <%{anExp}%> ... methodDecl ...– Declare method precondition– Throws runtime exception when violated

Page 18: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

18Software Practices Lab. -- The University of British Columbia

ELIDE modifier examples: JUnit

test<%{…test…}%> ... methodDecl ...– Declare JUnit test code for a particular method

– Creates a testing method in a separate TestCase class

– Creates a TestCase class (one per class with tested methods)

– Creates a TestSuite class that calls all TestCases.

Page 19: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

19Software Practices Lab. -- The University of British Columbia

An application of ELIDE: AVID

• AVID– visualization tool for execution of Java programs– looked at subset:

• 4200 loc or 1100 NCSS• complex inheritance hierarchy:

24 classes with depth 7

• Iteratively applied ELIDE

Page 20: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

20Software Practices Lab. -- The University of British Columbia

An example AVID class

allAccessors<>equals<>read<>write<>flyweight<>public abstract class EventEncoding

extends Encoding { private ThreadID threadID;

private ClassID classID;}

Expands to about 75 lines of Java (no comments)

After several refactoring steps …

accessors for all fieldsequals method, compares all fields

AVID specific reader and writer methods for permanent storage of trace data.

AVID specific implementation of flyweightdesign pattern

Page 21: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

21Software Practices Lab. -- The University of British Columbia

Different Separation of Concerns Mechanisms

Trying to “solve” this problem

transformation anchor

With Elide

Transformation definitions

=

With Explicit Calls

calls to public interface

With Aspects

advice/introduce

Aspect

Different characteristics

Different tradeoffs

How to characterize the differences between

mechanisms?

Page 22: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

22Software Practices Lab. -- The University of British Columbia

Comparison Point 1: who decides where to apply?

Receiver decides:request provider explicitly

IntroductionAdvice

ELIDEModifiers are “explicit receiver beacons” in the code

but the transform implementations can decide where, how and what functionality is provided.

No restrictions on where functionality may go from there!

Assuming two “participants” in a composition:• a provider of functionality, code, behavior, interface, …• a receiver of functionality …

Which participant decides where/when functionality “goes”.

Procedure-callMacro expansion

Provider decides:imposes functionality on

receiver

Page 23: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

23Software Practices Lab. -- The University of British Columbia

Point 2: context information, how and how much?

Explicit parameter passing.Provider can only access that which is explicitly provided as arguments by receiver.

Provider can get access to the receiver context through a restricted interface Receiver has no control over how much can be accessed.

Procedure-callMacro expansion

IntroductionAdvice

Inheritance withlate binding

More restricted

Less Restricted

ELIDEProvider can roam freely about the AST to find out what it needs.

Page 24: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

24Software Practices Lab. -- The University of British Columbia

Why are These Tradeofs Right for ELIDE?

Hypothesis: Some design concepts are hard to capture because…

B: Evolution: emerging concepts gradually crystallize.- initially poorly understood and chaotic implementation- tends to evolve to more regular and less coupled=> Need ability to evolve gradually between

“provider decides” and “receiver decides” (or in other words: from more local -> less local expansion)

A: Complex coupling:1) often complex context dependencies

=> make it hard to abstract and generalize=> Need wide interface to access context information!

2) often coupled to specific classes/methods• More natural to capture explicitly “where they occur”.• but still want to hide scattered details and clutter.=> Need mix of “provider decides” and “receiver decides”

Page 25: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

25Software Practices Lab. -- The University of British Columbia

EINDE

VRAGEN?

Page 26: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

26Software Practices Lab. -- The University of British Columbia

Related work

• Aspect-oriented programming [Kiczales et al 97] and AspectJ– ELIDE modularizes a concept but leaves “explicit

modifiers” in the base code

• Intentional programming [Simonyi 95]– Same main goal– ELIDE is lower-cost to apply but results in less

support within development environment

Page 27: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

27Software Practices Lab. -- The University of British Columbia

Related work

• Domain-specific languages– e.g., Jakarta Tool Suite [Batory et al 98]– ELIDE is cheaper and developer does not have to be a

language expert

• Macros– e.g., Lisp, JSE [Bachrach & Playford 01], Maya [Baker &

Hsieh 01]– ELIDE permits non-local transformations

Page 28: Software Practices Lab. -- The University of British Columbia 1 Explicit Programming Kris De Volder Joint work with: Avi Bryant, Andrew Catton and Gail

36Software Practices Lab. -- The University of British Columbia

ELIDE AST Structure

PackageNode

ClassNoden

FieldNode

MethodNode

ConstructorNode

n

n

n

n

InstanceBlockNode

StaticBlockNoden