"Contemporary software seems to equate design with objects. ... Yet not all that is in C++ is object-oriented, and most implementations take advantage of C++ features that are not object-oriented. This suggests that most designs in fact have a nontrivial component that is not object-oriented."
"Multi-paradigm embraces many of the goals of the object paradigm, but the goals differ in scope."
(James Coplien, 1999)
Design is about 'commonalities' and 'variations'
"When we think abstractly, we emphasize what is common while suppressing detail. A good software abstraction requires that we understand the problem well enough in all of its breadth to know what is common across related items of interest and to know what details vary from item to item."
Coplien calls these collective items of interest 'families'
Software design is multidimensional
a procedural axis, a data structure axis, an axis of compliant behaviors, and so on
each design technique ("-oriented") picks its own favorite axes of commonality/variability and uses them to formulate abstractions
Java is accidentally multiparadigmatic
a derivation of C++, Java deliberately sought to remove those features that detracted from object-oriented
despite that, Java has still managed to evolve into a language that supports multiple paradigms
it encompasses procedural, structural, object-ual (1.0), metaobject-ual (1.1,1.5), functional (1.1), dynamic-ual (1.1), and other "dimensions of commonality/variation" within its borders
as a result, it's getting to be a complicated to understand when to use one axis over a different axis
This lecture will not cure the world's Java design ills
too much of the problem is context-dependent
too much of the solution is aesthetics-driven
the space of possible design approaches is too large
But this lecture will...
help you to understand the different design axes
help you to see some of their idiomatic components
give you some ideas on how to approach which features to use, when
"But..."
"... I'm already using objects! Just show me the new features of Java 7 and be done with it already!"
"... I'm already using object-oriented design techniques, and though there are occasional problems, things tend to work out somehow. Why should I put those techniques aside and look at multi-paradigm design? After all, C++ is an object-oriented language, isn't it?"
With all due respect.... No.
C++ began a dangerous trend that only accelerated with Java and C# shortly thereafter: "the term 'object-oriented' has become a synonym for 'good'."
"One common failure is to use structured analysis to build an initial design around system data structures and then implement using responsibility-driven design. … Cohesion of the original data models breaks down and objects are forced more and more to expose their internal data structure."
Or we just use Reflection to pretend that the internal data structure is still well-encapsulated…
Go back to basics: commonality and variability
this is the how the human mind forms abstractions
we classify things into a family: abstractions we treat together because they are more alike than different
Commonalities are uninteresting: once we find it and agree to it, it's not worth discussing any further.
Variabilities capture the more interesting properties that distinguish abstractions in a domain
Different kinds of variability emerge
variability over time
We try to predict (!!) how the domain will change, or more importantly, how it won't change, and capture that as the commonality in the system structure
We do this to reduce maintenance costs
variability over space (within a family)
We try to identify commonalities in a family of abstractions for a product or product line
We do this to reduce development effort
Different kinds of variability emerge:
positive variability: variabilities that "add" to the underlying commonality
a Message class has a header and body; a positive variability is a special kind of Message that carries particular values in the header (date sent, date received, etc)
negative variability: variabilities that contradict or "remove" the underlying commonality
a Message class has a header and a body; a negative variability is a special kind of Message that has no body
Conclusion:
prefer to design with positive variability whenever possible!
Late binding: "bind all decisions as late as possible so that you can give customers control over system evolution" (Gregor Kiczales, 1994)
"If you can't conquer, divide, and try a meta-object protocol" (Kiczales)
Some common procedural concepts:
derived from "structured programming"
align data structures with program structures
where the logic of a program is a structure composed of similar sub-structures in a limited number of ways, thus reducing understanding a program to understanding each structure on its own, and in relation to that containing it
focus on modularity
Commonality/Variability
commonality captured principally through data structures
variability captured by providing different procedures by which to manipulate the data structures
at a larger scope, a data structure and its associated procedures (or a group of data structures and all the associated procedures) were grouped together into a module and reused
developers could always write their own procedures to operate on those common data structures, thus providing greater variability than that provided by the module
most variability here was positive variability
negative variability was often sneaky and hacky and ugly
Common object concepts:
dynamic dispatch
abstraction
subtype polymorphism
inheritance
encapsulation
Common design approaches:
data-driven design
responsibility-driven design
Commonality/Variability:
objects bring together two dimensions of commonality (behavior, structure) into a single abstraction
interfaces: clean separation of behavior from structure
inheritance: third dimension of commonality/variability
Open/Closed Principle: "Software entities (classes, modules, functions, etc) should be open for extension, but closed for modification."
(strong) behavioral subtyping
Liskov Substitution Principle: "Let q(x) be a property provable about objects x of type T. Then q(y) should be true for objects y of type S where S is a subtype of T."
Objects in common use are not without criticism:
Objects as "intelligent data"
Cast member data as a collection of states and to treat all objects as finite state machines
Overuse of inheritance
Fragile base-class (FBC) syndrome
Violations of LSP:
Use of RTTI to select a method based on object type
Square IS-A Rectangle: is a programmer justified in assuming that changing the width of a Rectangle leaves its height unchanged?
Metaprogramming: writing of programs that write or manipulate other programs (or themselves) as their data, or that do part of the work at compile time that would otherwise be done at runtime
three major forms:
automatic (code generation)
generic (parametric polymorphism)
reflective (attribute-oriented)
goal: to "lift algorithms and data structures from concrete examples to their most general and abstract form"
Commonality/Variability
Automatic Metaprogramming:
common structure or behavior (rarely both)
variability can vary (if you’ll pardon the pun)
Generic Metaprogramming:
common structure (class template)
common behavior (function template)
variability of data types
Reflective Metaprogramming:
commonality of algorithmic context
variability of structure, behavior, algorithm
Common concepts:
late binding
call dispatch flexibility
runtime error resolution
Meta-Object Protocol
Commonality/variability
name-based variability: relate groups of objects/classes together by member names
Functional languages
functional as in mathematics' notion of function
for every x, there is a corresponding value y
this implies no side effects (pure functionality)
not imperative statements, but expressions
"x = x+1" is not increment, but impossible
this implies expressions can be substituted
... or executed independently (paralellism)
strongly-typed, statically-typed, type-inferenced
full benefits of static typing and type-checking
"implicitly generic" (where applicable)
... but without all the "high ceremony" of C#/Java
Some basic functional concepts
functions as first-class values
currying, partial-application of functions
expressions-not-statements
immutable values
strongly-typed, type-inferenced
tuples, lists
recursion
pattern-matching
Commonality/variability:
functions seperate behavior and structure, using behavior as the core abstraction and leaving structure to be inferred (in most cases)
functional types (tuples) provide a new kind of commonality through structural typing
Kata Four: Data Munging
an exercise in three parts
Part One: Weather Data
In weather.dat you’ll find daily weather data for Morristown, NJ for June 2002. Download this text file, then write a program to output the day number (column one) with the smallest temperature spread (the maximum temperature is the second column, the minimum the third column).
(http://pragdave.pragprog.com/data/weather.dat)
solve it more than once: procedurally, object-ly, metaprogrammatically, dynamically, and/or functionally
Kata Four: Data Munging
an exercise in three parts
Part Two: Soccer League Table
The file football.dat contains the results from the English Premier League for 2001/2. The columns labeled ‘F’ and ‘A’ contain the total number of goals scored for and against each team in that season (so Arsenal scored 79 goals against opponents, and had 36 goals scored against them). Write a program to print the name of the team with the smallest difference in ‘for’ and ‘against’ goals.
(http://pragdave.pragprog.com/data/football.dat)
solve it more than once: procedurally, object-ly, metaprogrammatically, dynamically, and/or functionally
Kata Four: Data Munging
an exercise in three parts
Part Three: DRY Fusion
Take the two programs written previously and factor out as much common code as possible, leaving you with two smaller programs and some kind of shared functionality. Aggressively decide which of the different variability families (procedure, object, metaobject, dynamic or function) you are going to use.
Who is this guy?
Architect, Engineering Manager/Leader, "force multiplier"
Principal -- Neward & Associates
http://www.newardassociates.com
Educative (http://educative.io) Author
Performance Management for Engineering Managers
Author
Professional F# 2.0 (w/Erickson, et al; Wrox, 2010)
Effective Enterprise Java (Addison-Wesley, 2004)
SSCLI Essentials (w/Stutz, et al; OReilly, 2003)
Server-Based Java Programming (Manning, 2000)