Advanced Object-Oriented Design & Programming
Spring Semester, 2005 Introduction |
||
---|---|---|
© 2005, All Rights Reserved, SDSU & Roger Whitney San Diego State University -- This page last updated 25-Jan-05 |
CS 635 Advanced Object-Oriented Design & Programming Spring Semester, 2005 Doc 1 Introduction
Common Forms For Writing Design Patterns
Sample Refactoring: Extract Method
Copyright ©, All rights reserved. 2004 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA. OpenContent ( http://www.opencontent.org/opl.shtml) license defines the copyright on this document
CS 635 Spring 05 | Doc 1, Introduction Slide # 2 |
Refactoring: Improving the Design of Existing Code, Fowler, 1999, pp. 110-116, 237-270
The Pragmatic Programmer, Hunt & Thomas, Addison Wesley Longman, 2000
Quality Software Management Vol. 4 Anticipating Change, Gerald Weinberg, Dorset House Publishing, 1997
Patterns for Classroom Education, Dana Anthony, pp. 391-406, Pattern Languages of Program Design 2 , Addison Wesley, 1996
A Pattern Language , Christopher Alexander, 1977
Software Patterns, James Coplien, 1996, 2000, http://www1.bell-labs.com/user/cope/Patterns/WhitePaper/
Design Patterns: Elements of Reusable Object-Oriented Software, Gamma, Helm, Johnson, Vlissides, 1995
Abstraction, Encapsulation, and Information Hiding available at: http://www.toa.com/shnn?searticles
Design Patterns chapter 1.
CS 635 Spring 05 | Doc 1, Introduction Slide # 3 |
Writing quality OO code
Some basic tools:
CS 635 Spring 05 | Doc 1, Introduction Slide # 4 |
Java |
Smalltalk |
this |
self |
super |
super |
Field |
Instance variable |
Method |
Method, message |
"A String" |
'A String' |
/* a comment */ |
" a comment" |
x = 5; |
x := 5. |
x == y |
x == y |
x.equals(y) |
x = y |
if (y > 3) x = 12; |
y > 3 ifTrue: [x := 12]. |
if (y > 3) x = 12; else x = 9; |
y > 3 ifTrue: [x := 12] ifFalse: [x := 3]. |
z = Point(2, 3); |
z := 2 @ 3. |
Circle x = new Circle(); Circle y = new Circle(0, 0 3); |
| x y | x := Circle new. Y := Circle origin 0 @ 0 radius: 3 |
a.method() |
a method |
a.foo(x) |
a foo: x |
a.substring(4,7) |
a copyFrom: 4 to: 7 |
return 5; |
^5. |
Java |
Smalltalk |
class Circle { public float area() { return this.radius().squared() * pi(); } } |
Circle>>area ^self radius squared * self pi |
Note Class>>method is not Smalltalk syntax. It is just a convention to show which class contains the method
CS 635 Spring 05 | Doc 1, Introduction Slide # 5 |
C/C++/Java |
Smalltalk |
method() |
method |
public class LinkedListExample { public static void main( String[] args ) { LinkedList list = new LinkedList(); list.print(); } }
| list | list := LinkedList new. list print.
CS 635 Spring 05 | Doc 1, Introduction Slide # 6 |
C/C++/Java |
Smalltalk |
method( argument) |
method: argument |
public class OneArgExample { public static void main( String[] args ) { System.out.println( "Hi mom"); } }
Transcript show: 'Hi Mom'.
CS 635 Spring 05 | Doc 1, Introduction Slide # 7 |
C/C++/Java |
Smalltalk |
method(arg1, arg2, arg3) |
method: arg1 second: arg2 third: arg3 |
public class MultipleArgsExample { public static void main( String[] args ) { String list = "This is a sample String"; list.substring(2, 8); } }
| list | list := 'This is a sample String'. list copyFrom: 2 to: 8
CS 635 Spring 05 | Doc 1, Introduction Slide # 8 |
Transcript show: 'Name: '; show: _name; cr; show: 'Amount: '; show: outstanding; cr.
Is short hand notation for:
Transcript show: 'Name: '. Transcript show: _name. Transcript cr. Transcript show: 'Amount: '. Transcript show: outstanding. Transcript cr.
CS 635 Spring 05 | Doc 1, Introduction Slide # 9 |
Strength of interaction between objects in system
Degree to which the tasks performed by a single module are functionally related
CS 635 Spring 05 | Doc 1, Introduction Slide # 10 |
What is a Pattern?
"Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice"
"Each pattern is a three-part rule, which expresses a relation between a certain context, a problem, and a solution"
"Patterns are not a complete design method; they capture important practices of existing methods and practices uncodified by conventional methods"
CS 635 Spring 05 | Doc 1, Introduction Slide # 11 |
Waiting for doctor, airplane etc. requires spending time hanging around doing nothing
Cannot enjoy the time since you do not know when you must leave
Classic "waiting room"
Fundamental problem
Fuse the waiting with other activity that keeps them in earshot
Allow the person to become still meditative
CS 635 Spring 05 | Doc 1, Introduction Slide # 12 |
Therefore:
"In places where people end up waiting create a situation which makes the waiting positive. Fuse the waiting with some other activity - newspaper, coffee, pool tables, horseshoes; something which draws people in who are not simple waiting. And also the opposite: make a place which can draw a person waiting into a reverie; quiet; a positive silence"
CS 635 Spring 05 | Doc 1, Introduction Slide # 13 |
Two concepts are each a prerequisite of the other
To understand A one must understand B
To understand B one must understand A
A "chicken and egg" situation
First explain A then B
Simplify each concept to the point of incorrectness to explain the other one
Explain A & B correctly by superficially
Iterate your explanations with more detail in each iteration
CS 635 Spring 05 | Doc 1, Introduction Slide # 14 |
By providing domain expertise patterns
Patterns reduce time to design applications
Patterns reduce the time needed to understand a design
CS 635 Spring 05 | Doc 1, Introduction Slide # 15 |
Alexander - Originated pattern literature
GOF (Gang of Four) - Style used in Design Patterns text
Portland Form -Form used in on-line Portland Pattern Repository
Coplien
CS 635 Spring 05 | Doc 1, Introduction Slide # 16 |
Program to an interface, not an implementation
Use abstract classes (and/or interfaces in Java) to define common interfaces for a set of classes
Declare variables to be instances of the abstract class not instances of particular classes
Client classes/objects remain unaware of the classes of objects they use, as long as the objects adhere to the interface the client expects
Client classes/objects remain unaware of the classes that implement these objects. Clients only know about the abstract classes (or interfaces) that define the interface.
CS 635 Spring 05 | Doc 1, Introduction Slide # 17 |
Collection students = new XXX; students.add( aStudent);
students can be any collection type
We can change our mind on what type to use
CS 635 Spring 05 | Doc 1, Introduction Slide # 18 |
Favor object composition over class inheritance
Composition
class A { Foo x public int complexOperation() { blah } } class B extends A { public void bar() { blah} }
class B { A myA; public int complexOperation() { return myA.complexOperation() } public void bar() { blah} }
CS 635 Spring 05 | Doc 1, Introduction Slide # 19 |
Generics in Ada, Eiffel, Java (jdk 1.5)
Templates in C++
Allows you to make a type as a parameter to a method or class
template <class TypeX> TypeX min( TypeX a, Type b ) { return a < b ? a : b; }
Parameterized types give a third way to compose behavior in an object-oriented system
CS 635 Spring 05 | Doc 1, Introduction Slide # 20 |
Some common design problems that GoF patterns that address
• Creating an object by specifying a class explicitly
Abstract factory, Factory Method, Prototype
Chain of Responsibility, Command
Abstract factory, Bridge
Abstract factory, Bridge, Memento, Proxy
Builder, Iterator, Strategy, Template Method, Visitor
Abstract factory, Bridge, Chain of Responsibility, Command, Facade, Mediator, Observer
Bridge, Chain of Responsibility, Composite, Decorator, Observer, Strategy
Adapter, Decorator, Visitor
CS 635 Spring 05 | Doc 1, Introduction Slide # 21 |
We have code that looks like:
at: anInteger put: anObject (smallKey ~= largeKey) ifTrue: [(anInteger < smallKey) ifTrue: [self atLeftTree: anInteger put: anObject] ifFalse: [(smallKey = anInteger) ifTrue: [smallValue := anObject] ifFalse: [(anInteger < largeKey) ifTrue: [self atMiddleTree: anInteger put: anObject] ifFalse: [(largeKey = anInteger) ifTrue: [largeValue := anObject] ifFalse: [(largeKey < anInteger) ifTrue: [self atRightTree: anInteger put: anObject]]]]]] ifFalse:
[self addNewKey: anInteger with: anObject].
Now what?
CS 635 Spring 05 | Doc 1, Introduction Slide # 22 |
In inner cities some buildings are:
Clean inhabited buildings can quickly become abandoned derelicts
The trigger mechanism is:
If one broken window is left unrepaired for a length of time
CS 635 Spring 05 | Doc 1, Introduction Slide # 23 |
A visitor to an Irish castle asked the groundskeeper the secret of the beautiful lawn at the castle
The answer was:
Spending a little time frequently
So frequently spend time cleaning your code
CS 635 Spring 05 | Doc 1, Introduction Slide # 24 |
Why don't more programmers/companies continually:
Familiarity is always more powerful than comfort.
-- Virginia Satir
CS 635 Spring 05 | Doc 1, Introduction Slide # 25 |
Refactoring is the modifying existing code without adding functionality
Changing existing code is dangerous
To avoid breaking code while refactoring:
CS 635 Spring 05 | Doc 1, Introduction Slide # 26 |
You have a code fragment that can be grouped together.
Turn the fragment into a method whose name explains the purpose of the method
Short methods:
CS 635 Spring 05 | Doc 1, Introduction Slide # 27 |
CS 635 Spring 05 | Doc 1, Introduction Slide # 28 |
CS 635 Spring 05 | Doc 1, Introduction Slide # 29 |
Note I will use Fowler's convention of starting instance variables with "_".
printOwing | outstanding | outstanding := 0.0. Transcript show: '********************'; cr; show: '***Customer Owes***'; cr; show: '********************'; cr. outstanding := _orders inject: 0 into: [:sum :each | sum + each]. Transcript show: 'Name: '; show: _name; cr; show: 'Amount: '; show: outstanding; cr.
CS 635 Spring 05 | Doc 1, Introduction Slide # 30 |
Extracting the banner code we get:
printOwing | outstanding | outstanding := 0.0. self printBanner. outstanding := _orders inject: 0 into: [:sum :each | sum + each]. Transcript show: 'Name: '; show: _name; cr; show: 'Amount: '; show: outstanding; cr.
printBanner Transcript show: '********************'; cr; show: '***Customer Owes***'; cr; show: '********************'; cr
CS 635 Spring 05 | Doc 1, Introduction Slide # 31 |
We can extract printDetails: to get
printOwing | outstanding | self printBanner. outstanding := _orders inject: 0 into: [:sum :each | sum + each]. self printDetails: outstanding
printDetails: aNumber Transcript show: 'Name: '; show: _name; cr; show: 'Amount: '; show: aNumber; cr.
Then we can extract outstanding to get:
printOwing self printBanner; printDetails: (self outstanding)
outstanding ^_orders inject: 0 into: [:sum :each | sum + each]
The text stops here, but the code could use more work
CS 635 Spring 05 | Doc 1, Introduction Slide # 32 |
Using Add Parameter (275)
printBanner Transcript show: '********************'; cr; show: '***Customer Owes***'; cr; show: '********************'; cr
becomes:
printBannerOn: aStream aStream show: '********************'; cr; show: '***Customer Owes***'; cr; show: '********************'; cr
Similarly we do printDetails and printOwing
printOwingOn: aStream self printBannerOn: aStream. self printDetails: (self outstanding) on: aStream
Perhaps this should be called
Replace Constant with Parameter
CS 635 Spring 05 | Doc 1, Introduction Slide # 33 |
[1] Alexander 1977, pp. 707-711
[2] Anthony 1996
[3] Pragmatic Programmer, pp. 4-5
[4] Refactoring Text, pp. 110-116
[5] Example code is Squeak version of Fowler's Java example
Copyright ©, All rights reserved.
2005 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
OpenContent license defines the copyright on this document.