A Formal Model of Modularity in Aspect-Oriented ProgrammingOutlineModularity and EncapsulationIs AOP Modular?Example: Assurance AspectSlide 6Slide 7Slide 8Slide 9Example: Broken Assurance AspectSlide 11Slide 12AnalysisFix #1: external adviceFix #2: semantic pointcutOpen ModulesSlide 17Slide 18Slide 19Slide 20Slide 21Open Module Properties: EquivalenceOpen Module Properties: AbstractionComparison to Aspect-Aware InterfacesTool and Language ImplicationsDiscussionEnd of Presentation/Extra SlidesTinyAspect ExampleTinyAspect: SyntaxEvaluationSlide 31TinyAspect: Values and ContextsTinyAspect: Reduction RulesTinyAspect: Expression TypingTinyAspect: Declaration TypingTinyAspect: PropertiesOpen Modules: SyntaxOpen Modules: ExampleOpen Modules: SemanticsSlide 40Reynolds’ Abstraction PropertyObservational EquivalenceFormal Abstraction TheoremA Formal Model of Modularityin Aspect-Oriented ProgrammingJonathan Aldrich15-819: Objects and AspectsCarnegie Mellon UniversityOutlineAOP Modularity ChallengesOpen ModulesA Bit of FormalityComparison to Aspect-Aware InterfacesLessons Learned and DiscussionModularity and EncapsulationParnas’ advice:Modularize a system to hide information that may changeEncapsulationA mechanism for enforcing information hidingJava classes & packages, ML modules…Aspect-oriented ProgrammingMore flexible ways of modularizing a systemIs AOP Modular?Back to Parnas: Does AOP hide information that is likely to change?Yes, within the aspectAspect code can be evolved separatelyNo, not within the base codeMinor changes to base code break the aspectExample: Assurance Aspectclass Point extends Shape { void moveBy(int dx, int dy) { x += dx; y += dy; ...}Example: Assurance Aspectclass Point extends Shape { void moveBy(int dx, int dy) { x += dx; y += dy; ...}class Rectangle extends Shape { void moveBy(int dx, int dy) { p1x += dx; p1y += dy; p2x += dx; p2y += dy; ...}Example: Assurance Aspectclass Point extends Shape { void moveBy(int dx, int dy) { x += dx; y += dy; ...}class Rectangle extends Shape { void moveBy(int dx, int dy) { p1x += dx; p1y += dy; p2x += dx; p2y += dy; ...}aspect AssureShapeInvariants { }Example: Assurance Aspectclass Point extends Shape { void moveBy(int dx, int dy) { x += dx; y += dy; ...}class Rectangle extends Shape { void moveBy(int dx, int dy) { p1x += dx; p1y += dy; p2x += dx; p2y += dy; ...}aspect AssureShapeInvariants { pointcut moves() = call(Shape+.moveBy(..)); }Example: Assurance Aspectclass Point extends Shape { void moveBy(int dx, int dy) { x += dx; y += dy; ...}class Rectangle extends Shape { void moveBy(int dx, int dy) { p1x += dx; p1y += dy; p2x += dx; p2y += dy; ...}aspect AssureShapeInvariants { pointcut moves() = call(Shape+.moveBy(..)); after(): moves() { scene.checkInvariants(); }}Example: Broken Assurance Aspectclass Point extends Shape { void moveBy(int dx, int dy) { x += dx; y += dy; ...}class Rectangle extends Shape { void moveBy(int dx, int dy) { p1x += dx; p1y += dy; p2x += dx; p2y += dy; ...}aspect AssureShapeInvariants { pointcut moves() = call(Shape+.moveBy(..)); after(): moves() { scene.checkInvariants(); }}Change representation to use PointExample: Broken Assurance Aspectclass Point extends Shape { void moveBy(int dx, int dy) { x += dx; y += dy; ...}class Rectangle extends Shape { void moveBy(int dx, int dy) { p1.moveBy(dx, dy); p2.moveBy(dx, dy); ...}aspect AssureShapeInvariants { pointcut moves() = call(Shape+.moveBy(..)); after(): moves() { scene.checkInvariants(); }}Change representation to use PointExample: Broken Assurance Aspectclass Point extends Shape { void moveBy(int dx, int dy) { x += dx; y += dy; ...}class Rectangle extends Shape { void moveBy(int dx, int dy) { p1.moveBy(dx, dy); p2.moveBy(dx, dy); ...}aspect AssureShapeInvariants { pointcut moves() = call(Shape+.moveBy(..)); after(): moves() { scene.checkInvariants(); }}Change representation to use PointNow the scene invariants are checked in the middle of a Rectangle move—when they might be broken!AnalysisAspects can violate information hidingAssurance aspect depends on Shape internalsSimilar to OO Fragile Base Class ProblemObserving impl. dependant calling patternsCan fix each individual problemBetter: use modules to forestall issueFix #1: external adviceclass Point extends Shape { void moveBy(int dx, int dy) { x += dx; y += dy; ...}class Rectangle extends Shape { void moveBy(int dx, int dy) { p1x += dx; p1y += dy; p2x += dx; p2y += dy; ...}aspect AssureShapeInvariants { pointcut moves(): call(Shape+.moveBy(..)) && !within(shape.*); after(): moves() { scene.checkInvariants(); }}Only specifies calls that are external to the shape packageFix #2: semantic pointcutclass Point extends Shape { void moveBy(int dx, int dy) { x += dx; y += dy; ...}class Rectangle extends Shape { void moveBy(int dx, int dy) { p1x += dx; p1y += dy; p2x += dx; p2y += dy; ...}class Shape { public pointcut moves(): call(Shape+.moveBy(..));}aspect AssureShapeInvariants { after(): Shape.moves() { scene.checkInvariants(); }}Move pointcut to the shape packageNow the shape maintainer is responsible for preserving its semantics when shapes evolveOpen Modulesvoid moveBy(int, int);void animate(Motion);Open ModuleOrdinary functional interfaceOpen Modulesvoid moveBy(int, int);void animate(Motion);pointcut moves;Open ModuleOrdinary functional interfaceSemantic Pointcut• Denotes some internal event• Promise to maintain event semantics as code evolves[Gudmunson & Kiczales]Open Modulesvoid moveBy(int, int);void animate(Motion);pointcut moves;Open ModuleClients can call interface functionsOpen Modulesvoid moveBy(int, int);void animate(Motion);pointcut moves;Open ModuleClients can call interface functionsClients can advise external calls to interface functionsOpen Modulesvoid moveBy(int, int);void animate(Motion);pointcut moves;Open ModuleClients can call interface functionsClients can advise external calls to interface functionsClients can advise pointcuts in interfaceOpen Modulesvoid moveBy(int, int);void animate(Motion);pointcut moves;Open ModuleClients can call interface functionsClients can advise external calls to interface functionsClients can advise pointcuts in interfaceClients cannot advise any internal calls (not even to exported
View Full Document