670 likes | 830 Views
Adaptive Plug and Play Components for. Evolutionary Software Development. Mira Mezini University of Siegen mira@informatik.uni-siegen.de. Karl Lieberherr Northeastern University lieber@ccs.neu.edu. IBM connections for ingredients to adaptive plug-and-play components (APPCs).
E N D
Adaptive Plug and Play Components for Evolutionary Software Development Mira Mezini University of Siegen mira@informatik.uni-siegen.de Karl Lieberherr Northeastern University lieber@ccs.neu.edu
IBM connections for ingredients to adaptive plug-and-play components (APPCs) • Adaptive Programming developed with support from IBM: Cun Xiao, Ignacio Silva-Lepe both working for IBM • Contracts, another ingredient to APPCs, developed with support from IBM: Ian Holland also working for IBM
IBM San Francisco Project http://www.ibm.com/Java/Sanfrancisco Commands (similar to the Command pattern in the Design Patterns book) are objects with the sole purpose to provide a separate location for a specific piece of business logic processing. APPCs are similar to Commands
IBM San Francisco Project Benefits of Commands The implementation of business logic affecting several distinct business objects through Commands clearly brings advantages to maintenance and also allows application designers to isolate activities. By encapsulating the business logic in a Command object, client programs are isolated from changes in that piece of logic. It then becomes much easier to replace, modify, or enhance a certain piece of logic without impacting its users. This approach increases the flexibility of the framework. Benefits of Commands are also benefits of APPCs. APPCs are even better than commands.
self-service Z customer service teller service center What's the problem? OOAD Collab-1 C1 C4 C2 C3 C5 Collab-4 Collab-2 Collab-3 C1 C4 C2 C3 Implementation C5
What's the problem? • why do we need language constructs that capture collaborations? • unit of reuse is generally not a class, but a slice of behavior affecting • several classes • this is the core of application frameworks but: • “because frameworks are described with programming languages, it is • hard for developers to learn the collaborative patterns of a framework • by reading it … it might be better to improve oo languages so that they • can express patterns of collaboration more clearly” • [R. Johnson, CACM, Sep. ‘97]
What's the problem? • single methods often make sense in a larger context • “oo technology can be a burden to the maintainer because • functionality is often spread over several methods which must all • be traced to get the "big picture".” • [Wilde at al., IEEE Software, Jan ‘93] • “object-oriented technology has not met its expectations when applied • to real business applications and argues that this is partly due to the • fact that there is no natural place where to put higher-level operations • (such as business processes) which affect several objects. … • if built into the classes involved, it is impossible to get • an overview of the control flow. It is like reading a road map • through a soda straw'’ • [Lauesen, IEEE Software, April ‘98]
Adaptive? one generic collaboration P2 P3 P1 reused APPL 1 C1 C1 APPL C2 C4 n C2 C3 C3 C4 C5 with a family of concrete applications
Adaptive? one generic collaboration P2 P3 P1 reused with different mappings of participants to classes APPL 1 C1 APPL C1 1 C4 C4 C5 C5 C2 C3 C2 C3 of the same concrete application
Adaptive? • Requirements on the design: • Generic specification of the collaboration with respect to the class • structure it will be applied to. This serves two • purposes: (a) allow the same component to be used with several different • concrete applications, and (b) allow a collaborative component • to be mapped in different ways, i.e., with different class-to-participant • mappings, into the same class structure. • Loose coupling of behavior to structure to make collaborative components robust under changing class structures and thus better support • maintenance.
But, why adaptive? Well, let me explain by an example ... • from the domain of order entry systems • originated from an application system generator developed at IBM (‘70) called • Hardgoods Distributors Management Accounting System • goal: encode a generic design for order entry systems which could be • subsequently customized to produce an application meeting a customer’s • specific needs • customer’s specific requirements recorded in a questionnaire • the installation guide described the options and the consequences associated • with questions on the questionnaire consider the pricing component ...
But, why adaptive? Well, let me explain by an example ... PriceServerParty LineItemParty float basicPrice(ItemParty item) Integer discount(ItemParty item, Integer qty, Customer cust) quantity ItemParty Float additionalCharges(Float unitPrice Integer: qty) Customer ChargerParty ChargerParty Float cost(Integer qty, Float unitPrice, ItemParty item) pricing component: class diagram
But, why adaptive? Well, let me explain by an example ... price() { basicPr = pricer.basicPrice(item); discount = pricer.discount(item, qty, cust); unitPr = basicPr - (discount * basicPr); quotePr = uniPr + item.additionalCharges(unitPr, qty); return quotePr;} price() 1: basicPrice (item) 2: discount(item, qty,cust) lineItem: LineItemParty pricer: PriceServerParty 3: additionalCharges(unitPr, qty) additionalCharges(…){ Integer total; forall ch in charges{ total = total + ch.cost(…)} return total} item: ItemParty 3.2: cost(qty,unitPr,item) 3.1: ch=next() ChargerParty ChargerParty ch: ChargerParty pricing component: collaboration diagram
But, why adaptive? Well, let me explain by an example ... • design is fairly simple • complexity is a problem with this application generator’s component, though: • the complexity results from numerous, and arbitrary, pricing schemes in • use by industry and by the representation of these schemes in the system. The • price depends on: • the type of the customer (government, educational, regular, cash, etc.), • the time of the year (high/low demand season), • whether cost-plus or discounting applies • whether prior price-negotiated prices involved, • extra charges for the items such as taxes, deposits or surcharges • … etc.
But, why adaptive? Well, let me explain by an example ... • let us generate different pricing schemes out of the generic pricing component • specified by the pricing APPC … • Scheme 1: Regular Pricing • products have a base price which can be discounted depending on the • number of the units ordered • Scheme 2: Negotiated Pricing: • a customer may negotiate certain prices and discounts for particular items
refinement Plug and Play? 1. decoupled white-box composition - incrementally refine whole collaborations similar to individual classes base collaboration
base collaboration refinement Plug and Play? 1. decoupled white-box composition - reuse refinements with different bases
refinement refinement refinement Plug and Play? 1. decoupled white-box composition - combine several refinements of the same base base collaboration
Why decoupled white-box composition? e.g. AgingPricing could have different pricing refinements price() { basicPr = pricer.basicPrice(item); discount = pricer.discount(item, qty, cust); unitPr = basicPr - (discount * basicPr); quotePr = uniPr + item.additionalCharges(unitPr, qty); return quotePr;} if (item.stockTime() > item.stockTimeLimit() {quotePr := quotePr - quotePr * 0.1;} price() 1: basicPrice (item) 2: discount(item, qty,cust) lineItem: LineItemParty pricer: PriceServerParty 4. stockTime 3: additionalCharges(unitPr, qty) 5. stockTimeLimit item: ItemParty 3.1: ch=next() 3.2: cost(qty,unitPr,item) ChargerParty ChargerParty ch: ChargerParty
Why decoupled white-box composition? e.g. FrequentCustomerPricing could have different pricing refinements price() { basicPr = pricer.basicPrice(item); . . . return quotePr;} if (customer.frequent()) { hist = customer.get History(); freqRed = item.freqReduction(hist); quotePr = quotePr * freqRed} 1: basicPrice (item) 2: discount(item, qty,cust) price() lineItem: LineItemParty pricer: PriceServerParty 4. history() 5. freqReduction() 3: additional Charges(unitPr, qty) item: ItemParty 3.1: ch=next() 3.2: cost(qty,unitPr,item) customer: Customer ChargerParty ChargerParty ch: ChargerParty
Why decoupled white-box composition? could have different pricing refinements or combinations of the latter Pricing FrequentCustomer Pricing AgingPricing Aging&FrequentCustomer Pricing
Plug and Play? 2. decoupled black-box composition higher-level collaboration lower-level collaboration
Plug and Play? 2. decoupled black-box composition OrderParty LineItemParty LineItemParty float price() total() float price() :OrderParty 1:lineItem = next() 2: price() :LineItemParty LineItemParty lineItem :LineItemParty :LineItemParty LineItemParty
Plug and Play? • Requirements on the design: • flexible composition mechanisms to support reusing existing collaborations to build more complex collaborations. Why? • Loose coupling among collaborations in the sense that their definition does • not make explicit commitments to a particular structure of composition. • The aim is to facilitate putting the same components into several • compositions in a flexible manner. • A composition mechanism that maintains the ``encapsulation'' and • independence of collaborations when involved in compositions with • other components. The aim is to avoid name conflicts and allow • simultaneous execution of several collaborations even if these may • share a common ``parent''’.
Interface Class Graph minimal assumptions on the structure of the applications P1 + P3 P2 expected interfaces Behavior Definition main-entry main control flow of the collaboration P 1 m m m m ... 1,k 1,1 1,k 1,1 written to the ICG similar to an OO program written to a concrete class graph P 3 ... How do APPCs look like?
How do APPCs look like? APPC Pricing { Interface Class Graph: // structural interface LineItemParty = <item> ItemParty <pricer> PricerParty <customer> Customer ItemParty = <charges> ListOf(ChargerParty) // behavioral interface LineItemParty { int quantity();} PricerParty { float basicPrice(ItemParty item); float discount(ItemParty item, int qty, Customer customer); } ChargerParty { float cost(int qty, float unitP, ItemParty item); }
How do APPCs look like? Behavior Definition: LineItemParty { main-entry float price() { float basicPrice, unitPrice; int discount, qty; qty = this.quantity(); basicPrice = pricer.basicPrice(item); discount = pricer.discount(item, qty, customer); unitPrice = basicPrice - (discount * basicPrice); return (unitPrice + item.additionalCharges(unitPrice, qty));} } ItemParty { private float additionalCharges(float unitP, int qty) { float total; while (chargerParties.hasElement()) { nextCharge = chargerParties.next(); total =+ charge.cost(qty, unitP, itemInst); return total; } }
P3 P2 P 1 m m 1,k 1,1 How do I attach APPCs to aplications? participant-to-class name map Interface Class Graph Application C1 expected interface name map P1 C4 link-to-path map Behavior Definition C2 C3 main-entry ... adaptive compiler (CCG-to-CGI conformance?) executable Java code
How do I attach Pricing APPC to applications? Map 1 HWAppl::+ {float regularPrice() = Pricing with { LineItemParty = Quote; PricerParty = HWProduct { basicPrice = regPrice; discount = regDiscount }; ItemParty = HWProduct; ChargerParty = Tax { cost = taxCharge};} Application prod Quote HWProduct cust taxes Pricing APPC Tax Customer Tax Tax Tax adaptive compiler (CCG-to-CGI conformance?)
How do I attach Pricing APPC to applications? Map 1 HWAppl::+ {float regularPrice() = Pricing with { LineItemParty = Quote; PricerParty = Customer { basicPrice = negProdPrice; discount = negProdDiscount }; ItemParty = HWProduct; ChargerParty = Tax { cost = taxCharge};} Application prod Quote HWProduct cust taxes Pricing APPC Tax Customer Tax Tax Tax adaptive compiler (CCG-to-CGI conformance?)
What is produced by the adaptive compiler? class Quote { …. public regPrice() { RegularPriceVisitor v = RegularPriceVisitor(); return {v.price (this);} …. } class RegularPriceVisitor { public price (Quote host) { ... } private additionalCharges(float unitPrice, Integer qty) { ... } }
mixin-like behavior definition - late binding of super + static declaration of the assumed specialization interface APPC SpecialPricingmodifiesPricing { Behavior-Definition: LineItemParty { public float price() { float calcPrice = super.price(); return reducedPrice(calcPrice); protected float reducedPrice(float calcPrice); } } How does white-box composition of APPCs work?
How does white-box composition of APPCs work? APPC AgingPricingmodifiesSpecialPricing { Interface-Class-Graph: //more behavioral interface ItemParty {Time stockTime();} Behavior Definition: LineItemParty { protected float reducedPrice(float calcPrice) { ...} } APPC FrequentCustomerPricingmodifiesSpecialPricing { Interface-Class-Graph: //more behavioral interface Customer {... } ItemParty {... } Behavior Definition: LineItemParty { protected float reducedPrice(float calcPrice) { ...} }
How does white-box composition of APPCs work? AgingPriicng SpecialPricing Pricing AgingPolicy = AgingDelta + Pricing AgingDelta = AgingPricing + SpecialPricing reducedPrice price price AgingDelta AgingPolicy AgingPricing SpecialPricing FrequentCustomerPricing SpecialPricing Pricing price price price reducedPrice reducedPrice AgingDelta FrequentCustomerDelta AgingAndFrequentCustomerPolicy AgingAndFrequentCustomerPolicy = AgingDelta + FrequentCustomerDelta + Pricing FrequentCustomerDelta = FrequentCustomerPricing + SpecialPricing
How does black-box composition of APPCs work? well, operations in the expected interface of one (higher-level) APPC can be mapped to the result of instantiating another (lower-level) APPC. APPC Total { Interface-Class-Graph: OrderParty = <customer> Customer <lineItems> SetOf(LineItemParty) LineItemParty { float price(); } Behavior-Definition: OrderParty { main-entry float total() { ... while lineItems.hasElements()) { ... total += nextLineItem.price(); } return total; } } } HWAppl ::+ {float totalReg = Total with { OrderParty = Order; LineItemParty = Quote {price = regularPrice}; }
Adaptive Programming APPCs Rondo Related Work visitor pattern (GOF) role modeling with template classes (VanHilst & Notkin) mixin-layers (Smaragdakis & Batory) contracts (Holland) SOP (Harrison & Ossher)
Future Work Implement APPCs using Java Beans Formal semantics of APPCs Develop a library of APPCs to replace an existing framework
Subject-Oriented ProgrammingHow are APPCs different? • Both subjects and APPCs use the idea of an interface class graph • But APPCs use ideas from graph theory and automata theory to help map interface class graphs to concrete application class graphs: mapping may be controlled by strategy graphs.
Subject-Oriented ProgrammingHow are APPCs different? • APPCs support a traversal-visitor style of programming • Traversals are specified by graphs (strategy graphs) that direct the navigation in both positive and negative ways • Strategy graphs are automatically converted into traversal code (error-prone if done manually)
Underlying ideas • Graph1 refinement Graph2 • Graphs can play the following roles: • interface class graph • (application class) graph • positive strategy graph
G1compatibleG2 F F D D E E B B C C G2 Compatible: connectivity of G2 is in G1 G1 A A
G1refinementG2 F F D D E E B B C C G2 refinement: connectivity of G2 is in G1 and G1 contains no new connections in terms of nodes of G2 G1 A A
Small graph G PSG PSG Big graph G PSG G Roles graphs play in OODunder refinement relations G: class graph (CG) or interface class graph (ICG). ICG is a view on a class graph. PSG: positive strategy graph.
Roles graphs play in OODunder refinement relations PSG PSG subtraversal
Applications of strategy graphs • Specify mapping between graphs (adaptor) • Advantage: mapping does not have to refer to details of lower level graph robustness • Specify traversals through graphs • Specification does not have to refer to details of traversed graph robustness • Specify function compositions • without referring to detail of API robustness
Applications of strategy graphs • Specify range of generic operations such as comparing, copying, printing, etc. • without referring to details of class graph robustness. Used in Demeter/Java. Used in distributed computing: marshalling, D, AspectJ, Xerox PARC
Theory of Strategy Graphs • Palsberg/Xiao/Lieberherr: TOPLAS ‘95 • Palsberg/Patt-Shamir/Lieberherr: Science of Computer Programming 1997 • Lieberherr/Patt-Shamir: 1997 NU TR • Lieberherr/Patt-Shamir: Dagstuhl ‘98 Workshop on Generic Programming (LNCS)
Strategy graph and base graph are directed graphs Key concepts • Strategy graph S with source s and target t of a base graph G. Nodes(S) subset Nodes(G) (Embedded strategy graph). • A path p is an expansion of path p’ if p’ can be obtained by deleting some elements from p. • S defines path set in G as follows: PathSetst(G,S) is the set of all s-t paths in G that are expansions of any s-t path in S.
PathSet(G1 ,G2) F=t F D D E E B B C C G2 G1 A = s A
Strategy graph and base graph are directed graphs Key concepts • A strategy graph G1 is a path-set-refinement of a strategy graph G2 if for all base graphs G3: PathSet(G3,G1) PathSet(G3,G2).