Aspect-Oriented Programming with C++ and Aspectc++

Aspect-Oriented Programming with C++ and Aspectc++

Aspect-Oriented Programming with C++ and AspectC++ AOSD 2007 Tutorial University of Erlangen-Nuremberg Computer Science 4 Presenters ➢ Daniel Lohmann [email protected] – University of Erlangen-Nuremberg, Germany ➢ Olaf Spinczyk [email protected] – University of Erlangen-Nuremberg, Germany Introduction © 2007 Daniel Lohmann and Olaf Spinczyk I/2 Schedule Part Title Time I Introduction 10m II AOP with pure C++ 40m III AOP with AspectC++ 70m IV Tool support for AspectC++ 30m V Real-World Examples 20m VI Summary and Discussion 10m Introduction © 2007 Daniel Lohmann and Olaf Spinczyk I/3 This Tutorial is about ... ➢ Writing aspect-oriented code with pure C++ – basic implementation techniques using C++ idioms – limitations of the pure C++ approach ➢ Programming with AspectC++ – language concepts, implementation, tool support – this is an AspectC++ tutorial ➢ Programming languages and concepts – no coverage of other AOSD topics like analysis or design Introduction © 2007 Daniel Lohmann and Olaf Spinczyk I/4 Aspect-Oriented Programming ➢ AOP is about modularizing crosscutting concerns well modularized concern aspect badly modularized without AOP with AOP ➢ Examples: tracing, synchronization, security, buffering, error handling, constraint checks, ... Introduction © 2007 Daniel Lohmann and Olaf Spinczyk I/5 Why AOP with C++? ➢ Widely accepted benefits from using AOP avoidance of code redundancy, better reusability, maintainability, configurability, the code better reflects the design, ... ➢ Enormous existing C++ code base maintainance: extensions are often crosscutting ➢ Millions of programmers use C++ for many domains C++ is the adequate language they want to benefit from AOP (as Java programmers do) ➢ How can the AOP community help? Part II: describe how to apply AOP with built-in mechanisms Part III-V: provide special language mechanisms for AOP Introduction © 2007 Daniel Lohmann and Olaf Spinczyk I/6 Scenario: A Queue utility class Introduction © 2007 Daniel Lohmann and Olaf Spinczyk I/7 The Simple Queue Class namespace util { Item* dequeue() { class Item { printf(" > Queue::dequeue()\n"); friend class Queue; Item* res = first; Item* next; if( first == last ) public: first = last = 0; Item() : next(0){} else }; first = first->next; printf(" < Queue::dequeue()\n"); class Queue { return res; Item* first; } Item* last; }; // class Queue public: } // namespace util Queue() : first(0), last(0) {} void enqueue( Item* item ) { printf( " > Queue::enqueue()\n" ); if( last ) { last->next = item; last = item; } else last = first = item; printf( " < Queue::enqueue()\n" ); } Introduction © 2007 Daniel Lohmann and Olaf Spinczyk I/8 Scenario: The Problem Various users of Queue demand extensions: Please extend the Queue class by an element counter! I want Queue to throw exceptions! Queue should be thread-safe! Introduction © 2007 Daniel Lohmann and Olaf Spinczyk I/9 The Not So Simple Queue Class class Queue { Item* dequeue() { Item *first, *last; Item* res; int counter; lock.enter(); os::Mutex lock; try { public: res = first; Queue () : first(0), last(0) { if (first == last) counter = 0; first = last = 0; } else first = first->next; void enqueue(Item* item) { if (counter > 0) –counter; lock.enter(); if (res == 0) try { throw QueueEmptyError(); if (item == 0) } catch (...) { throw QueueInvalidItemError(); lock.leave(); if (last) { throw; last->next = item; } last = item; lock.leave(); } else { last = first = item; } return res; ++counter; } } catch (...) { int count() { return counter; } lock.leave(); throw; }; // class Queue } lock.leave(); } Introduction © 2007 Daniel Lohmann and Olaf Spinczyk I/10 What Code Does What? class Queue { Item* dequeue() { Item *first, *last; Item* res; int counter; lock.enter(); os::Mutex lock; try { public: res = first; Queue () : first(0), last(0) { if (first == last) counter = 0; first = last = 0; } else first = first->next; void enqueue(Item* item) { if (counter > 0) –counter; lock.enter(); if (res == 0) try { throw QueueEmptyError(); if (item == 0) } catch (...) { throw QueueInvalidItemError(); lock.leave(); if (last) { throw; last->next = item; } last = item; lock.leave(); } else { last = first = item; } return res; ++counter; } } catch (...) { int count() { return counter; } lock.leave(); throw; }; // class Queue } lock.leave(); } Introduction © 2007 Daniel Lohmann and Olaf Spinczyk I/11 Problem Summary The component code is “polluted” with code for several logically independent concerns, thus it is ... ➢ hard to write the code – many different things have to be considered simultaneously ➢ hard to read the code – many things are going on at the same time ➢ hard to maintain and evolve the code – the implementation of concerns such as locking is scattered over the entire source base (a “crosscutting concern”) ➢ hard to configure at compile time – the users get a “one fits all” queue class Introduction © 2007 Daniel Lohmann and Olaf Spinczyk I/12 Aspect-Oriented Programming with C++ and AspectC++ AOSD 2007 Tutorial Part III – Aspect C++ Introduction © 2007 Daniel Lohmann and Olaf Spinczyk I/13 The Simple Queue Class Revisited namespace util { Item* dequeue() { class Item { printf(" > Queue::dequeue()\n"); friend class Queue; Item* res = first; Item* next; if( first == last ) public: first = last = 0; Item() : next(0){} else }; first = first->next; printf(" < Queue::dequeue()\n"); class Queue { return res; Item* first; } Item* last; }; // class Queue public: Queue() : first(0), last(0) {} } // namespace util void enqueue( Item* item ) { printf( " > Queue::enqueue()\n" ); if( last ) { last->next = item; last = item; } else last = first = item; printf( " < Queue::enqueue()\n" ); Intr } oduction I/14 © 2007 Daniel Lohmann and Olaf Spinczyk Queue: Demanded Extensions I. Element counting Please extend the Queue class by an element counter! II. Errorhandling (signaling of errors by exceptions) III. Thread safety (synchronization by mutex variables) Introduction © 2007 Daniel Lohmann and Olaf Spinczyk I/15 Element counting: The Idea ➢ Increment a counter variable after each execution of util::Queue::enqueue() ➢ Decrement it after each execution of util::Queue::dequeue() Introduction © 2007 Daniel Lohmann and Olaf Spinczyk I/16 ElementCounter1 aspect ElementCounter { int counter; ElementCounter() { counter = 0; } advice execution("% util::Queue::enqueue(...)") : after() { ++counter; printf( " Aspect ElementCounter: # of elements = %d\n", counter ); } advice execution("% util::Queue::dequeue(...)") : after() { if( counter > 0 ) --counter; printf( " Aspect ElementCounter: # of elements = %d\n", counter ); } }; ElementCounter1.ah Introduction © 2007 Daniel Lohmann and Olaf Spinczyk I/17 ElementCounter1 - Elements aspect ElementCounter { We introduced a new aspect named int counter; ElementCounter. ElementCounter() { counter = 0; An aspect starts with the keyword aspect } and is syntactically much like a class. advice execution("% util::Queue::enqueue(...)") : after() { ++counter; printf( " Aspect ElementCounter: # of elements = %d\n", counter ); } advice execution("% util::Queue::dequeue(...)") : after() { if( counter > 0 ) --counter; printf( " Aspect ElementCounter: # of elements = %d\n", counter ); } }; ElementCounter1.ah Introduction © 2007 Daniel Lohmann and Olaf Spinczyk I/18 ElementCounter1 - Elements aspect ElementCounter { Like a class, an aspect int counter; can define data members, ElementCounter() { constructors and so on counter = 0; } advice execution("% util::Queue::enqueue(...)") : after() { ++counter; printf( " Aspect ElementCounter: # of elements = %d\n", counter ); } advice execution("% util::Queue::dequeue(...)") : after() { if( counter > 0 ) --counter; printf( " Aspect ElementCounter: # of elements = %d\n", counter ); } }; ElementCounter1.ah Introduction © 2007 Daniel Lohmann and Olaf Spinczyk I/19 ElementCounter1 - Elements aspect ElementCounter { We give after advice (= some int counter; crosscuting code to be executed ElementCounter() { after certain control flow positions) counter = 0; } advice execution("% util::Queue::enqueue(...)") : after() { ++counter; printf( " Aspect ElementCounter: # of elements = %d\n", counter ); } advice execution("% util::Queue::dequeue(...)") : after() { if( counter > 0 ) --counter; printf( " Aspect ElementCounter: # of elements = %d\n", counter ); } }; ElementCounter1.ah Introduction © 2007 Daniel Lohmann and Olaf Spinczyk I/20 ElementCounter1 - Elements This pointcut expression denotes where the advice should be given. aspect ElementCounter { (After execution of methods that match int counter; the pattern) ElementCounter() { counter = 0; } advice execution("% util::Queue::enqueue(...)") : after() { ++counter; printf( " Aspect ElementCounter: # of elements = %d\n", counter ); } advice execution("% util::Queue::dequeue(...)") : after() { if( counter > 0 ) --counter; printf( " Aspect ElementCounter: # of elements = %d\n", counter ); } }; ElementCounter1.ah Introduction © 2007 Daniel Lohmann and Olaf Spinczyk I/21 ElementCounter1 - Elements aspect ElementCounter { int counter; Aspect member elements can be ElementCounter() { accessed from within the advice body counter = 0; } advice execution("% util::Queue::enqueue(...)") : after() { ++counter; printf( " Aspect ElementCounter: # of elements = %d\n", counter ); } advice execution("% util::Queue::dequeue(...)") : after() { if( counter > 0 ) --counter; printf( " Aspect ElementCounter: # of elements = %d\n", counter ); } }; ElementCounter1.ah Introduction © 2007 Daniel Lohmann and Olaf Spinczyk I/22 ElementCounter1 -

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    78 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us