Presentation is loading. Please wait.

Presentation is loading. Please wait.

Workshop: Moderne Softwareentwicklungs-Methoden Teil 1: AOP, MDSOC, GP, IP Teil 2: eXtreme Programming Markus Völter markus.voelter@mathema.de Michael.

Similar presentations


Presentation on theme: "Workshop: Moderne Softwareentwicklungs-Methoden Teil 1: AOP, MDSOC, GP, IP Teil 2: eXtreme Programming Markus Völter markus.voelter@mathema.de Michael."— Presentation transcript:

1 Workshop: Moderne Softwareentwicklungs-Methoden Teil 1: AOP, MDSOC, GP, IP Teil 2: eXtreme Programming Markus Völter Michael Wiedeking

2 Contents (I) The big picture Generative Programming
Product Line Engineering Variability Analysis How AOP, GP, IP and MDSOC can help Generative Programming Principles Compile-time Metaprogramming (using templates) Jenerator – Generative Programming for Java Other GP tools Aspect-Oriented Programming Patterns for AOP AspectJ Sally Jenerator and AOP

3 Contents (II) Multidimensional Separation of Concerns
Problem revisited: Multidimensional Variability Example introduced: SEE Hyper/J concepts Example continued Intentional Programming Background Basic Concepts IP System Architecture Active Source Stunning Features  Thanks Resources

4 The big picture Product Line Engineering Variability Analysis How AOP, GP, IP and MDSOC can help

5 Common Roots: Product Line Engineering
Instead of developing one single system, development focuses on a family of related systems.Reasons: different target platforms (operating system, middleware) different quality of service (QoS) requirements, potential for future growth Systems are built from product-specific parts and reusable part: the common platform Creation of concrete systems should be done with the help of a (semi-)automatic process industrialized production of software „build software like they build cars“

6 Common Roots: Product Line Engineering
Software Family as defined by Parnas in 1976: We consider a set of programs to constitute a family whenever it is worthwhile to study programs from the set by first studying the common properties of the set and then determining the special properties of the individual family members. Instead of developing one single system, development focuses on a family of related systems.Reasons: different target platforms (operating system, middleware) different quality of service (QoS) requirements, potential for future growth Creation of concrete systems should be done with the help of a (semi-)automatic process industrialized production of software „build software like they build cars“

7 Product Line Engineering: Process
Domain Scoping Variability Analysis Domain Structuring Define common architecture Define Production Plan Define Building Blocks Components DSLs & Generators Production Process

8 Product Line Engineering: Process
AOP, IP, GP & MDSOC are located here. But first...

9 Domain Analysis Goal: A domain model
Scoping defines, what is part of the domain, and what is not (defines the range of possible products) Example: GQM (Goal Question Metric) A common vocabulary defines the terms in which the domain can be described The commonalities and the differences between different products in the domain have to be defined  Variability Analysis

10 Variability Analysis Variability analysis discovers the variable and fixed parts of a product in a domain. Parts can be structural, or behavioral (functional) non-functional (technical) To define variable aspects, we need to have a commonality base: something fixed There are two kinds of variability: positive variability: add something (optional) negative variability: removes something (essential) Positive variability leaves the concept intact, while netative variability does not.

11 Domain Analysis: Feature Modelling
Feature Modelling is more abstract than OO analysis and design because it does not prescribe the realization of features A feature model describes the (sub-)features of a concept Subfeatures can be Mandatory Optional Alternative N of M A feature model can be multi-dimensional A graphical notation exists: feature diagrams

12 Feature Diagram: Aircraft example
Example products: An aircraft with a low wing, piston engine and made of metal, wood and cloth: Robin DR-400 An aircraft with shoulder wing, no engine and made of plastic: ASW-27 An aircraft with low wing, jet engine(s) and made of metal: Airbus A320

13 More features of feature diagrams
They can contain constraints on the combinations of features They can define „names“ for specific combinations of features; feature groups Features can be open: additional subfeatures can be added Features can be incomplete: the subfeatures are not yet defined Multiplicity of subfeatures can be added

14 Exercise 1: Feature Models
Describe a feature model for a specific concept using a feature diagram. You may use a suitable editor for that purpose. Possible concepts: Personal Computer, Vehicle, JVM, curriculum, list (software)

15 Binding Times A feature diagram defines the common and variable aspects of a system. It has to be defined, when the variable aspects are fixed for a particular product. This is called binding time. Usually, binding time has consequences on flexibility performance code size type safety and: on the technique used to implement the variable aspect

16 Typical Binding Times source time: manual programming, template parameters compile time: function overloading, precompiler, template evaluation link time: DLLs, class loading run time: virtual functions, inheritance & polymorphism, factory-based instance creation, delegation deployment/configuration time: component deployment (impl. for an interface), environment variables

17 Binding Times and consequences (at runtime)

18 Exercise 2: Binding Times
Depending on the programming language used, there are different techniques how the binding times can be realised. Some may even be impossible. Select one of the following languages and describe the possible realization of the binding times, as well as potential advantages and drawbacks: Languages: C++, Java, Eiffel, Ada, Smalltalk, Perl

19 Source Time binding Source time binding is tedious and error prone, because it has to be programmed manually. However, it has significant advantages: High performance, low code size Of course, some flexibility is sacrificed To make source time binding more efficiently usable, generative programming can be used.

20 Multi-Dimensional Variability
A software system, and a family of systems in a domain, is usually decomposed, or structured using one dimension only.

21 What is multi-dimensional variability
Multi-Dimensional means: The variability aspects can vary independently They cannot be decomposed in one hierarchy Typically, the result is many possible combinations (permutations) of the dimensions

22 Multi-Dimensional Variability
What, if an certain feature cannot be decomposed along this same dimension?

23 Multi-Dimensional Variability: Apache Example
Logging Session Expiration

24 Multi-Dimensional Variability
Things that are tangled all through the primary decomposition structure are called cross-cutting concerns. have a well-defined purpose have a non-obvious structure Thus, Aspects are a way to separate concerns. It catches cross-cutting concerns in a single syntactic entity

25 AOP generalized AOP uses one primary decomposition structure (classes) and several additional aspects that cross-cut this structure. New aspects can be added after the system is designed A more generalized approach to realizing multi-dimensional variability is Multi-Dimensional Separation of Concerns (MDSOC): There is no primary decomposition structure, all dimensions are treated equal. each concerns is specified in its decomposition structure, and combined with other concerns in a second step.

26 MDSOC-Techniques Help to modularize the different concerns (dimensions) that arise from the feature model of a product family. Examples of MDSOC are adaptive programming aspect oriented programming (AOP) composition filters role-modelling subject-oriented programming (SOP) hyperspaces

27 Specifying products A product in a software family can be specified by combining the features in a specific, legal way. Such a specification can become quite complex, because Several different techniques might be used Constraints on the feature model have to be enforced It might be very low-level (programming-language dependent) To overcome these problems, Domain-Specific Languages can be used.

28 Domain-Specific Languages (DSLs)
Allow to specify systems (or products of a family) in terms (vocabulary) of the software family. A higher level of expressiveness is thus reached. Thus, Intentional Programming can be seen as a construction kit for multilevel-DSLs: represents general and domain specific abstractions as intentions provides an extensible environment that allows to load (domain-specific) extensions represents source code as active entities extensions can affect the complete environment; the editor, compiler, debugger, version control, ...

29 Relations among the mentioned techniques

30 Domain Engineering: Can it be used today?
It has been in use by several institutions, e.g. SEI, Mobile Phone manufacturers Feature models and diagrams are useable today and very helpful, so is variability analysis. Frameworks are a way to realize product lines, as well as components. Both are in use today. Thinking about binding times other than runtime is also very useful. Ok, this is not really part of the tutorial, but anyway 

31 Generative Programming Principles Compile-time Metaprogramming Jenerator – Generative Programming for Java Other GP tools

32 Generative Programming (GP)
Industrialized production of products from a product line/system family Take care of the different binding times by using appropriate tools For example code generation to take care of source time variability, Reflection at runtime Optimization wherever possible and useful Improve performance by remove runtime decisions Reduce code size by only including the really needed parts

33 GP Elements Generative Domain Model consists of the following elements
A way to specify products (family members) Implementation components from which these members can be assembled And configuration knowledge, which maps between the spec of a member and its implementation The terms problem space and solution space are used for specification and implementation components

34 Product Specification
Product specification is usually done by using feature models (in textual or graphical notation) declarative languages (DSLs) regular programming with generators

35 Configuration Knowledge
Constraints on the configuration space, i.e. legal and illegal product configurations Defaults configurations (default components and dependencies) Feature mapping (which implementation components satisfy which feature) Optimizations (optimzing for performance, or for code size, or for safety)

36 Implementation Components
Active Libraries (such as template libraries that generate code) DSLs and their mappings code generators code transformers

37 GP Example: C++ Template Metaprogramming
Also called compile-time metaprogramming, because metaprograms „run“ while the program is compiled Uses the features of C++ template instantiation Programming style is „functional“ and operates on types Note that some awkward constructs are required, because C++ templates were not originally intended for this purpose and many generally unknown and non-trivial features of the standard are used. Error reporting is usually clumsy

38 GP Example: C++ Template Metaprogramming
struct SimpleBoundsChecker; template<class ElementType, class BoundsChecker=SimpleBoundsChecker> class Vector { public: //... ElementType& at(const int& i) { BoundsChecker::checkBounds(i,length); } }; struct OutOfBounds {}; struct SimpleBoundsChecker { static void checkBounds(const int& i,const int& length) { if(i<0 || i>=length) throw OutOfBounds(); struct EmptyBoundsChecker { static void checkBounds(const int& i,const int& length) { } }; //... int main() { Vector<int> v1; //v1 uses SimpleBoundsChecker Vector<int, EmptyBoundsChecker> v2; //v2 uses EmptyBoundsChecker return 0;

39 GP Example: C++ Template Metaprogramming
struct SimpleBoundsChecker; template<class ElementType, class BoundsChecker=SimpleBoundsChecker> class Vector { public: //... ElementType& at(const int& i) { BoundsChecker::checkBounds(i,length); } }; struct OutOfBounds {}; struct SimpleBoundsChecker { static void checkBounds(const int& i,const int& length) { if(i<0 || i>=length) throw OutOfBounds(); struct EmptyBoundsChecker { static void checkBounds(const int& i,const int& length) { } }; //... int main() { Vector<int> v1; //v1 uses SimpleBoundsChecker Vector<int, EmptyBoundsChecker> v2; //v2 uses EmptyBoundsChecker return 0; „combines“ the classes at compile time Creates only those versions that are really used Inlining is used to improve runtime performance (or reduce code size) Calls to empty operations are eliminated

40 Template Metaprogramming: IF
A static if can be used to check boolean conditions on types at compile time. #include <iostream> using namespace std; template<bool condition, class Then, class Else> struct IF { typedef Then RET; }; //specialization for condition==false template<class Then, class Else> struct IF<false, Then, Else> { typedef Else RET; void main() { cout << "sizeof(short) = " << sizeof(short) << endl << "sizeof(int) = " << sizeof(int) << endl << "sizeof(IF<(1+2>4), short, int>::RET) = " << sizeof(IF<(1+2>4), short, int>::RET) << endl; IF<(1+2>4), short, int>::RET i; //the type of i is int! }

41 Compile Time Factorial
Statically calculates the factorial of an int at compile time! At runtime, the result is a constant! #include <iostream> using namespace std; #include "../meta/meta.h" using namespace meta; struct Stop { enum { RET = 1 }; }; template<int n> struct Factorial { typedef IF<n==0, Stop, Factorial<n-1> >::RET PreviousFactorial; enum { RET = (n==0) ? PreviousFactorial::RET : PreviousFactorial::RET * n }; void main() { cout << Factorial<3>::RET << endl; }

42 Other compile time functions
Static versions of switch, while, do-while for etc... It has been shown that the C++ template facility can be used as a full-blown functional programming language. Its data are the types and constant integral values of the C++ language. In generative programming, these and other constructs are used to select code to be included in the final program.

43 Exercise 3: Template Metaprogramming
Below you can find a static version of switch. Try(!) to explain how it works. #include <iostream> using namespace std; #include "../meta/meta.h" using meta::IF; const int DEFAULT = ~(~0u >> 1); //initialize with smallest struct NilCase {}; template <int tag_, class Type_, class Next_ = NilCase> struct CASE { enum { tag = tag_ }; typedef Type_ Type; typedef Next_ Next; }; // SWITCH<> template<int tag, class Case> class SWITCH { typedef typename Case::Next NextCase; enum { caseTag = Case::tag, found = (caseTag == tag || caseTag == DEFAULT) }; public: typedef IF<found, typename Case::Type, typename SWITCH<tag, NextCase>::RET >::RET RET; template<int tag> class SWITCH<tag, NilCase> {public: typedef NilCase RET; // test struct A {static void exec(){ cout << "A" << endl;} }; struct B {static void exec(){ cout << "B" << endl;} }; struct D {static void exec(){ cout << "Def" << endl;}}; void main() { SWITCH<(1+1-2), CASE<1,A, CASE<2,B, CASE<DEFAULT,D > > > > ::RET::exec(); }

44 Why use template metaprogramming
Allows you to „modify“ or adapt your program at compile time to achieve Performance Optimizations, Inlining, Loop unrolling Size-specific adaptions Type-specific adaptions Memory Optimizations Code size Optimizations Keep out all the code that is not necessary Use code optimized for specific cases Other stuff Adapt Interfaces at compile time Impress and scare other people 

45 Example: Generic Container

46 Example: Generic Container
template<class Generator> class PtrList { public: //make Config available as a member type typedef typename Generator::Config Config; private: typedef typename Config::ElementType ElementType; typedef typename Config::SetHeadElementType SetHeadElementType; typedef typename Config::ReturnType ReturnType; typedef typename Config::Destroyer Destroyer; typedef typename Config::TypeChecker TypeChecker; typedef typename Config::Copier Copier; public: PtrList(SetHeadElementType& h, ReturnType *t = 0) : head_(0), tail_(t) { setHead(h); } ~PtrList() { Destroyer::destroy(head_); void setHead(SetHeadElementType& h) { TypeChecker::check(h); head_ = Copier::copy(h); ElementType& head() { return *head_; } void setTail(ReturnType *t) { tail_ = t; } ReturnType *tail() const { return tail_; } private: ElementType* head_; ReturnType *tail_; };

47 Example: Generic Container
template<class Generator> class PtrList { public: //make Config available as a member type typedef typename Generator::Config Config; private: typedef typename Config::ElementType ElementType; typedef typename Config::SetHeadElementType SetHeadElementType; typedef typename Config::ReturnType ReturnType; typedef typename Config::Destroyer Destroyer; typedef typename Config::TypeChecker TypeChecker; typedef typename Config::Copier Copier; public: PtrList(SetHeadElementType& h, ReturnType *t = 0) : head_(0), tail_(t) { setHead(h); } ~PtrList() { Destroyer::destroy(head_); void setHead(SetHeadElementType& h) { TypeChecker::check(h); head_ = Copier::copy(h); ElementType& head() { return *head_; } void setTail(ReturnType *t) { tail_ = t; } ReturnType *tail() const { return tail_; } private: ElementType* head_; ReturnType *tail_; }; specific specialized templated classes exist for Copier, TypeChecker and Destroyer (kind of static subclassing) Config serves as the configuration repository and defines, which of them is used in a particular generation

48 Example: Generic Container
Config serves as the configuration repository for a specific List instantiation struct RefPolyPersonListConfig { typedef Person ElementType; typedef ElementType SetHeadElementType; typedef EmptyDestroyer<ElementType> Destroyer; typedef EmptyTypeChecker<ElementType> TypeChecker; typedef EmptyCopier<ElementType> Copier; typedef PtrList<RefPolyPersonListConfig> ReturnType; } // use it! Typedef RefPolyPersonListConfig::ReturnType PersonList; PersonList list = new PersonList();

49 Example: Generic Container
Last step: A Generator that takes a config structure and returns the generated product. It uses enums, static IFs and static SWITCHes heavily. Provides useful defaults Usage example: LIST_GEN< Person, ext_ref, poly >::RET someList;

50 Example: Generative Programming in Java
Java provides no templates. Template metaprogramming thus cannot work! Also, GJ or Java 1.5 templates or Ada can‘t do it, because they are implemented differently. One approach is Jenerator, a code generation framework in and for Java. It is implemented by MATHEMA and used in several projects EJB generation Component Container generation ...

51 Example: Hello Jenerator
public class HelloJenerator { public HelloJenerator() { CClass createdClass = new CClass( “jenerator", "HelloWorld" ); CMethod mainMethod = new CMethod( CVisibility.PUBLIC, CType.VOID, "main" ); mainMethod.addParameter( new CParameter( CType.user( "String[]" ), "args" ) ); mainMethod.addToBody( new ClassInstantiation( createdClass.getName(), "app", true ) ); CConstructor cons = new CConstructor( CVisibility.PUBLIC ); cons.addToBody( new CCode( "System.out.println(\"Hello World!\");" ) ); createdClass.addConstructor( cons ); createdClass.addMethod( mainMethod ); new CodeGenerator().createCode( createdClass ); }

52 Jenerator Guiding Principle
Every interesting part of the AST can be modelled explicitly

53 Jenerator: Principles for extension – building generative components
Jenerator applies the usual OO concepts on the generator level: Subclassing: By subclassing generator classes, higher-level, domain specific generators can be created. Parametrization: By parametrizing the generator classes, the behaviour of a generator can be easily controlled. Delegation: Generator classes can use each other, creating more complex results.

54 Exercise 4: Jenerator You have seen the „Hello World“ program for Jenerator. It creates a CMethod object and prints out hello world. Try to outline how a CMainMethod could look like. It should contain the typical signature of main() and allow the programmer to add arbitrary code to the body of the operation.

55 Jenerator: More Advanced Techniques: Macros
A macro is an entity that modifies a CClass. Example: JavaBean properties can also operate on ClassGroups (see EJB generation) class SomeClass { private String id; public void setId( String _id ) { id = _id; } public String getId() { return id; } } new Property( "name", CType.STRING ).execute( createdClass );

56 Jenerator Examples: Interceptor proxy
Goal: For each class, a Proxy should be generated Proxy allows to insert Interceptors to the invocation chain Good performance Must work for any class!! Implementation alternatives: Java‘s Proxy API can do that dynamically, but with significant runtime overhead. Jenerator does it in a generative fashion, i.e. almost no overhead.

57 Jenerator Examples: Interceptor proxy
Goal: Be able to attach Interceptors to any object public class Test { public void addInterceptors( Interceptable ic ) { ic.addInterceptor( new NonNullInterceptor() ); } public Test() { TestGenerated tg = new TestGenerated(); tg = new TestGeneratedInterceptor( tg ); addInterceptors( (Interceptable)tg ); tg.test2(); tg.test3(null); public static void main( String[] args ) { new Test();

58 Jenerator Examples: Interceptor proxy
Some interfaces are required Example interceptor: Throws exception in case of null argument public abstract class DynamicInterceptor { public abstract void preInvoke( Object target, String opName, Object[] params, String[] paramNames ) throws Stop; } public interface Interceptable { void addInterceptor( DynamicInterceptor interceptor ); public class NonNullInterceptor extends DynamicInterceptor { public void preInvoke( Object target, String opName, Object[] params, String[] paramNames ) throws Stop { for ( int i=0; i<params.length; i++ ) { if ( params[i] == null ) throw new Stop( "null value caught: "+paramNames[i] ); } } }

59 Jenerator Examples: Interceptor proxy
Once the generators are implemented, their use is fairly simple (their implementation isn‘t hard either, it‘s just too much code to show here ) CClass testClass = new CClass( "generated", "TestGenerated" ); CMethod testMethod = new CMethod( CVisibility.PUBLIC, CType.INT, "test2" ); testMethod.addChild( new CSysOut( "Test2" ) ); testMethod.addChild( new CCode( "return 0;" ) ); testClass.addMethod( testMethod ); CMethod am = new CMethod( CVisibility.PUBLIC, CType.VOID, "test3" ); am.addParameter( new CParameter( CType.OBJECT, "aParam" ) ); am.addChild( new CSysOut( "Test3" ) ); testClass.addMethod( am ); am = new CMethod( CVisibility.PUBLIC, CType.VOID, "test6" ); am.addParameter( new CParameter( CType.INT, "aParam" ) ); gen = new InterceptorProxy( testClass ); CClass proxy2 = gen.generateProxy( null );

60 Exercise 5: Jenerator II
The example just seen creates a proxy for an aribitrary class and provides an interface to plug-in interceptors at runtime (runtime of the generated program). This still has some performance overhead, because at runtime the system has to iterate over the interceptors and do quite a lot of method invocations... Try to optimize this by inlining the interceptors calls directly at the call sites. Of course, the configuration of which interceptors to use will have to happen at generation time.

61 Other GP examples: COMPOST
COMPOST is a software composition system to engineer reengineer evolve software by program transformations. COMPOST supports invasive composition COMPOST's architectural language is Java Technically, COMPOST is a set of tools cooperating to attack the problems described above. COMPOST is still a research tool. URL: i44s11.info.uni-karlsruhe.de/~compost/

62 Other GP examples: COMPOST (II)
COMPOST Recorder. It provides Parsing and unparsing of Java sources Simple preprocessors, simple code generators, source code beautification tools Name and type analysis for Java programs Software visualization tools, software metrics, Lint-like semantic problem detection tools, design problem detection tools (anti-patterns), cross-referencing tools Transformation of Java sources Preprocessors for language extensions, semantic macros, aspect weavers, source code obfuscation tools, compilers Incremental analysis and transformation of Java sources Source code optimization, refactoring tool, software migration programs (Smart Patches), design pattern, clichés and idiom synthesis, architectural connector synthesis, adaptive programming environments, invasive software composition

63 Other GP examples: FUUT-je
FUUT-je (The Fantastic, Unique UML Fool for the Java Environment) Generates code from (simple) UML models Uses a mix of Java code and UML for code generation. Has been used by the author to generate code for IBM‘s San Francisco URL:

64 Other GP examples: FUUT-je (II)
<Rule> <Target>Attributes</Target> <Condition> scope = public </Condition> /** * Gets the #<attribute.name># property */ public #<type># get#<u.name>#() { return #<name>#; } </Rule> * Sets the #<name># property (#<type>#) value. public void set#<u.name>#(#<type># p#<u.name>#) { #<name># = p#<u.name>#; /**Gets the description property */ public String getDescription() { return description; } /** Sets the owner property */ public void setOwner(String pOwner) { owner = pOwner;

65 Other GP examples: MDA (ok, to some extent)
MDA is OMG‘s new initiative Generate application code from plattform independent domain models (UML) using well-defined rules and transformations. URL:

66 ? GP: Can it be used today? Generating code is not completely new and is used today. Template metaprogramming is used increasingly in C++, for example in the BOOST library. Several approach exist and can be used, others are still subject to research.

67 Aspect Oriented Programming Principles Patterns for AOP AspectJ Sally Jenerator and AOP

68 AOP principles AOP is a „mind set“ and can be used with ordinary programming languages. Key point is Separation of Concerns. Some design patterns can help to realize AOP concepts in normal languages.

69 Exercise 6: Aspects Join up in groups, agree on a well-known kind of application and try to identify some typical aspects, things, that are usually scattered all over the place.

70 DIY-AOP: Decorator Es kann transparent zu einem Objekt neue Funktionalität hinzugefügt werden, z.B. pre/post operations

71 DIY-AOP: Decorator

72 DIY-AOP: Proxy Proxies können Methodenaufrufe „abfangen“ und deren Semantik verändern Beispiel: Remote Proxy

73 DIY-AOP: Factory Factories abstrahieren den Erstellungsprozess von Objektes Damit können z.B. Proxies, Singletons oder Decorators erstellt werden

74 Exercise 7: Aspects and Patterns
You want to provide a Logging aspect for method invocations and for object creation for your applications. It should be possible to run the application with or without logging enabled. Use the above mentioned patterns to implement these requirements as separate entities. Discuss advantages and drawbacks of implementing aspects this way.

75 AOP compared to Frameworks
Frameworks require an identification of hot spots as part of its design. AOP allows you to inject aspects into a completely designed system without prior planning. Thus, many of the goals of frameworks can also be realized by AOP, of course with a different approach.

76 AOP tools: AspectJ AspectJ is an AOP extension to Java.
It allows to define aspects as separate source entities They are woven together with the regular code before compilation. The result of the weaving process is normal Java source.

77 Java and Aspects in AspectJ
Join points connect normal Java programs and Aspects “points in the execution” of Java programs 4 small additions to Java Pointcuts pick out join points and values at those points Advices define additional action to take at join points in a pointcut Introductions add additional fields/methods/constructors to classes Aspects are crosscutting types comprised of advice, introduction, field,constructor and method declarations

78 Typical Join Points Usually, join points are concerned with the message exchange between objects, i.e. method calls. several kinds of join points method & constructor call join points method & constructor execution join points field get & set join points exception handler execution join points static & dynamic initialization join points

79 Example: Figures in Drawing application
Goal: Display has to be updated when figures move. class Line implements FigureElement{ private Point p1, p2; Point getP1() { return p1; } Point getP2() { return p2; } void setP1(Point p1) { this.p1 = p1; } void setP2(Point p2) { this.p2 = p2; } } class Point implements FigureElement { private int x = 0, y = 0; int getX() { return x; } int getY() { return y; } void setX(int x) { this.x = x; } void setY(int y) { this.y = y; }

80 Example without aspects
Invasive change required because it is a cross-cutting concern. class Line { private Point p1, p2; Point getP1() { return p1; } Point getP2() { return p2; } void setP1(Point p1) { this.p1 = p1; MoveTracking.setFlag(); } void setP2(Point p2) { this.p2 = p2; class MoveTracking { private static boolean flag = false; public static void setFlag() { flag = true; } public static boolean testAndClear() { boolean result = flag; flag = false; return result;

81 Example: Figures in Drawing application
each time a Line receives a void setP1(Point) or void setP2(Point) method call The following pointcut captures this situation: We want to „step in“ after the point has been updated: pointcut move(): call(void Line.setP1(Point)) || call(void Line.setP2(Point));

82 Aspect declaration that does just that
aspect MoveTracking { private boolean flag = false; public boolean testAndClear() { boolean result = flag; flag = false; return result; } pointcut move(): call(void Line.setP1(Point)) || call(void Line.setP2(Point)); after() returning: move() { flag = true; // and update display

83 Aspect declaration that does just that
public boolean testAndClear() { boolean result = flag; flag = false; return result; } pointcut move(): call(void Line.setP1(Point)) || call(void Line.setP2(Point)); after() returning: move() { flag = true; // and update display Advising several classes is also possible: pointcut move(): call(void Line.setP1(Point)) || call(void Line.setP2(Point)) || call(void Point.setX(int)) || call(void Point.setY(int));

84 Combining aspects and normal code
Advising several classes is also possible: ajc Point.java Line.java MoveTracking.java Or: Result is ordinary Java class files.

85 AspectJ features Join Points Aspects method & cons calls & executions
field gets and sets exception handler executions intializations Aspects pertarget perthis percflow percflowbelow Pointcuts call execution handler get set initialization this target within withincode cflow cflowbelow Advice before after around

86 Exercise 8: Aspects and AspectJ
Again: You want to provide a Logging aspect for method invocations and for object creation for your applications. It should be possible to run the application with or without logging enabled. This time, use AspectJ to implement these requirements as separate entities. Discuss advantages and drawbacks of implementing aspects this way.

87 Sally – an object model for aspect languages
Join Points are declared by 4-tuple A pointcut is an interaction between two join points. Advices are special methods. joinpoint j1 {B, void, methodB, null} joinpoint j1 {B, void, methodB, null} joinpoint j2 {C, int, methodC, null} pointcut pc {j1, j2} public void beforePC() before pc { // insert code here }

88 Sally (II) Aspects are declared like classes, with additionally join point, pointcut and advice method declarations. Aspects can be abstract (with abstract join points) and can be extended by inheritance. aspect SomeAspect { joinpoint j1 {B, void, methodB, null} joinpoint j2 {C, int, methodC, null} pointcut pc {j1, j2} public void beforePC() before pc { // insert code here }

89 Exercise 9: Different Aspect Languages
Compare the way Sally and AspectJ implement aspects. What are the commonalities, the differences? Which approach do you like better? Which is more versatile? Can you think of other ways how aspects can be implemented? Consider Templates in C++, or Java‘s Dynamic Proxies

90 Jenerator: Aspects Jenerator also supports aspect.
In Jenerator, an aspect consists of introduce() jointPointClass() appliesTo() apply() package de.mathema.jenerator.paper; // imports… public class LogObjectCreationAspect extends Aspect { public Class joinPointClass() { return ClassInstantiation.class; } public void apply( CodeSnippet cs ) { ClassInstantiation inst = (ClassInstantiation)cs; CodeContainer container = inst.parent(); CMethod m = (CMethod)inst.parent( CMethod.class ); CClass c = (CClass)inst.parent( CClass.class ); String log = "System.out.println( //logmessage container.addChildBefore( new CCode( log ), cs );

91 AOP: Can it be used today?
The concept of separating out certain aspects into separate units is certainly worthwhile. Using patterns, or native language mechanisms to represent aspects works fine. AspectJ can be used in certain environments, however, for example debugging support is limited; it is not so simple to use it together with e.g. EJB.

92 Multidimensional Separation of Concerns (MDSOC) Problem revisited: Multidimensional Variability Example introduced: SEE Hyper/J concepts Example continued

93 MDSOC Basics Goals are somewhat similar to AOP, only a bit more general. Separation of concerns is an approach to decomposing software into modules, each of which deals with, and encapsulates, a particular area of interest, called a concern. Examples of concerns are functions, data types or classes, features (e.g., "persistence,„ "print," or "concurrency control"), variants, and roles. Object-oriented languages permit decomposition only by class. (Tyranny of the dominant decomposition).

94 Multi-Dimensional Variability
What, if an certain feature cannot be decomposed along this same dimension?

95 Exercise 10: Decomposition Tyranny
The Tyranny of the dominant decomposition states that a programming paradigm usually only allows one way, the dominant way, of decomposing a system. You have seen this for procedural and object-oriented languages. What are the dominant decompositions in other programming languages, and which techniques are available to break this tyranny?

96 MDSOC Basics (II) It is thus necessary, to This will:
decompose a system into as many concerns as necessary combine them as required ideally, to do this decomposition after the system has been developed. This will: reduce software complexity and improve comprehensibility. promote traceability within and across artifacts limit the impact of change, facilitating evolution and non-invasive adaptation and customization. facilitate reuse. simplify component integration.

97 IBM‘s Hyperspaces and Hyper/J
IBM uses the notion of hyperspaces for MDSOC. The research tool they use is Hyper/J. Hyper/J provides a powerful composition capability, to combine separated concerns selectively into an integrated program Hyper/J can be used at any stage of the software lifecycle: Design, Implementation, Integration, Evolution, Reengineering It uses standard Java and uses bytecode rewriting

98 Hyper/J Example: Simple Expression Editor
Tool to edit expressions of the form a = b + c * x It contains a set of tools that share a common representation of expressions, the AST. The set of tools should include the following: Evaluation tool: Determines the result Display tool: Depicts an expression program Check tool: Checks an expression program for syntactic and semantic correctness.

99 Hyper/J Example: Simple Expression Editor
Tools are implemented as operations on the AST classes. The following concerns can be identified: Classes/Objects Features

100 SEE: Manual Solution: Visitor Pattern
Implementing visitor requires design decision before implementation specific design and programming model

101 Exercise 11: Features and Visitor
Implement the different features „operating“ on the AST using the visitor pattern. Discuss advantages and especially the drawbacks of this solution. Assuming, Hyper/J solves these problems – what features would you like Hyper/J to have?

102 Hyper/J Example: Additional Requirements
It should be possible to have versions of the SEE that include subsets of the tools and capabilities. It should be possible to impose, optionally, checks for conformance to one or more programming styles. It should be possible to log, selectively, the execution of the SEE. Results in more concerns: configurations logging:

103 Hyper/J: Features to solve the problems
Multiple, arbitrary dimensions of concern. Separation along these dimensions simultaneously. No dominant dimension! The ability to handle new concerns, and new dimensions of concern, dynamically a posteriori. Overlapping and interacting concerns; usually they are not orthogonal

104 Hyper/J: Concepts A hyperspace is the problem space to be separated into concerns. Each dimension in that space is a concern. A unit is a program artifact, in Hyper/J only Java: packages, interfaces, classes and members. A concern mapping associates units (classes, interfaces, etc.) with a dimension and a concern. A hyperslice is set of concerns that is declaratively complete. I.e. it must declare everything to which they refer, it need not implement it! This requirement reduces coupling. artifact: dimension.concern

105 Hyper/J: Declarative completeness example
A hyperslice contains unit Plus.display(), which uses Plus.getOperand() defined in Kernel hyperslice To make the slice declaratively complete (i.e. compilable), it must supply its own version of Plus.getOperand(), however, it need not implement it (abstract declaration). Plus.display() then refers to this declaration Later on, the local declaration is mapped to a suitable implementation in another hyperslice.

106 Hyper/J: Concepts A hypermodule is a
set of hyperslices being integrated and a set of integration relationships, which specify how the hyperslices relate to one another. Hyper/J provides a compositor tool to specify concerns, hyperslices, hypermodules, etc. and to compose them.

107 Hyper/J: Example continued
The Java classes are implemented as usual (see class diagram) We now want to factor out the the Feature dimension and its concerns. First, we create a hyperspace specification file that specifies the complete space: hyperspace DemoHyperspace composable class demo.ObjectDimension.*;

108 Hyper/J: Example continued
Then, we have to define the concerns mapping. Here, operations are mapped to concerns. package demo.ObjectDimension : Feature.Kernel operation check : Feature.Check operation display : Feature.Display operation eval : Feature.Eval operation check_process : Feature.Check operation display_process : Feature.Display operation eval_process : Feature.Eval operation process : Feature.None

109 Hyper/J: Example continued
As a last step, we define the hypermodule specification file, which defines how the dimensions and concerns can be composed. hypermodule DemoSEE hyperslices: Feature.Kernel, Feature.Check, Feature.Display; Relationships: mergeByName; equate operation Feature.Kernel.process, Feature.Check.check_process, Feature.Display.display_process; end hypermodule;

110 Hyper/J: Example continued
We then have to run the compositor tool: And then, we can run the application. Simple, isn‘t it? By changing the hypermodule definition file, we can easily change the included concerns. java com.ibm.hyperj.hyperj -hyperspace %HYPERJ_DIR%/demo/ObjectDimension.hs -concerns %HYPERJ_DIR%/demo/ObjectDimension/concerns.cm -hypermodules %HYPERJ_DIR%/demo/CheckDisplay.hm -verbose

111 Hyper/J: Example, adding a new Feature
We want to add the StyleChecking Feature, after the system is finished! New package: Add this to the hyperspace configuration file: ... and the concern mapping: demo.StyleChecker hyperspace DemoHyperspace composable class demo.ObjectDimension.*; composable class demo.StyleChecker.*; package demo.StyleChecker : Feature.StyleChecker

112 Hyper/J: Example continued
The hypermodule configuration file: hypermodule DemoSEE hyperslices: Feature.Kernel, Feature.Check, Feature.Display, Feature.StyleChecker; relationships: mergeByName; equate operation Feature.Kernel.process, Feature.Check.check_process, Feature.Display.display_process; set summary function for action DemoSEE.BinaryOperator.check to action DemoSEE.Expression.summarizeCheck; end hypermodule;

113 Exercise 12: Hyper/J The source on the previous page contains the set summary function specification. What do you think is it good for?

114 MDOSC: Can it be used today?
Again, the concept is simple and can be used today. Hyper/J as an implementation has been around for a while and is quite stable. However, I would not recommend using it in industry projects, because it is not an established tool and approach.

115 Intentional Programming Background Basic Concepts IP System Architecture Active Source Stunning Features 

116 IP Background Intentional Programming (IP) has been a research project by Microsoft, lead by Charles Simonyi. It has since been transferred to the Visual Tools development division. As a consequence, it is very hard to obtain substantial information on the project. The best description I found is in Eisenecker and Czarnecki‘s book.

117 IP Basics IP is an extendible (meta)programming environment.
The environment and the language can be extended to contain (domain-specific) higher-level abstractions. Extension libraries are used to supply the exetensions. It allows extensions to the Language Compiler Debugger Editor Version control

118 IP System itself The IP system supports the extensibility by providing
a code transformation framework compilation support protocols debugging facilities that also allow the debugging of metacode and standard APIs for accessing the various parts of the system. Developers of extension libraries can make use of other extension libaries.

119 IP System Architectural Overview
Important components Editor & Browser Reduction Engine Debugger VCS Import Parsers Reduction engine ±Compiler No parser! Creates R-Code Reduction is applied repeatedly Backend and Linker creates machine code

120 IP System Architectural Overview
int x; x = 1; while ( x < 5 ) ++x; Reduction engine ±Compiler No parser! Creates R-Code Reduction is applied repeatedly Backend and Linkter creates machine code TEST: if ( x < 5 ) { ++x; goto TEST; } 0FAB12CF AFCD DF12

121 IP Core: Active Source Source is not represented as ASCII text, instead it is Active Source: Source elements are graph-structure, a kind of enhanced AST Each element has a reference to its declaration, which can be in an extension libary. methods operate on this tree, i.e. programming time behaviour can be specified

122 Active Source Example int x; x = 1; while ( x < 5 ) ++x;

123 Active Source at Programming-Time
The declarations of elements in an active source tree can point to definitions inside libraries. These „types“ can contain operations to render type-in reduce debug refactor They are called by the framework at appropriate times.

124 AST methods example: Type-In
The following shows support for typing in a simple expression:

125 More advanced support for type-in
The following shows support for handling matrices.

126 More advanced support for type-in (II)
The following shows support for handling general mathematical formulas.

127 More advanced support for type-in (III)
... electrical circuits

128 More advanced support for type-in (IV)
... or just some help in typing in normal code

129 More advanced support for type-in (V)
... or chinese

130 ? IP: Can it be used today? Yes, probably, but only by Microsoft 
Parts have probably gone into .NET

131 Thanks... to the aspectj team for letting me use some material from their tutorial Ulrich Eisenecker and Krzysztof Czarnecki for the permission to use some code examples and illustrations from their book „Generative Programming“ The Hyper/J team for allowing me to use some of their material Krzysztof Czarnecki for reviewing the slides and giving useful feedback Andreas Bohn for scanning illustrations.

132 Resources You will find information on many of the topics in this tutorial in the book Generative Programming by Ulrich Eisenecker and Krzysztof Czarnecki, Addison Wesley, 2000 Information on generative programming on the web can be found at and various conference workshop pages. Information on aspect orientation can be found at aosd.net and The former of the two contains a really good link collection.

133 Resources (II) Information about Multi-Dimensional Separation of Concerns can be found at Information on Intentional Programming is not available on the web anymore. Read E&C‘s book. In general, all of these topics are still (at least partly) subject to ongoing research – chances are that you will find information at conferences and associated workshops. Examples: OOPSLA, ECOOP, OT, ...

134 The end. Questions? Criticism? Opinions?
build software like they build cars!


Download ppt "Workshop: Moderne Softwareentwicklungs-Methoden Teil 1: AOP, MDSOC, GP, IP Teil 2: eXtreme Programming Markus Völter markus.voelter@mathema.de Michael."

Similar presentations


Ads by Google