Thursday, February 22, 2007

2/22 - Patterns & Frameworks

Patterns

+ first used - Christopher Alexander, 1972 "A Pattern Language"
+ 250 patterns for arch. design

Motivation for Patterns & Frameworks
+ developing software is hard
+ developing reusable software is even harder

Proven solutions include Patterns & Frameworks

Patterns: support reuse of software architecture and design
capture static and dynamic structure and collaboration of successful solutions to problems that arise when building applications in a particular domain

Frameworks: support reuse of detailed design code
a framework is an integrated set of components that collaborate to provide a reusable architecture for a family of related applications


Becoming a Chess Master

(i) learn the rules, e.g. names of pieces, legal movements, where pieces belong on the chessboard
(ii) learn the principles, e.g. relative values of pieces, strategic value of center squares, etc.
(iii) study the game of chess masters:
-patterns of the game, e.g. opening the game, final moves, etc.
(100s of patterns)





Becoming a Software Design Master

(i) learn the rules, e.g. algorithms, data structures, programming languages
(ii) learn the principles, e.g structured programming, modular, OOP, etc.
(iii) study the design of other masters
-these designs contain patterns
- these patterns must be understood and applied in your work

In software engineering, we seem to be making the same mistakes over and over again

design patterns are solutions to problems that arise when developing software in a particular context

PATTERN == problem & solution pair in a context

Design Pattern Descriptions
(i) name and intent
(ii) problems and context
(iii) forces addressed
(iv) abstract description of structure and collaborations in solution
(v) positive and negative consequences of use

(vi) implementation guidelines and sample code
(vii) known uses and related patterns

(some include anti-patterns, i.e. when NOT do use something)


Design Pattern Space
1. Creational patterns - deal with initializing and configuring classes and objects
e.g. factory method, abstract factory, singleton, prototype, etc.
2. structural patterns- deal with decoupling interface and implementation of classes and objects
e.g. adapter, decorator, etc.
3. Behavioral patterns - deal with dynamic interactions among societies of classes and objects
e.g. observer, iterator, etc.

NOTE: these patterns are language independent

Examples of Design Patterns

Pattern: Encapsulation (data hiding)
Problem: exposed data members can be manipulated directly (and inappropriately)
Solution: hide some members, allow access only through methods
Disadvantages: the interface may not provide all desired operation. can be inefficient (extra overhead)

Example Code
class Cup {
float fluidAmt;
float cupCapacity;

//other methods

}

Cup myCup = new Cup(12);
myCup.fluidAmt = 32;

//the cup cannot take more than 12 fluid ounces!!

/********************************/

class Cup {
private float fluidAmt;
private float cupCapacity;
void addFluid(float amt){
//code
}
}
Cup myCup = new Cup(12);
myCup.addFluid(32);
//methods enforce some logic

Pattern: Subclassing (Inheritance)
Problem: similar abstractions have similar members (data and methods); repeating them is tedious, prone to error and hard to maintain
Solution: inherit default members from the superclass; select the correct implementation via run-time dispatching
Disadvantages: code for class is spread out between parent class and subclasses (can make it easier to follow), run-time dispatching introduces overhead

Note: in Java, everything is a subclass of Object
beware very deep inheritance trees because they are expensive at execution time
when you create in inheritance of child all constructors in the inheritance tree will be executed, all the way up to Object


Pattern: Exceptions
Problem: errors occurring in the code are often handled elsewhere. Code should not be cluttered with error-handling code
Solution: introduce language structure for throwing and catching exceptions
Disadvantage: it's still hard at times to know where the exception will be handled (in particular if it's not done locally). programmer's may be tempted to use exception to control program flow (inefficient)

When (not) to Use Patterns

Same rule as for optimization: delay.
Don't try to force patterns into your code.

Creational Patterns

factories
example: write class to represent a bicycle race. a race consists of multiple bicycles

class Race {
Race createRace() {
Frame frame1 = new Frame();
Wheel front1 = new Wheel();
Wheel rear1 = new Wheel();
Bicycle bike1 = new Bicycle(frame1,front1,rear1);
Frame frame2 = new Frame();
Wheel front2 = new Wheel();
Wheel rear2 = new Wheel();
Bicycle bike2 = new Bicycle(frame2,front2,rear2);
// and so on
}
}

Specialize Race for other bicycle races:

class TourDeFrance extends Race {
Race createRace() {
France game1 = new RacingFrance();
Wheel front1 = new Wheel1700c();
Wheel rear1 = new Wheel1700c();
Bicycle bike1 = new Bicycle(frame1, front1,rear1);
// and so on
}
}

class Cyclocross extends Race {
Race createRace() {
Frame frame1 = new MountainFrance();
Wheel front1 = new Wheel27in();
Wheel rear1 = new Wheel27in();
Bicycle bike1 = new Bicycle(frame1, front1, rear1);
//and so on
}

}


This is TEDIOUS since we could not re-use the Race.createRace() method.

A factory method is a method that "manufactures" objects of a particular type.

We can add factory methods to Race.


//
Factory methods are in bold
class Race {
Frame createFrame() {
return new Frame();
}
Wheel createWheel() {
return new Wheel() ;
}
Bicycle createBicycle(Frame frame, Wheel front, Wheel rear) {
return new Bicycle(frame, front, rear);
}
//return a complete bicycle without needing any arguments

Bicycle completeBicycle(){
Frame frame = createFrame();
Wheel front = createWheel();
Wheel rear = createWheel();
return createBicycle(frame, front, rear);
}
Race createRace() {
Bicycle bike1 = completeBicycle();
Bicycle bike2 = complete Bicycle();
}
}


class TourDeFrance extends Race {
France createFrance() {
return new RacingFrame();
}
Wheel createWheel() {
return new Wheel1700c();
}
Bicycle createBicycle(Frame frame, Wheel front, Wheel rear) {
return new RacingBicycle();
}
}

class Cyclocross extends Race {
Frame createFrame() {
return new MountainFrame();
}
Wheel createWheel() {
return new Wheel27in();
}
Bicycle createBicycle(France france, Wheel front, wheel rear) {
return new MountainBicycle(frame, front, rear);
}
}

A factory object is an object that encapsulates factory methods

class BicycleFactory {
Frame createFrame() {
return new Frame();
}
Wheel createWheel() {
return new Wheel();
}
Bicycle createBicycle(Frame frame, Wheel front, Wheel rear) {
return new Bicycle(frame, front, rear);
}
Bicycle completeBicycle() {
Frame frame = creatveFrame();
Wheel front = createWheel();
Wheel rear = createWheel();
return createBicycle(frame,front,rear);
}
}

class RacingBicycleFactory {
Frame createFrame() {
return new RacingFrame();
}
Wheel createWheel() {
return new Wheel1700c();
}
Bicycle createBicycle(Frame frame, Wheel front, Wheel rear) {
return new RacingBicycle(frame, front, rear);
}
}

// do same for cyclecross factory Object

The Race methods will use the factory Objects.

class Race {
BicycleFactory bfactory;
Race() {
bfactory = new BicycleFactory();
}
Race createRace() {
Bicycle bike1 = bfactory.completeBicycle();
Bicycle bike2 = bfactory.completeBicycle();
//and so on
}
}

class TourDeFrance extends Race {
//constructor
TourDeFrance() {
bfactory = new RacingBicycleFactory();
}
}

class Cyclocross extends Race {
Cyclocross() {
bfactory = new MountainBicycleFactory();
}
}

Problem with latest code: the type of bike is still hard-coded in the race.
This can be made more flexible by changing the way we call constuctor.

class Race {
BicycleFactory bfactory;
//constuctor
Race (BicycleFactory bfactory) {
this.bfactory = bfactory;
}
Race createRace() {
Bicycle bike1 = bfactory.completeBicycle();
Bicycle bike2 = bfactory.completeBicycle();
}

class TourDeFrance extends Race {
TourDeFrance(BicycleFactory bfactory) {
this.bfactory = bfactory;
}
}

Now you can control the type of race and the variety of bicycle:

new TourDeFrance(new racingBicycleFactory());

One reason that factory methods are required is a weakness in Java constructors .
Constructors cannot return an object of a subtype ( a different type), even though semantically it would be correct.

Take home:
(i) What is the criticism against patterns?
(ii) What is the "Big Ball of Mud" ? Is this in any way related to patterns?


Applying patterns requires good familiarity with a programing language (lots of experience). So focus you time on your project.








Thursday, February 8, 2007

2/8 - More UML (use cases, conceptual, state chart diagrams, sequence diagrams



aggregation - an association in which an object is part of a whole

composition - a strong association in which the parts can belong to only one whole


visibility and scope

a constraint is a condition that every implementation of the design must satisfy

sequence diagram
+ class and object diagram are static model views
+ interaction diagrams are dynamic; they describe how objects collaborate
+ a sequence diagram is an interaction diagram that details how operations are carried out, i.e. what messages are being sent and in what sequence

state chart diagram
+ shows the possible sates of the object and the conditions that cause a transition from a state to another



the beauty of OOP - you design for the interface of a class, NOT an implementation

ask questions of your client; "what do you want in this situation?"



***********************photos of diagrams from lecture notes














2/1 - Review of OOP & Intro to UML + extra credit opp.

Review of the key concepts of object-oriented programming

1) Abstraction - refine away unnecessary details

2) Encapsulation - data and representations are combined in a single entity, an object (user-defined type)

3) Inheritance - create specialized objects from simpler objects (inherit dat and operations from parent and add specific data and operations)

4) Polymorphism - ability to dynamically interchange modules without affecting clients




UML

UML (Unified Modeling Language) is a set of simple graphical notations for describing object-oriented models

+ it's actual uses can from a conceptual tool to a rigorous blueprint
+ goal if UML is independent of the implementation language


9 types of UML diagrams

> use-case diagrams
> class
> object
> sequence
> collaboration
> state chart
> activity
> component
> deployment


Use Cases

A use case is a textual description of major activities that take place in a system.

+ usually 1-2 paragraph description of what a user does
+ unlikely to have thousands
+ example: a 3 year, $30 mill. project for United Airways had 29 use cases

Example use case: "A patient calls the client to schedule an appointment for a yearly checkup. The receptionist finds the earliest available slot in the schedules the appointment for that time slot."

a use case should consider:

main flows - what happens if everything is ok
alternate flows - what happens in special circumstances


Use Case Diagrams



A use case diagram describes what the system does, not how.

+ In the above example, the patient is an actor, a line represents communcation
+ Note that a use case may involve multiple actors or nonhuman actors.
+ Note that an actor represents a role, NOT a specific user or individual.


Image: An example use case diagram








Class Diagrams



Martin Fowler describes three levels of class diagrams:

1) conceptual
+ a way to represent entities in the system
+ very helpful in the conceptual phase of development
+ there may be very little connection between these high level entities and the classes you'll end up writing

2) specification
+ defines what software must do, the information it must hold and the behavior it must exhibit

3) implementation
+ every single painful detail of classes (e.g. access control, return types, etc.)
+ these are a little bit too much for Fowler and Professor Bistriceanu


Fowler's Maxim: "don't be dogmatic" (use whatever level of detail you find useful to the particular project).

modeling relationships

association - If one class must know about an instance of another class to perform its function, then there is an association between the two classes.

aggregation - An association in which one class belongs to a collection

generalization - An inheritance link indicating one class is the parent (i.e. superclass) of the other.

navigability
- Indicates the direction in which an association can be traversed or queried.

multiplicity - Number of possible occurences.


Image: An example class diagram












Extra Credit Opportunities




1) class notes
+ readable
+ commitment to attend all classes
+ make copies for instructor every week

2) special assignment
+ bring w/ for final and attach to your work
+ up to 10-20% boost of final grade

3) class participation
+ helps settle borderline situations

4) submit a problem or more to be included on the midterm or final
+ criteria: non-trival & original