Overview Structure-shy Object pattern

Slides:



Advertisements
Similar presentations
Inheritance // A simple class hierarchy. // A class for two-dimensional objects. class TwoDShape { double width; double height; void showDim() { System.out.println("Width.
Advertisements

Exercise: Balanced Parentheses
INTERPRETER Main Topics What is an Interpreter. Why should we learn about them.
1 Data Structures - CSCI 102 CS102 C++ Polymorphism Prof Tejada.
Controlling the Complexity of Software Designs Karl Lieberherr College of Computer and Information Science Northeastern University.
Design Pattern Interpreter By Swathi Polusani. What is an Interpreter? The Interpreter pattern describes how to define a grammar for simple languages,
Controlling the Complexity of Software Designs Karl Lieberherr College of Computer and Information Science Northeastern University.
Take-Home Final COM 3205 Fall Stamp Coupling Def: data structure is passed as parameter, but called method operates on only some of the` individual.
Aspect Oriented Programming Gülşah KARADUMAN.
Data Design and Implementation. Definitions of Java TYPES Atomic or primitive type A data type whose elements are single, non-decomposable data items.
Not only mark-up languages! There are other many other grammar formalisms and tools than XML. Some of them standardized (ASN). Even XML does not always.
The following viewgraphs about RIDL from: D: A Framework for Distributed Programming Cristina Videira Lopes.
Cross cutting Cross-cutting of components and aspects ordinary program structure-shy functionality structure synchronization better program Components.
1 XAspects An Extensible System for Domain- Specific Aspect Languages Macneil Shonle (UCSD) Karl Lieberherr (Northeastern University) Ankit Shah (Northeastern.
1 Modularization of crosscutting concerns Write this public class Shape { protected double x_= 0.0, y_= 0.0; protected double width_=0.0, height_=0.0;
Controlling the Complexity of Software Designs Karl Lieberherr College of Computer and Information Science Northeastern University.
Controlling the Complexity of Software Designs Karl Lieberherr College of Computer and Information Science Northeastern University.
Controlling the Complexity of Software Designs Karl Lieberherr College of Computer and Information Science Northeastern University.
The Interpreter Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.
Lorenz: Visitor Beans: An Aspect-Oriented Pattern Aspect-oriented pattern: describes a solution to a tangling problem in a particular context.
XAspects slides Cross-cutting of concerns ordinary program structure-shy functionality structure synchronization better program Chapter 1 Chapter 2 Chapter.
AOP/cross-cutting What is an aspect?. An aspect is a modular unit that cross-cuts other modular units. What means cross-cutting? Apply AOP to AOP. Tease.
Features of AOP languages AOP languages have the following main elements: –a join point model (JPM) wrt base PL –a specification language for expressing.
Comp 411 Principles of Programming Languages Lecture 3 Parsing
Chapter 3 – Describing Syntax
Agenda Preliminaries Motivation and Research questions Exploring GLL
CS 3304 Comparative Languages
Parsing & Context-Free Grammars
Chapter 4 - Parsing CSCE 343.
Lexical and Syntax Analysis
Introduction to Parsing (adapted from CS 164 at Berkeley)
Syntax Analysis Chapter 4.
CS 404 Introduction to Compiler Design
Controlling the Complexity of Software Designs
4 (c) parsing.
Inheritance "Question: What is the object oriented way of getting rich? Answer: Inheritance.“ “Inheritance is new code that reuses old code. Polymorphism.
Presentation by Julie Betlach 7/02/2009
CS 3304 Comparative Languages
Parsing & Context-Free Grammars Hal Perkins Autumn 2011
Programming Language Syntax 7
Lexical and Syntax Analysis
(Slides copied liberally from Ruth Anderson, Hal Perkins and others)
Software Design and Development
Controlling the Complexity of Software Designs
ADAPTIVE PROGRAMMING Sezen ERDEM December 2005.
Northeastern University, CCIS/PRL
Review lecture AOO/Demeter.
LL(1) Parser Generators
Software Design and Development
Karl Lieberherr CCIS/PRL Northeastern University
Bottom Up Parsing.
R.Rajkumar Asst.Professor CSE
Third lecture Review Visitor pattern DemeterJ 12/25/2018 SD.
ASTs, Grammars, Parsing, Tree traversals
Compilers Principles, Techniques, & Tools Taught by Jing Zhang
Interpreter Pattern.
Sustainable Software Karl Lieberherr Northeastern University
SAMANVITHA RAMAYANAM 18TH FEBRUARY 2010 CPE 691
Third lecture Review Visitor pattern DemeterJ 2/17/2019 SD.
APPCs revisited 2/25/2019 APPCs revisited.
Syntax Analysis - 3 Chapter 4.
Software Development CSU 670 Karl Lieberherr
Declarative Techniques for Improving Aspect Orthogonality
The Recursive Descent Algorithm
Parsing & Context-Free Grammars Hal Perkins Summer 2004
Design Yaodong Bi.
College of Computer Science
Parsing & Context-Free Grammars Hal Perkins Autumn 2005
COP 4620 / 5625 Programming Language Translation / Compiler Writing Fall 2003 Lecture 2, 09/04/2003 Prof. Roy Levow.
Introduction to Computer Science and Object-Oriented Programming
Presentation transcript:

Overview Structure-shy Object pattern Better separation of concerns using Structure-shy Traversal and Selective Visitor Cover now more details 5/15/2019 AOO/Demeter

Structure-shy object pattern Parsing, class graphs etc. separation of concerns: sentences : robust representation objects : brittle representations grammars: rules for constructing brittle rep. from robust rep. XML, JSR 31 5/15/2019 AOO/Demeter

Parsing class graphs class dictionaries = class graphs + syntax legal objects printing function defines language defined by class dictionary ambiguous class dictionary: two distinct objects are mapped to same sentence 5/15/2019 AOO/Demeter

Class graphs construction, alternation nodes and edges textual and graphical common parts, flat class graphs optional parts and repetition parameterized classes 5/15/2019 AOO/Demeter

Exercise Derive a class graph for explaining concrete class structure and syntax. 5/15/2019 AOO/Demeter

Parsing Is a class dictionary ambiguous? If not ambiguous, can define inverse of printing function: called parsing Goal: Want a fast parser. Want to quickly recognize an unambiguous class dictionary. 5/15/2019 AOO/Demeter

Parsing Inherent problem: There is no algorithm to check for ambiguity. Shown by reduction: Could solve other undecidable problems. Invent condition which is stronger than non-ambiguity and which can be checked efficiently. Ok. to exclude some non-ambiguous grammars. LL(1) conditions. 5/15/2019 AOO/Demeter

Parsing LL(1) condition 1: Alternatives of abstract class must have pair-wise disjoint first sets. LL(1) condition 2: Deals with alternatives which may be empty. Requires follow sets. LL(1) conditions can be checked efficiently. Printing is a bijection between tree objects and sentences. 5/15/2019 AOO/Demeter

Commercial parsing tools Yacc and Lex JavaCC (Java compiler compiler) LL(k) support JJTree: define classes using a grammar and provides a universal visitor many more 5/15/2019 AOO/Demeter

Context switch: Separation of concerns An introduction to aspect-oriented programming 5/15/2019 AOO/Demeter

Better separation of concerns An old topic: Dijkstra 1976 Minimize tangling 5/15/2019 AOO/Demeter

Two types of concerns Generic concerns Behaviors structure coordination remote invocation exception handling efficiency interoperability migration Behaviors sum check print translate Pricing FrequentCustomerPricing 5/15/2019 AOO/Demeter

public class Shape implements ShapeI { interface ShapeI extends Remote { double get_x() throws RemoteException ; void set_x(int x) throws RemoteException ; double get_y() throws RemoteException ; void set_y(int y) throws RemoteException ; double get_width() throws RemoteException ; void set_width(int w) throws RemoteException ; double get_height() throws RemoteException ; void set_height(int h) throws RemoteException ; void adjustLocation() throws RemoteException ; void adjustDimensions() throws RemoteException ; } public class Shape implements ShapeI { protected AdjustableLocation loc; protected AdjustableDimension dim; public Shape() { loc = new AdjustableLocation(0, 0); dim = new AdjustableDimension(0, 0); } double get_x() throws RemoteException { return loc.x(); } void set_x(int x) throws RemoteException { loc.set_x(); } double get_y() throws RemoteException { return loc.y(); } void set_y(int y) throws RemoteException { loc.set_y(); } double get_width() throws RemoteException { return dim.width(); } void set_width(int w) throws RemoteException { dim.set_w(); } double get_height() throws RemoteException { return dim.height(); } void set_height(int h) throws RemoteException { dim.set_h(); } void adjustLocation() throws RemoteException { loc.adjust(); void adjustDimensions() throws RemoteException { dim.adjust(); class AdjustableLocation { protected double x_, y_; public AdjustableLocation(double x, double y) { x_ = x; y_ = y; } synchronized double get_x() { return x_; } synchronized void set_x(int x) {x_ = x;} synchronized double get_y() { return y_; } synchronized void set_y(int y) {y_ = y;} synchronized void adjust() { x_ = longCalculation1(); y_ = longCalculation2(); class AdjustableDimension { protected double width_=0.0, height_=0.0; public AdjustableDimension(double h, double w) { height_ = h; width_ = w; synchronized double get_width() { return width_; } synchronized void set_w(int w) {width_ = w;} synchronized double get_height() { return height_; } synchronized void set_h(int h) {height_ = h;} width_ = longCalculation3(); height_ = longCalculation4(); 5/15/2019 AOO/Demeter

thread synchronization remote interaction interface ShapeI extends Remote { double get_x() throws RemoteException ; void set_x(int x) throws RemoteException ; double get_y() throws RemoteException ; void set_y(int y) throws RemoteException ; double get_width() throws RemoteException ; void set_width(int w) throws RemoteException ; double get_height() throws RemoteException ; void set_height(int h) throws RemoteException ; void adjustLocation() throws RemoteException ; void adjustDimensions() throws RemoteException ; } remote interaction public class Shape implements ShapeI { protected AdjustableLocation loc; protected AdjustableDimension dim; public Shape() { loc = new AdjustableLocation(0, 0); dim = new AdjustableDimension(0, 0); } double get_x() throws RemoteException { return loc.x(); } void set_x(int x) throws RemoteException { loc.set_x(); } double get_y() throws RemoteException { return loc.y(); } void set_y(int y) throws RemoteException { loc.set_y(); } double get_width() throws RemoteException { return dim.width(); } void set_width(int w) throws RemoteException { dim.set_w(); } double get_height() throws RemoteException { return dim.height(); } void set_height(int h) throws RemoteException { dim.set_h(); } void adjustLocation() throws RemoteException { loc.adjust(); void adjustDimensions() throws RemoteException { dim.adjust(); class AdjustableLocation { protected double x_, y_; public AdjustableLocation(double x, double y) { x_ = x; y_ = y; } synchronized double get_x() { return x_; } synchronized void set_x(int x) {x_ = x;} synchronized double get_y() { return y_; } synchronized void set_y(int y) {y_ = y;} synchronized void adjust() { x_ = longCalculation1(); y_ = longCalculation2(); class AdjustableDimension { protected double width_=0.0, height_=0.0; public AdjustableDimension(double h, double w) { height_ = h; width_ = w; synchronized double get_width() { return width_; } synchronized void set_w(int w) {width_ = w;} synchronized double get_height() { return height_; } synchronized void set_h(int h) {height_ = h;} width_ = longCalculation3(); height_ = longCalculation4(); tell what the colors mean make it grey first lots of redundancy 5/15/2019 AOO/Demeter

The source of tangling Alignment with classes would be nice, but... 5/15/2019 AOO/Demeter

The source of tangling ...issues cross-cut classes 5/15/2019 Cut this psrt? ...issues cross-cut classes 5/15/2019 AOO/Demeter

D Write this Instead of writing this 5/15/2019 AOO/Demeter public class Shape implements ShapeI { protected AdjustableLocation loc; protected AdjustableDimension dim; public Shape() { loc = new AdjustableLocation(0, 0); dim = new AdjustableDimension(0, 0); } double get_x() throws RemoteException { return loc.x(); } void set_x(int x) throws RemoteException { loc.set_x(); } double get_y() throws RemoteException { return loc.y(); } void set_y(int y) throws RemoteException { loc.set_y(); } double get_width() throws RemoteException { return dim.width(); } void set_width(int w) throws RemoteException { dim.set_w(); } double get_height() throws RemoteException { return dim.height(); } void set_height(int h) throws RemoteException { dim.set_h(); } void adjustLocation() throws RemoteException { loc.adjust(); void adjustDimensions() throws RemoteException { dim.adjust(); class AdjustableLocation { protected double x_, y_; public AdjustableLocation(double x, double y) { x_ = x; y_ = y; synchronized double get_x() { return x_; } synchronized void set_x(int x) {x_ = x;} synchronized double get_y() { return y_; } synchronized void set_y(int y) {y_ = y;} synchronized void adjust() { x_ = longCalculation1(); y_ = longCalculation2(); class AdjustableDimension { protected double width_=0.0, height_=0.0; public AdjustableDimension(double h, double w) { height_ = h; width_ = w; synchronized double get_width() { return width_; } synchronized void set_w(int w) {width_ = w;} synchronized double get_height() { return height_; } synchronized void set_h(int h) {height_ = h;} width_ = longCalculation3(); height_ = longCalculation4(); interface ShapeI extends Remote { double get_x() throws RemoteException ; void set_x(int x) throws RemoteException ; double get_y() throws RemoteException ; void set_y(int y) throws RemoteException ; double get_width() throws RemoteException ; void set_width(int w) throws RemoteException ; double get_height() throws RemoteException ; void set_height(int h) throws RemoteException ; void adjustLocation() throws RemoteException ; void adjustDimensions() throws RemoteException ; D public class Shape { protected double x_= 0.0, y_= 0.0; protected double width_=0.0, height_=0.0; double get_x() { return x_(); } void set_x(int x) { x_ = x; } double get_y() { return y_(); } void set_y(int y) { y_ = y; } double get_width(){ return width_(); } void set_width(int w) { width_ = w; } double get_height(){ return height_(); } void set_height(int h) { height_ = h; } void adjustLocation() { x_ = longCalculation1(); y_ = longCalculation2(); } void adjustDimensions() { width_ = longCalculation3(); height_ = longCalculation4(); coordinator Shape { selfex adjustLocation, adjustDimensions; mutex {adjustLocation, get_x, set_x, get_y, set_y}; mutex {adjustDimensions, get_width, get_height, set_width, set_height}; portal Shape { double get_x() {} ; void set_x(int x) {}; double get_y() {}; void set_y(int y) {}; double get_width() {}; void set_width(int w) {}; double get_height() {}; void set_height(int h) {}; void adjustLocation() {}; void adjustDimensions() {}; Write this Instead of writing this 5/15/2019 AOO/Demeter

Code tangling is bad Harms program structure Distracts from main functionality Hard to program, error-prone Code difficult to understand, maintain 5/15/2019 AOO/Demeter

Ways to decrease the tangling Style guidelines Design patterns Better programming languages 5/15/2019 AOO/Demeter

Tangling of traversal/visitor calls class A void t(V v){ v.before_b(this); b.t(v); v.after_b(this);} class B v.before_c(this); c.t(v); v.after_c(this); } visitor class V before_b(A host) { … } after_b(A host) { …} ... class graph A = B. B = C. C = D. D = . 5/15/2019 AOO/Demeter

Tangling of behaviors V and W traversal + visitor calls class A: void f() {t(new V(), new W());} void t(V v,W w){ v.before_b(this); w.before_b(this); b.t(v,w); w.after_b(this); v.after_b(this);} class graph A = B. B = C. C = D. D = . class B: void t(V v,W w){ v.before_c(this); w.before_c(this); c.t(v,w); w.after_c(this); v.after_c(this); } visitor class V visitor class W At design level: class A:void f() to D (V,W) 5/15/2019 AOO/Demeter

AOP => control of tangling DemeterJ controls the following tangling problems structure/behavior, navigation/behavior, behavior/behavior, object construction/structure, synchronization/behavior, remote invocation/behavior. 5/15/2019 AOO/Demeter

Context switch 5/15/2019 AOO/Demeter

Developing an adaptive program each simple behavior is translated into a visitor; localizes concerns; visitors are self-contained compose visitors, order visitors use top-down approach for writing program: first write method using visitors before visitors are implemented 5/15/2019 AOO/Demeter

Container capacity problem recursive containers each contains items and has capacity each item has a weight find all containers above capacity leave details of containers vague 5/15/2019 AOO/Demeter

Container capacity problem need to sum: use SummingVisitor need to check: use CheckingVisitor want to do it in one traversal: need to store sum when container is entered to compute difference after the container: DifferenceVisitor 5/15/2019 AOO/Demeter

Event based view of traversals and visitors Summing before Weight Difference before Container after Container Checking after Container Summary of code Summary of data flow s d v Summary of event flow before Weight before Container before Container after Container after Container after Container Event based view of traversals and visitors 5/15/2019 AOO/Demeter

Event based view of traversals and visitors Summing before Weight return s Difference before Container after Container return d Checking after Container return v Summary of code Summary of data flow s d v Summary of event flow before Weight before Container before Container after Container after Container after Container Event based view of traversals and visitors 5/15/2019 AOO/Demeter

Visitor classes as components return visitor class strategy s class graph Difference Checking Summing return return total diff sum what? get_value check what? get_capacity 5/15/2019 AOO

Which Conceptual View? Most basic innermost Checking uses Difference Difference uses Summing CheckingVisitor after Container Traversal DifferenceVisitor before Container after Container node and edge events SummingVisitor before Weight 5/15/2019 AOO/Demeter

Which Conceptual View? Most basic outermost: filter Checking uses Difference Difference uses Summing SummingVisitor before Weight Traversal DifferenceVisitor before Container after Container node and edge events CheckingVisitor after Container 5/15/2019 AOO/Demeter

Traversals are iterative from Container to Weight: total = total + host.get_i(); some recursive computations need extra attention using difference visitors 5/15/2019 AOO/Demeter

Container capacity problem SummingVisitor data member total, initialize to 0 add at Weight 5/15/2019 AOO/Demeter

Container capacity problem CheckingVisitor data member: violations after each container, check whether difference of sum at the end and the beginning of a container (supplied by DifferenceVisitor) is larger than capacity uses DifferenceVisitor return violations 5/15/2019 AOO/Demeter

Container capacity problem DifferenceVisitor store sum at beginning (SummingVisitor) of container return difference between sum at beginning of container and current sum upon request uses SummingVisitor twice per container 5/15/2019 AOO/Demeter

Container capacity problem Preliminary visitor class graph! Visitor order: after container, both DifferenceVisitor and CheckingVisitor are active. DifferenceVisitor must be after CheckingVisitor (because after methods are in reverse order) CheckingVisitor = <dV> DifferenceVisitor. DifferenceVisitor = <sV> SummingVisitor. 5/15/2019 AOO/Demeter

Container capacity problem DemeterJ Container capacity problem traversal allWeights(CheckingVisitor cV, DifferenceVisitor dV, SummingVisitor sV) {to Weight;} int checkCapacity() {{ CheckingVisitor cV = new CheckingVisitor(); DifferenceVisitor dV = new DifferenceVisitor(); SummingVisitor sV = new SummingVisitor(); cV.set_dV(dV); dV.set_sV(sV); //link behaviors this.allWeights(cV, dV, sV); // call traversal with visitors return (cV.get_return_val()); }} cannot avoid all tangling, but can localize it. No longer spread over several classes. 5/15/2019 AOO/Demeter

Container capacity problem DJ Container capacity problem int checkCapacity(TraversalGraph whereToGo) { CheckingVisitor cV = new CheckingVisitor(); DifferenceVisitor dV = new DifferenceVisitor(); SummingVisitor sV = new SummingVisitor(); cV.set_dV(dV); dV.set_sV(sV); //link behaviors Integer res = (Integer) whereToGo.traverse(this, new Visitor[]{cV, dV,sV}); return res.intValue(); } cannot avoid all tangling, but can localize it. No longer spread over several classes. 5/15/2019 AOO/Demeter

Container capacity problem Refined visitor class graph CheckingVisitor = <dV> DifferenceVisitor <violations> int. DifferenceVisitor = <sV> SummingVisitor <difference> int <stack> Stack. // from java.util.*; SummingVisitor = <total> int. 5/15/2019 AOO/Demeter

CheckingVisitor init {{ violations = 0; }} DemeterJ CheckingVisitor init {{ violations = 0; }} after Container {{ diff = // use dV cap = host.get_capacity() if (diff > cap) violations = violations + 1; }} return int {{ violations }} need to give return type since DemeterJ does not analyze code between {{ and }} 5/15/2019 AOO/Demeter

CheckingVisitor void start() {violations = 0; } DJ CheckingVisitor void start() {violations = 0; } void after(Container host) { diff = // use dV cap = host.get_capacity() if (diff > cap) violations = violations + 1; } Object getReturnValue() {return new Integer(violations);} 5/15/2019 AOO/Demeter

DifferenceVisitor init {{ stack = new Stack(); }} DemeterJ DifferenceVisitor init {{ stack = new Stack(); }} before Container {{ stack.push(… sV.get_total() …); }} after Container {{ difference = sV.get_return_val() - … (Integer) stack.pop() …; }} return int {{ difference }} 5/15/2019 AOO/Demeter

DifferenceVisitor void start() { stack = new Stack(); } DJ DifferenceVisitor void start() { stack = new Stack(); } void before(Container host){ stack.push( sV.getReturnValue()); } void after(Container host) { diff = ((Integer) sV.getReturnValue()).intValue() - ((Integer) stack.pop()).intValue(); } Object getReturnValue() {return new Integer(diff);} 5/15/2019 AOO/Demeter

SummingVisitor init {{ total = 0; }} before Weight DemeterJ SummingVisitor init {{ total = 0; }} before Weight {{ total = total + host.get_i(); }} return int {{ total }} 5/15/2019 AOO/Demeter

SummingVisitor SummingVisitor { {{ void start() { total = 0; } DJ SummingVisitor SummingVisitor { {{ void start() { total = 0; } void before(Weight host) { total = total + host.get_i(); } Object getReturnValue() {return new Integer(total);} }} } 5/15/2019 AOO/Demeter

Adaptiveness program we developed can be used with many different class graphs which satisfy a small set of constraints: Container must contain Weight Weight must have data member i of type int Container must have data member capacity 2 examples 5/15/2019 AOO/Demeter

Class graphs Container = <contents> List(Item) <capacity> Capacity. Item : Container | Simple. List(S) ~ {S}. Simple = <name> Ident <w> Weight. Capacity = <i> int. Weight = <i> int. alternative: move <w> Weight to Item 5/15/2019 AOO/Demeter

Class graphs Container : Container1 | Container2 common <contents> List(Item) <capacity> Capacity. Container1 = <packaging1> Simple. Container2 = <packaging2> Simple. Item : Container | Simple common <w> Weight. List(S) ~ {S}. Simple = <name> Ident. Capacity = <i> int. Weight = <i> int. 5/15/2019 AOO/Demeter