Class and Method Design MSO 08/09, Chapter 10, WP
Feb 22, 2016
Class and Method Design
MSO 08/09, Chapter 10, WP
Positioning
2
Why are we talking about “class” and “method” design? Is this course is not supposed to be about “system” ?
Because in the end we have to build our classes and methods, and they represent lots of work, of which we again has “design” issue.
(Dennis et al, Wiley)
Objectives of chapter 10, learning to:
write designs write specifications. aware of some design* criteria
3
Certain issues in Ch. 10 are actually closer to implementation than design! So our scope will also extend a bit to implementation.
Design Implementation
Keep an objective perspective....
4
(Dennis et al, Wiley)
(Wikipedia)
Overall Dennis et al tend to lean towards “waterfall” SDLC
heavy emphasis on well documented designs.
Keep in mind that we also have the “agile” model.
Some relevant statements from Agile
5
However, too much documentation is worse than too little. Huge software documents take a great deal of time to produce, and even more time to keep in sync with the code. If they are not kept in sync, then ... become a significant source of misdirection.
(Robert C. Martin, Agile Processes, 2001)
Software cannot be ordered like a commodity. You cannot write a description of the software you want and then have someone develop it on a fixed schedule for a fixed price. Time and time again, attempts to treat software projects in this manner have failed.
(Robert C. Martin, Agile Processes, 2001)
But knowing nothing about well documented designs would be too naive either! So we proceed with Dennis et al; on the field you will have to use your own judgment as to whether to use Waterfall or Agile, or a mix of both.
How will we proceed ?
We’ll use the book’s example: Internet CD shop
Using this example we’ll go through the design steps.
We'll discuss some design/development criteria
And some other issues like dynamic binding.
6
Internet CD Shop, excerpt from ‘system request’
7
System Request: Internet Shop
Project sponsor: Margaret Mooney, VP of Marketing
Business Requirement:
... The provided functionalities :
• Search through our CDs inventory• Identify the retail stores that have a given CD product• Schedule product pickup from a store• Place an order if product is not in stock
...
Business Value:
... 750.000 $ yearly increase in sales.
Overall design at the class diagram level
8
Designing a class and method
Dennis et al:
Add more specifications
When needed iteratively optimize and restructure your design
Map design to an implementation language
9
For a class:• attributes and operations• types and visibility• constraints
Class CD
10
CD--------------+CD Number+CD Name+Pub Date+Artist Name+Artist Number+Vendor/Vendor ID--------------
Package CD
Dennis’ CRC card of the class CD
11
Class name : CDDescription : represents a CDResponsibilities : Collaborators : Order Item, CD List, Vendor, Mkt Info
Duplicated information , hopefully you have a CASE tool to maintain consistency.
Constraint
Constraints
12
CD Vendor< distributes
1..10..*
CD--------------+CD Number+CD Name...+Vendor +VendorID--------------
{ CD Vendor.distributes }
{ VendorID = Vendor.ID }
Constraints
pre-conditions and post-conditions (for methods) (class) invariants
13
Tax = State.GetTaxRate() * SubTotal
SubTotal =Sum(ProductOrder.Qty * ProductOrder.Product.Price)
Object Constraint Language (OCL)
Formal. You may want to take a look at it. Now part of UML standard. Examples:
14
context CDinv self.VendorID = self.Vendor.ID
context CDinv self.Vendor.distributes includes(self)
CD--------Vendor
VendorID
Vendor< distributes
1..10..*
Basic OCL Class invariant:
context <class name> inv : <boolean expression>
Specifying pre/post-condition of an operation:
context <class name>::<operation name>(<parameters>) : <return type>
pre: <boolean expression>post: <boolean expression>
Logical operators like “and”, “or”, “implies” etc to form your boolean expression.
15
Basic OCL “self” refers to an object of the described class; can be omitted if
unambiguous.
Referring to an attribute of an object:
<object expression> . <attribute>
Calling an operation of an object:
<object expression> . <operation> ( <parameters> )
Navigating through relations:
<object expression> . <your own side of relation><object expression> . <partner’s role>
16
Basic OCL OCL provides several concepts of collections: Set, Bag, Seq
Navigation through a relation by default results in a Set of objects but a single object if the relation maps to 1..1 multiplicity
a whole bunch of standard “properties” on collections:
size, includes, forall, ...
Usage: <collection expression> –> <collection property>
17
Method Contract
18
Method name : GetReview(int k) Class Name : Mkt InfoClients : CDAssociated Use Cases : AskCDInformation
Responsibilities: returning the latest k reviews about this CD
Arguments received: obviousType of value returned: list of Reviews
Pre-condition: 0k<10Post-condition: returned list contains at most k elements.
Primarily is used to specify the pre- and post-conditions of a method.
Method specification In Dennis et all it contains lots of information (Fig. 10-14)
e.g. types of the arguments and return val. events that trigger the method list of other methods called from within the specified method explanation on the used algorithm
Many would call Dennis’ “contract” as “specification”.
19
We can just as well do this in the “contract”
I’m not sure if we should really document this kind of details in a design. I would document this in the implementation.
Method contract in OCL
20
context MktInfo :: GetReview(int k) : Seq(Review)pre : 0k<10post : result size() k
and
result forall( r | self.reviewedBy include(r) )
MktInfo------------
------------getReview
ReviewreviewedBy >
0..*1..1
Quiz : express these “business rules”
21
Top100
0..1
0..*< listedBy
• Top100 only has 1 instance!
• Every CD listed in top-100 should have a sample clip.
• A VIP vendor must distribute all CDs in top 100.
promotedBy >
has >
VIP : boolean
So, is our design good !?
Coad & Yourdon: “a good design is one that balances trade-offs to minimize the total cost of the system over its entire lifetime”.
Dennis et al suggest these as design criteria :
cohesion, coupling, connascence
These are concepts from software quality metrics
You can't measure them without having an implementation We should be aware of them as we develop
22
Cohesion is the extent to which the elements of a 'module' are related
to one another. Originally by Stevens, Myers, Constantine, 1974!
High cohesion (good): if all methods of the class CD are related to a single purpose.
Cohesion is lower when CD provides a set of methods to inspect a CD a set of utility methods to format reviews
Very low if ... Difficult to measure with an automated tool...
23
Coupling Also originally by Stevens, Myers, Constantine, 1974.
The coupling between two modules is the manner and degree of interdependence between them [IEEE].
E.g. the coupling is high (bad) if changing the internal implementation of A may impact B
will increase your maintenance cost !
Otherwise the coupling is low (good)
24
Coupling types between module A and B
Some of the traditional notions of coupling, from low to high:
no coupling data coupling stamp coupling control coupling global coupling content coupling
25
Coupling (explained at the "procedures" level)
Data coupling : A,B interact by passing 'elementary' data.
E.g. between min and max here:
min(int x, int y) { if x<max(x,y) return x else y }
Stamp coupling: A,B interact by passing composite data, each using only part of them.
E.g. between discount and notify
discount(CD x) {x.price = x.price – 10 ;notify(x.vendor, x)}
26
Coupling control coupling: in the interactions between A and B, one
passes parameters that alter the algorithm of the other.
E.g. :
getBestReview() { ... z = getReview(1) ... }
getReview(int k) { if (k == -1) then ... // return all reviews else if (k > 0) then ... // return k-th review else ... // return empty list }
27
Coupling Common/global coupling: interactions between A and B use
global variables (rather than purely using parameters).
Content coupling: if A requires access to B's internal information.
In most modern languages, content coupling is not even possible.
28
Declaration coupling [Binkley & Schach, 98]
If module A uses something declared in module B. A refers to an attribute in B A calls a method of B A inherits a member from B A has an attribute of type B A has a method with a parameter of type B ...
Very broad definition, but still useful
29
So, what can we do with these ?
We can scan our software and calculates e.g. The overall decl. coupling Decl. coupling per package
But this is so trivial!
Well, keep in mind that real software have hundreds of classes.
Strategic information like this can be a valuable instrument as you try to steer your development and maintenance processes.
30
Law of Demeter Coming from a design guideline for developing OO software in 1987 reduce
coupling.
31
x : CD m : MktInf
r : Review
getAReview()
we get a Review “r” here
Make it so that each object only talk with its friends.
CD MktInf Review
getOtherReviews()
1..*
Returning all reviews by written by r.author
Law of Demeter More concretely, inside a method m(x,y) in a class C we should only
calls: methods of self/this methods of objects in the attributes/relations of self/this methods of x and y methods of objects created in m
E.g. this would be considered bad :
32
class CD { ... getRelatedReviews() {
return promotedBy.getAReview().getOtherReviews
} ...
Law of Demeter
Advantage: the resulting software tends to be more maintainable and adaptable.
Experimental results in 1996 by Basili et al suggests that Law of Demeter reduces the probability of software fault.
Critics: classes may become excessively cluttered with wrapper methods negatively impact maintenance. decrease cohesiveness
33
Mapping Design to Implementation Lang.
The choice of impl. lang. can be imposed by your business setup
Several possible scenarios:
OO lang. with multiple inheritance watch out for inheritance conflict.
OO lang. with single inheritance have to factor out M-Inh in your design.
Non OO lang mapping would be too complicate.
34
Multiple inheritance language C++, Eiffel, Python ... To watch out inheritance conflict
Two inherited members have different names but same semantic.
Two inherited members have same name but different semantics
35
Coffee
Drink--------------pour()
Plant-------------show()pour()
Factoring out Mult. Inheritance Java is single inheritance Java "Interface" is not really a superclass :
as in: class Coffee extends Drink implements Plant { ... }
In "Plant" we can't have fields nor method bodies, thus we can't let Coffee inherit them either.
36
Coffee
Drink--------------pour()
Plant-------------LatinName-------------show()
Simulate MI with delegation
But: the compiler won't see that a Coffee can also be seen as a Plant. You have to manually initialize with the right plant. You have to explicitly add Plant's members to Coffee.
37
public class Coffee extends Drink { ...
private Plant p = ... ;
public show() { return p.show() ; }
public getLatinName() { return p.LatinName ; }
}
Coffee
Drink--------------pour()
Plant-------------LatinName-------------show()
Other solution: Abstract Coupling
Drink and Plant are now Interfaces
Additionally we have classes DrinkImp and PlantImp as the actual implementation of Drink and Plant.
Let Coffee implements both interfaces
Add (in Coffee) delegations to DrinkImp and PlantImp
38
MI via Abstract Coupling
39
interface Plant {show() }
class PlantImp implements Plant { String LatinName ; String show() { ... } ; ...} class Coffee implements Drink, Plant {
... private ImpDrink d = ... ; private ImpPlant p = ... ;
show() { return p.show() ; } pour() { return d.pour() ; } getLatinName() { return p.LatinName ; } ...}
Few other issues to mention Overriding method Polymorphism
40
Overiding
41
class Coffee extends Drink { ...}
class Drink { ... pour() // pour the drink into a cup }
pour() // pour the coffee into a coffee cup
pour() // pour water into Senseo machine
pour is not overriden.
Polymorphism Literally: ability to take multiple shapes. In programming it is a feature allowing values of different
types to be handled uniformly.
In FP:
a program that can handle a list of any type.
In Java:
a program that can handle any Plant, or any instance from its subclasses.
42
head :: [a]Int
class Plant { ... show() { ... } }
Dynamic Binding Because you can override, polymorphism in Java leads to
this issue:
43
class Application { helper(Plant p) { ... ; return p.show() }
main(args) { if (args.length > 0) helper(new Plant()) : else helper(new Coffee()) ; ... } }
So, which method is called here?
This is only known at the runtime dynamic binding.
Threat : semantic inconsistency.