PhaserMatchâ„¢ ICC 7700 Printer Color Management Software Introduction What is color
Software Product Lines - Carnegie Mellon School of ... Philips Siemens ... Software Product Lines...
Transcript of Software Product Lines - Carnegie Mellon School of ... Philips Siemens ... Software Product Lines...
Configuration in Software
• Systems cover all possible functionality– e.g., Windows, Open Office, Oracle, SAP myERP,
Photoshop
• Specialized software and software for embedded systems increasingly important– Mobile divices, sensor networks, automotive systems,
consumer electronics, smart cards, ubiquitious computing
– 98% of all CPUs in embedded devices [2000]
– Resource constraints, heterogeneous hardware
4
Linux kernel
~6 000 000 Lines of C code Highly configurable
> 10.000 configuration options! (x86, 64bit, …)
Most source code is “optional”
Software Product Linesin Industry
BoeingBosch GroupCummins, Inc.EricssonGeneral DynamicsGeneral MotorsHewlett PackardLockheed MartinLucentNASANokiaPhilipsSiemens…
Software Product Lines
• Coordinated development of a family of software systems
• Sharing code, reusealbe parts(instead of developing from scratch)
• Tailoring to specific needs
Global configuration optionsclass Config { public static boolean isLogging = false; public static boolean isWindows = false; public static boolean isLinux = true;}class Main { public void foo() { if (isLogging) log( running foo()“);„ if (isWindows) callWindowsMethod(); else if (isLinux) callLinuxMethod(); else throw RuntimeException();} 26
Graph Library
class Edge { Node a, b; Color color = new Color(); Weight weight; Edge(Node _a, Node _b) { a = _a; b = _b; } void print() { if (Conf. COLORED) Color.setDisplayColor(color); a.print(); b.print(); if (!Conf.WEIGHTED) weight.print(); }}
class Graph { Vector nv = new Vector(); Vector ev = new Vector(); Edge add(Node n, Node m) { Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); if (Conf.WEIGHTED) e.weight = new Weight(); return e; } Edge add(Node n, Node m, Weight w) if (!Conf.WEIGHTED) throw RuntimeException(); Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); e.weight = w; return e; } void print() { for(int i = 0; i < ev.size(); i++) { ((Edge)ev.get(i)).print(); } }}
class Node { int id = 0; Color color = new Color(); void print() { if (Conf.COLORED) Color.setDisplayColor(color); System.out.print(id); }}
class Color { static void setDisplayColor(Color c) { ... } } class Weight { void print() { ... } }
class Conf { public static boolean COLORED = true; public static boolean WEIGHTED = false;}
Limitations
31
• Variable code scattered in entire program
– Hard to test in isolation
• Global variables or long parameter lists
• All code always included
– Binary size, memory consumption
– Performance
– Unused functionality as attack vector
• Changes at runtime or load-time?
Limitations
32
• Variable code scattered in entire program
– Hard to test in isolation
• Global variables or long parameter lists
• All code always included
– Binary size, memory consumption
– Performance
– Unused functionality as attack vector
• Changes at runtime or load-time?
compile-time if
designpattern
Berkeley DB
#include "db_int.h"
static int __rep_queue_filedone(dbenv, rep, rfp)DB_ENV *dbenv;REP *rep;__rep_fileinfo_args *rfp; {
#ifndef HAVE_QUEUECOMPQUIET(rep, NULL);COMPQUIET(rfp, NULL);return (__db_no_queue_am(dbenv));
#elsedb_pgno_t first, last;u_int32_t flags;int empty, ret, t_ret;
#ifdef DIAGNOSTICDB_MSGBUF mb;
#endif// over 100 lines of additional code
}#endif
35
Preprocessor in Java?• No native preprocessor• Some compilers support conditional compilation
at statement level
• External tools
class Example {public static final boolean DEBUG = false;
void main() {System.out.println(“immer”);if (DEBUG) {
System.out.println(“debug info”); printDetails(); }
} void printDetails() { ... }}
36
Munge• Simple external preprocessor for Java• Originally developed for Swing 1.2
class Example {void main() {
System.out.println(“immer”);/*if[DEBUG]*/System.out.println(“debug info”);/*end[DEBUG]*/
}}
java Munge –DDEBUG –DFEATURE2 file1.java file2.java
http://weblogs.java.net/blog/tball/archive/2006/09/munge_swings_se.html37
Configurable Graph Libraryclass Edge { Node a, b; /*if[COLOR]*/ Color color = new Color(); /*end[COLOR]*/ /*if[WEIGHT]*/ Weight weight; /*end[WEIGHT]*/ Edge(Node _a, Node _b) { a = _a; b = _b; } void print() { /*if[COLOR]*/ Color.setDisplayColor(color); /*end[COLOR]*/ a.print(); b.print(); /*if[WEIGHT]*/ weight.print(); /*end[WEIGHT]*/ }}
class Graph { Vector nv = new Vector(); Vector ev = new Vector(); Edge add(Node n, Node m) { Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); /*if[WEIGHT]*/ e.weight = new Weight(); /*end[WEIGHT]*/ return e; } /*if[WEIGHT]*/ Edge add(Node n, Node m, Weight w) Edge e = new Edge(n, m); nv.add(n); nv.add(m); ev.add(e); e.weight = w; return e; } /*end[WEIGHT]*/ void print() { for(int i = 0; i < ev.size(); i++) { ((Edge)ev.get(i)).print(); } }}
class Node { int id = 0; /*if[COLOR]*/ Color color = new Color(); /*end[COLOR]*/ void print() { /*if[COLOR]*/ Color.setDisplayColor(color); /*end[COLOR]*/ System.out.print(id); }}
/*if[COLOR]*/class Color { static void setDisplayColor(Color c) { ... } }/*end[COLOR]*/
/*if[WEIGHT]*/class Weight { void print() { ... } } /*end[WEIGHT]*/
Discussion• Compile-time configuration• Can remove arbitrary code before
compilation• Simple programming model
• Bad reputation– Scattered code
– Error prone
– Hard to understand
– Invites neglecting design
– Hinder tool support40
class Stack {void push(Object o
#ifdef SYNC, Transaction txn
#endif) {
if (o==null#ifdef SYNC
|| txn==null#endif
) return;#ifdef SYNC
Lock l=txn.lock(o);#endif
elementData[size++] = o;#ifdef SYNC
l.unlock();#endif
fireStackChanged();}
}
class Stack {void push(Object o
#ifdef SYNC, Transaction txn
#endif) {
if (o==null#ifdef SYNC
|| txn==null#endif
) return;#ifdef SYNC
Lock l=txn.lock(o);#endif
elementData[size++] = o;#ifdef SYNC
l.unlock();#endif
fireStackChanged();}
}
Error Prone
static int _rep_queue_filedone(...)DB_ENV *dbenv;REP *rep;__rep_fileinfo_args *rfp; {
#ifndef HAVE_QUEUECOMPQUIET(rep, NULL);COMPQUIET(rfp, NULL);return (__db_no_queue_am(dbenv));
#elsedb_pgno_t first, last;u_int32_t flags;int empty, ret, t_ret;
#ifdef DIAGNOSTICDB_MSGBUF mb;
#endif//over 100 lines of additional code
}#endif
#ifdef TABLESclass Table { void insert(Object data,
Txn txn) { storage.set(data,
txn.getLock()); }}#endifclass Storage {#ifdef WRITE boolean set(…) { ... }#endif}
Error Prone
static int _rep_queue_filedone(...)DB_ENV *dbenv;REP *rep;__rep_fileinfo_args *rfp; {
#ifndef HAVE_QUEUECOMPQUIET(rep, NULL);COMPQUIET(rfp, NULL);return (__db_no_queue_am(dbenv));
#elsedb_pgno_t first, last;u_int32_t flags;int empty, ret, t_ret;
#ifdef DIAGNOSTICDB_MSGBUF mb;
#endif//over 100 lines of additional code
}#endif
#ifdef TABLESclass Table { void insert(Object data,
Txn txn) { storage.set(data,
txn.getLock()); }}#endifclass Storage {#ifdef WRITE boolean set(…) { ... }#endif}
A matter of scale
E x a m p l e : S e s s i o n e x p i r a t i o n i n t h e A p a c h e T o m c a t S e r v e r
47
Design Patterns
• Solutions to reoccuring design problems
• Design for extensibility, variation, and reuse are reoccuring problems
• Separate variable part from stable part
• Strategy pattern• Template method pattern• Decorator pattern• Observer pattern
49
Inheritance for Variability
52
S t a c k
S e c u r e S t a c k S y n c h r o n i z e d S t a c kU n d o S t a c k
modular, but inflexible
Inflexible Extension Mechanism
S t a c k
S e c u r e S t a c k
S y n c h r o n i z e d S t a c k
U n d o S t a c k
S t a c k
S e c u r e S t a c k S y n c h r o n i z e d S t a c kU n d o S t a c k
Extensions
not combinable
Middle extension
not optional
cf. White-Box Framework
Work arounds?
• Combining inheritance hierarchies– Combinatorical explosion– Massive code replication
• Multiple inheritance– Diamond problem
S t a c k
S e c u r e S t a c k
S y n c h r o n i z e d U n d o S e c u r e S t a c k
U n d o S t a c k
U n d o S e c u r e S t a c kS y n c h r o n i z e d U n d o S t a c k
S y n c h r o n i z e d S t a c k
+ p u s h ( )+ p o p ( )+ s i z e ( )
- v a l u e s
S t a c k
+ p u s h ( )+ p o p ( )+ s i z e ( )+ l o c k ( )+ u n l o c k ( )
L o c k e d S t a c k
+ p u s h ( )+ p o p ( )+ u n d o ( )
- l o g
U n d o S t a c k
L o c k e d U n d o S t a c k
Decorator Pattern
+ p u s h ( )+ p o p ( )+ s i z e ( )
« i n t e r f a c e »I S t a c k
+ p u s h ( )+ p o p ( )+ s i z e ( )
- v a l u e s
S t a c k
+ p u s h ( )+ p o p ( )+ s i z e ( )
- d e l e g a t e
S t a c k D e c o r a t o r
+ p u s h ( )+ p o p ( )+ s i z e ( )+ l o c k ( )+ u n l o c k ( )
L o c k e d S t a c k
+ p u s h ( )+ p o p ( )+ u n d o ( )
- l o g
U n d o S t a c k
+ p u s h ( )+ p o p ( )+ e n c r y p t( )+ d e c r y p t( )
- k e y p h r a s e
S e c u r e S t a c k
1
1
Delegation vs. Inheritance
• Allows dynamic (re-)configurations• Requires independent extensions• Can override but not add methods• Late binding hard to implement• Many indirection (runtime overhead)• No compile-time optimization
• Advanced language constructs: mixins, traits, ...
Frameworks
• Set of abstract and concrete classes• Reusable solutions of a set of problems• Planned hot spots, extended by plug-ins
• Extension mechanisms often based on design patterns
– Strategy
– Template method
– Observer
58
Discussion
• Separated, modular extensions
– Compile and test plug-ins separately• Compile-time/load-time configuration• Well understood in practice• Hard to design, hard to evolve• Small runtime overhead• Suited for coarse-grained extensions
59
From HP to Linux
2000 FeaturesInhouse configuration100 Printers (Product Map)30 New Printers per Year
10000 FeaturesEnd user configures
210000 Configurations
∀ p PL . ...∈
true
Dead-Code Detection
line 1#ifdef Aline 2 #ifndef A line 3 #endifline 4#elif defined(X)line 5#elseline 6#endif
A
A ^ not A
A
not A ^ X
not A ^ not X
Dead code
Analysis:SAT(pc(block i))
Dead-Code Detection
class Example {public static final boolean DEBUG = false;
void main() {System.out.println(“immer”);if (DEBUG) {
System.out.println(“debug info”); printDetails(); }
} void printDetails() { ... }}
66
Closed-World Analysis
Specified Variability Implementation Variability
P
WORLD
BYE
WORLD v BYE
¬ (WORLD ˄ BYE)
(WORLD v BYE) ˄¬ (WORLD ˄ BYE)
Check Consistency
∀ p PL .∈ p is well-typed
Cohen et al. Interaction testing of highly-configurable systems in the presence of constraints. ISSTA 2007
F1 F2 F3
on on on
on on off
on off on
on off off
off on on
off on off
off off on
off off off
Pairwise Testing
Cohen et al. Interaction testing of highly-configurable systems in the presence of constraints. ISSTA 2007
F1 F2 F3
on on on
on on off
on off on
on off off
off on on
off on off
off off on
off off off
Pairwise Testing
Other Topics
• Product planning, product-line scoping
• Team organization
• Development and design process (domain engineering)
• More implementation techniques (components, version control systems, feature/aspect-oriented development)
• Product-line analysis
Summary
• Software product lines: Systematic reuse by planning variations
• From runtime parameters and conditional compilation to design patterns and frameworks
• Analysis for product lines
73
Further Reading
K. Czarnecki and U. Eisenecker. Generative Programming: Methods, Tools, and Applications. Addison-Wesley, 2000.
Christian Kästner, and Sven Apel. Feature-Oriented Software Development: A Short Tutorial on Feature-Oriented Programming, Virtual Separation of Concerns, and Variability-Aware Analysis. In GTTSE Summer School: Generative & Transformational Techniques in Software Engineering, Springer-Verlag, 2011.
P. Clements, L. Northrop. Software Product Lines: Practices and Patterns. Addison-Wesley, 2002
74