94
Lecture 02 Software Design

L02 Software Design

Embed Size (px)

DESCRIPTION

Object Oriented Programming is revisited. It is assumed that students know OO languages so this is more of a review. We will cover concepts such as encapsulation, interfaces and polymorphism. These are important concepts that students must understand in order to write flexible and lasting code. We look at several design principles. We also look at software design and take an example from a video games. In this lecture we will also reveal the secret of programming which all good programmers must know.

Citation preview

Page 1: L02 Software Design

Lecture 02Software Design

Page 2: L02 Software Design

Agenda Programming with Objects

– Classes– Interfaces– Generic programming– Reflection

Software Design– Ducks…

Page 3: L02 Software Design

Reading Don’t Repeat Yourself Polymorphism Separation of concerns Loose coupling Optional:

– http://docs.oracle.com/javase/tutorial/

Page 4: L02 Software Design

Programming with Objects

Page 5: L02 Software Design

Object Oriented Programming Object Oriented programming can be powerful

– One of the best ways for general purpose computing

But– The power of object oriented languages needs to

be used properly!

However– Programmers tend to forget the power of OO

Page 6: L02 Software Design

Object Oriented Programming

Page 7: L02 Software Design

Object Oriented Programming Programming languages with objects

– Objects hold data and methods– Object variables (reference) point to objects

Object Oriented – Object are instances of classes, created with

new– Classes describe the objects– Classes extend other classes – inheritance– Instance variables are encapsulated– Methods manipulate instance variable

Page 8: L02 Software Design

Explain these concepts and why they are important in programmingEncapsulationInterfacesPolymorphism

EXERCISE

Page 9: L02 Software Design

Think About This! Object-oriented programming

– Is not about class inheritance and creating advanced class diagrams

Remember– Encapsulation – Hiding data– Interfaces – Hiding implementation– Polymorphism – Flexible and Generic Programming

Powerful programming– Separation of concerns– Separating what varies from what stays the same

Page 10: L02 Software Design

Think About This! Object-oriented programming

– Is not about class inheritance and creating advanced class diagrams

Remember– Encapsulation – Hiding data– Interfaces – Hiding implementation– Polymorphism – Flexible and Generic Programming

Powerful programming– Separation of concerns– Separating what varies from what stays the same

Page 11: L02 Software Design

Separate Variations Design Principle

Identify the aspects of your application that vary and separate them from what stays the same

Page 12: L02 Software Design

Don’t Repeat Yourself – DRY Single source of truth

Every piece of knowledge must have a single, unambiguous, authoritative representation within a system

Page 13: L02 Software Design

Object Oriented Design Design of classes and interfaces

– Class diagram shows relationships– Sequence diagrams show flows

Design Patterns– Reoccurring solutions in design – “Best practices” – known solutions for common

problems

Page 14: L02 Software Design

Classes

Page 15: L02 Software Design

Objects Object created

Object used

Date day1; Date day2 = new Date();

System.out.println (new Date ()); String s = new Date().toString ();

day1 null

day2Date

Date now = new Date(); if (day2.before(now)) { System.out.println (day2.toString()); }

beforetostring...

Page 16: L02 Software Design

Objects Operator new creates

memory– String is an exception

Reference variablesalways point to some memory

day1 null

day2Date

beforetostring...

Date d = new Date();

Must be a concrete class

Can be any supertype or interface of the concrete class

Page 17: L02 Software Design

ClassesObject

+getId() : String

-id : int-name : String-username : String-password : String-email : String

User

Classes extend other classes– Concrete Inheritance– Subtype extends supertype

Class contains – Instance variables– Methods

Reference variables of type Object points to any class– Any supertype can reference subtype

Object obj = new User ();User u = (User)obj;

supertype

subtype

Page 18: L02 Software Design

Class methods Methods can be overridden

– Class extends a class and overrides a method Methods can be overloaded

– Same method with different parameters Methods can be

– public – any class can call the method– private – only available within the class– protected – only available within the class and

extended classes

Page 19: L02 Software Design

Class A inherits class B. A overwrites method f. Variable b is created like this:

B b = new A();What happens when this line is run:

b.f();

A) The method in A is runB) The method in B is runC) First the method in B is run, then the method in AD) The new statement is illegal and does not compile

QUIZ

Page 20: L02 Software Design

Classes References

– Point to concrete objects– Must be same type or supertype of concrete

object– Can be interface or abstract classObject obj = new Date ();Date d = (Date)obj;

Page 21: L02 Software Design

Constructors Classes have constructor

– Instantiation methods– Same name as the class

References– this – refers to the class– super – extended class

public Employee (String name, double salary){ this (name); this.salary = salary;}

public Manager (String name){ super (name, 0.0); ... }

Page 22: L02 Software Design

class Point{ private int x, y; public Point () { x = 0; y = 0; } public Point (int x, int y) { this.x = x; this.y = y; } public void move (intdx, intdy) { x+=dx;y+=dy; } public String toString () { return "(" + x + "," + y + ")"; }}

this used to refer to the class variables

Override toString method of Object

Class variablesDefault constructors

Overloaded constructor

Example

Page 23: L02 Software Design

Example

Bla

public class Test{ public static void main (String[] args) { System.out.println ("Test"); Test test = new Test(); } public Test () { Point p0; // null reference Point p1 = new Point (); Point p2 = new Point (1,2);

Object obj = p2; p0 = (Point)obj; p0.move (1, 1); System.out.println("p0=" + p0); }}

C:\java>javac Test.java

C:\java>java TestTestp0=(2,3)

X = 2Y = 3

Page 24: L02 Software Design

Java uses this method to pass objects to methods

A) Call by referenceB) Call by valueC) Call by object referenceD) Call by value reference

QUIZ

Page 25: L02 Software Design

Call By Value Methods use call by value

– Object references are passed by value– The reference cannot change, but the object

can

x:

y:

42

0

Point

void changeReferance(Point p){ while (p.x>0) p.x--;}

p

Point p = new Point (42,0);changeReferance(p);System.out.println(p.x);

Reference p to PointLocal copy of a referencep to Pointp is same as this.p

p

Page 26: L02 Software Design

Inheritance Classes extend other classes

– Subclasses extend superclasses

Reference variables of super types can reference objects of subtypes

Employee

Manager

Empolyee e;e = new Employee(. . .)e = new Manager(. . .)

class Manager extends Employee{ ... }

Polymorphism

Page 27: L02 Software Design

public class Employee{ private String name; private double salary; private Date hireDate;

public Employee() { }

public Employee(String name, double salary, Date hireDate) { this.name = name; this.salary = salary; this.hireDate = hireDate; }

public Employee(String name) { this.name = name; }

Page 28: L02 Software Design

public String getName() { return name; }

public double getSalary() { return salary; }

public void setName(String name) { this.name = name; } public String toString() { return "Employee: " + getName(); }}

Page 29: L02 Software Design

Bla

class Manager extends Employee{ String title; double bonus; public Manager (String name, String title) { super (name); this.title = title; } public String getTitle () { return title; } public double getSalary() { return this.bonus + super.getSalery(); } public String toString () { return "Manager: " + getName() + ", " + getTitle (); }}

New method

New variables

Overridden methods

Page 30: L02 Software Design

What does this program print?public class Test2{ public static void main (String[] args) { System.out.println ("Test2"); Test2 test2 = new Test2(); } public Test2 () { Employee e0 = new Employee ("Dilbert"); Employee e1 = new Manager ("Pointy Haired", "Boss"); System.out.println("e0: " + e0); System.out.println("e1: " + e1); }}

C:\java>java Test2Test2e0: Employee: Dilberte1: Manager: Pointy Haired, Boss

EXERCISE

Page 31: L02 Software Design

Dynamic binding Decision on which method to run is taken

at runtime– The virtual machine uses a method table for

each classManager m = new Manager();m.setName(“P.H. Carl”); // Employee.setNamem.setTitle (“Boss”); // Manager.setTitlem.getSalary (); // Manager.getSalary

Employee e1 = new Manager("Pointy Haired", "Boss");e1.getSalary();

Is this manager salary with bonus?

Page 32: L02 Software Design

What does this program print?public class Test1{ public static void main(String[] args) { System.out.println("Test1"); new Test1(); }

public Test1() { Employee e0 = new Employee ("Dilbert"); Employee e1 = new Manager ("Pointy", "Boss"); System.out.println(e1.getTitle(); }} Trick question!

Does not compile since getTitle is not in Employee

EXERCISE

Page 33: L02 Software Design

Think About This! Why use Concrete Inheritance?

– Powerful implementation approach– Layered Supertype Pattern– Enables polymorphism if supertypes are used – New classes can be added without recompile

But remember– Object oriented programming is not just about

concrete inheritance– It has to be natural!– Class hierarchies are rigid– Not always good to force others to extend

Page 34: L02 Software Design

Abstract Classes Abstract classes put the responsibility of

implementation on subclasses– Classes extending an abstract class must

implement the abstract methods– Can contain both concrete and abstract

methods– Normal classes are concrete classes

Abstract classes cannot be instantiated Reference variables of abstract types are

allowed– Object must be a concrete class

Page 35: L02 Software Design

Abstract Exampleabstract class Person{ private String name; public Person(String name) { this.name = name; } // get and set methods ... public abstract String getDescription ();}class Employee extends Person{ public String getDescription() { return "Employee called " + super.getName(); }}

// Person p1 = new Person (); Does not work!Person p2;Person p3 = new Employee ("Dilbert");System.out.println (p3.getDescription());

Key Concept: Polymorphism

Page 36: L02 Software Design

Interfaces

Page 37: L02 Software Design

Interfaces Interface is a class without

implementation– Declaration of how to implement class– All methods and variables are static final

Classes implement interfaces– implements keyword– Must implement all the methods – or be

abstract

Page 38: L02 Software Design

Interfaces

public interface Comparable{ public int compareTo(Object other);}

class Employee extends Person implements Comparable{ public int compareTo(Object o) { ...

Page 39: L02 Software Design

Examplepublic interface Comparable{ public int compareTo(Object other);}

class Employee extends Person implements Comparable{ public int compareTo(Object o) { Employee e = (Employee)o; return this.getName().compareTo (e.getName()); } ...

Employee[] ale = new Employee[3]; ale[0] = new Employee ("Dilbert"); ale[1] = new Employee ("Wally"); ale[2] = new Employee ("Alice"); Arrays.sort(ale); for (int j=0; j <ale.length; j++) System.out.println(ale[j].getName());

AliceDilbertWally

How is this possible?

Page 40: L02 Software Design

Think About This! Class A calls class B -> A depends on B Class java.util.Arrays calls the

Employee.compareTo method Does Arrays depend on Employee?

Polymorphism

Separated interface

Page 41: L02 Software Design

Many Faces Arrays looks at the class as Comparable,

while we regard it as Employee

Class Employee implements Comparable{ ... compare

Class Arrays... sort(Object[] { Comparable c ...

Test...

Arrays.sort(persons

Arrays does NOT call Employee.compareTo, it calls Comaparable.compareTo which happens to be Employee Polymorphism

Page 42: L02 Software Design

Objects

class Employee extends Person

abstract class Person implements Comparable

class Manager extends Employee

Object o = new Manager()Person p = new Manager()Comparable c = new Manager()Employee e = new Manager()Manager m = new Manager()

Memory for Manager

reference

Must be concrete class

Can be any supertype

Page 43: L02 Software Design

Using Interfaces Interfaces cannot be instantiated

– Variables of interface types can reference objects that implement the interface

Interface can extend interfacespublic interface Powered extends Movable{ double milesPerGallon(); double SPEED_LIMIT = 95;}

Comarable c = new Comparable (); // NO!!!Comarable c = new Employee (); // OK!

Page 44: L02 Software Design

Why interfaces? Why not use abstract classes?

– Only one class can be extended– Class hierarchies are rigid and not always

suitable Interfaces can improve software design

– Provide abstraction – hide the implementation

– Classes that use interfaces are not dependant on a particular implementation

class Employee extends Person implements Comparable{ ...

Page 45: L02 Software Design

Example Pattern Table Data Gateway or Data Access Object

provide an interface to database table– Decision on what database access methods to

use can be configured

Example

public interface TeamDAO extends RuDAO{ public void addTeam (Team team); public Collection getTeams ();}

Inte

rface

ImplementationClientcode

Page 46: L02 Software Design

Example: Drawing systempublic interface Drawable{ public void draw ();}

public class Rectangle extends Shape{ private int h, w; public Rectangle (int x, int y, int h, int w) { this.x=x; this.y=y; this.h=h; this.w=w; } public void draw () { System.out.println ("Rectange (x="+x+",y="+y+",h="+h+",w="+w+")"); }}

public abstract class Shape implements Drawable{ protected int x,y;}

public class Circle extends Shape{ private int r; public Circle(int x, int y, int r) { this.x = x; this.y = y; this.r = r; } public void draw() { System.out.println ("Circle (x="+x+",y="+y+",r="+r+")"); }}

Page 47: L02 Software Design

Example: Drawing system Drawing all objects

– All draw objects implement Drawable

public DrawTest() { List<Drawable> l = new ArrayList<Drawable>();

l.add(new Rectangle(1, 1, 1, 1)); l.add(new Circle(2, 1, 1)); l.add(new Rectangle(8, 4, 1, 1));

for (Drawable d: l) { d.draw(); } }

Rectange (x=1,y=1,h=1,w=1)Circle (x=2,y=1,r=1)Rectange (x=8,y=4,h=1,w=1)

Page 48: L02 Software Design

Think About This! All drawing objects in this Layer extend Shape

Shape is abstract and implements Drawable

Client code does not know about the classes that implement Drawable

Shape is Layered Supertype

Shape is Template Method

Generic Programming

Page 49: L02 Software Design

X extends Y. Which is true? A) Correct if and only if X is a class and Y is an interfaceB) Correct if and only if X is an interface and Y is a classC) Correct if X and Y are either both classes or both interfacesD) Correct for all combinations of X and Y being classes and/or interfaces.

QUIZ

Page 50: L02 Software Design

Generic Programming

Page 51: L02 Software Design

Generic Programming Programming in an data type independent

way– Same code is used regardless of the data type

Example– Sort can be applied to any data type– Generic collection

• Java Collection Framework

Design Principle– Always use the most generic data type

possible

Page 52: L02 Software Design

Generic Programming All classes extend Object

– Allows generic algorithms and data structuresstatic int find (Object[] a, Object key){ int i; for (i=0;i<a.length;i++) if (a[i].equals(key)) return i; return -1;}

Employee[] staff = new Employee[10];Employee e1 = new Employee("Dilbert");

staff[x] = e1;int n = find(staff, e1);

Page 53: L02 Software Design

Generic Programming Generic collections

– ArrayList is an example class that uses Object ArrayList al = new ArrayList();

al.add (new Employee ("Dilbert")); al.add (new Employee ("Wally")); al.add (new Employee ("Alice"));

Iterator i = al.iterator(); Employee e; while (i.hasNext()) { e = (Employee)i.next(); System.out.println(e.getName()); }

DilbertWallyAlice

Page 54: L02 Software Design

Generic Programming Generic collections

– The Collections class is another exampleList<Employee> list = new ArrayList<Employee>();

list.add (new Employee ("Dilbert"));list.add (new Employee ("Wally"));list.add (new Employee ("Alice"));

Collections.sort(list);for (Employee e: list){ System.out.println(e);}

AliceDilbertWally

Page 55: L02 Software Design

Reflection

Page 56: L02 Software Design

Reflection Reflection allows examination and manipulation

of objects at runtime– Get information about a class

• Fields, methods, constructors, and super classes• Constants and method declarations belong to an interface

– Create an instance of a class whose name is not known until runtime

– Get and set the value of an object's field, even if the field name is unknown to your program until runtime

– Invoke a method on an object, even if the method is not known until runtime

Page 57: L02 Software Design

Reflectionstatic void showMethods(Object o){ Class c = o.getClass(); Method[] theMethods = c.getMethods(); for (int i = 0; i < theMethods.length; i++) { String methodString = theMethods[i].getName(); System.out.println("Name: " + methodString); String returnString = theMethods[i].getReturnType().getName(); System.out.println(" Return Type: " + returnString); Class[] parameterTypes = theMethods[i].getParameterTypes(); System.out.print(" Parameter Types:"); for (int k = 0; k < parameterTypes.length; k ++) { String parameterString = parameterTypes[k].getName(); System.out.print(" " + parameterString); } System.out.println(); } } }

Page 58: L02 Software Design

Reflection

Bla

public class ReflectMethods{ public static void main(String[] args) { Polygon p = new Polygon(); showMethods(p); } Name: getBoundingBox

Return Type: java.awt.Rectangle Parameter Types:Name: contains Return Type: boolean Parameter Types: java.awt.geom.Point2D...Name: toString Return Type: java.lang.String Parameter Types:

Page 59: L02 Software Design

Reflection Reflection is very useful in frameworks

– Infrastructure code– “plumbing” – The “Noise”

Examples– Create Java objects from XML descriptions– Load classes at runtime and invoke methods– Tools and utilities for development

Page 60: L02 Software Design

Dynamically Loading Classes Classes can be dynamically loaded at

runtime– Offers the flexibility to decide which class to

run dynamically– Class names can be specified in configuration

files Class class

Class instanceClass = Class.forName("RssFeedReader"); reader = (FeedReader)instanceClass.newInstance();

Page 61: L02 Software Design

A) BDB) DBC) BDCD) Compilation fails

QUIZ

class Top { public Top(String s) { System.out.print("B"); } }public class Bottom2 extends Top { public Bottom2(String s) { System.out.print("D"); } public static void main(String [] args) { new Bottom2("C"); System.out.println(" "); } }

Page 62: L02 Software Design

Software Design

Page 63: L02 Software Design

Object Oriented Design Design and implementation of software

needs to be of quality– Badly designed, well implemented = problem!– Well designed, badly implemented = problem!

CODEHORROR!!

CODE HORROR DUDE

Page 64: L02 Software Design

Object Oriented Design Good design

Is based on OO principles

Abstracts complex APIs such as J2EE

Is flexible and can be changed

Contains loosely coupled components

Page 65: L02 Software Design
Page 66: L02 Software Design

Example from Head First Design Patterns

Page 67: L02 Software Design

Getting Started SimUDuck is highly successful duck pond

simulation game Original design

Page 68: L02 Software Design

Change Request But now we need the ducks to FLY

Page 69: L02 Software Design

Problem! But not all duck fly – We forgot Rubber

Duck!

Page 70: L02 Software Design

How can we fix this? Just override fly and quack to do nothing

Page 71: L02 Software Design

We even think ahead We fix all non-flyable and non-quackable

ducks as wellCode smell!

Page 72: L02 Software Design

Which of the following are disadvantages of using inheritance to provide Duck behavior?

A) Code is duplicated across subclassesB) Runtime behavior changes are difficultC) We can’t make ducks danceD) Hard to gain knowledge of all duck behaviorsE) Ducks can’t fly and quack at the same timeF) Changes can unitentionally affect other ducks

QUIZ

✔✔

Page 73: L02 Software Design

The Problem The problem is this

– Derived classes (RubberDuck) are forced to inherit behaviour they don’t have

– Derived classes (RubberDuck) needs to be exposed to the inner workings of the superclass (Duck)

– Users of the base class (Duck) should expect same functionality

– Violation of the Liskov Substitution Principle

Page 74: L02 Software Design

Trying to fix the Problem Let’s try using interfaces

– Flyable and Quackable Code duplication!

Page 75: L02 Software Design

What is the Problem? We tried this

– Inheritance changes all subcasses– Interfaces cause code duplication

The problem is we are mixing different types of code in one type of classes

Fix– Separate Variation Design Principle– Take what varies and encapsulate it so it

wont affect the rest of the code

Page 76: L02 Software Design

Separate Variations Design Principle

Identify the aspects of your application that vary and separate them from what stays the same

Page 77: L02 Software Design

Separation of Concerns Separate what changes from what stays

the same– Move duck behavior to a separte classes

FlyWithWings flyBehavior = new FlyWithWings();DATA TYPE IS TOO SPECIFIC

Page 78: L02 Software Design

Separation of Concerns But the Duck classes cannot use the

concrete behavior classes! – We need an interface or supertype

FlyBehavior flyBehavior = new FlyWithWings();

INTERFACE - POLYMORPHISIM

Page 79: L02 Software Design

The Interface Design Principle

Program to an interface, not an implementation

Page 80: L02 Software Design

Loose Coupling with Interfaces Advantages

– The ability to change the implementing class of any application object without affecting calling code

– Total freedom in implementing interfaces– The ability to provide simple test

implementations and stub implementations of application interfaces as necessary

Page 81: L02 Software Design

Program to an interfacesProgram to an implementation

Program to interface/subtype

Program to unknown creation

Dog d = new Dog();d.bark();

Animal animal = new Dog();animal.makeSound();

Animal animal = getAnimal();animal.makeSound();

Page 82: L02 Software Design

Program to an interfacesDependency Injection– Make the caller responsible for setting the

dependencyprivate Animal animal;

public setAnimal(Animal animal){ this.animal = animal;}...

animal.makeSound();

Injection happens here, in the set-method

LOOSE COUPLING = BEAUTIFUL!

Page 83: L02 Software Design

Implementing Behavior We can add new behaviors without

touching the Duck classes

Page 84: L02 Software Design

Integrating the Behavior The Duck classes will now delegate its

flying and quacking behavior

Behavior interfaces

Perform the Bahavior

Page 85: L02 Software Design

Integrating the Behavior Using the behavior

public class Duck { QuackBehavior quackBehavior; ...

public void performQuack() { quackBehavior.performQuack() }

}

We don’t care what kind of object this is, all we care is that it knows how to

quack!

Page 86: L02 Software Design

Integrating the Behavior Setting the behavior

public class MallardDuck extends Duck { public MallardDuck() { quackBehavior = new Quack(); flyBehavior = new FlyWithWings(); }

}

This is not programming to an interface!

Page 87: L02 Software Design

Setting Behavior Dynamically Add two new methods to the Duck class Dependency Injection

public void setFlyBehavior(FlyBehavior flyBehavior){ this.flyBehavior = flyBehavior}

public void setQuackBehavior(QuackBehavior quackBehavior){ this.quackBehavior = quackBehavior}

DuckFactory{ public Duck getMallardDuck() { Duck duck = new MallardDuck() duck.setFlyBehavior(new FlyWithWings()); duck.setQuackBehavior(new Quack()); return duck; }}

Page 88: L02 Software Design

Setting Behavior Dynamically The idea

– Don´t think: Mallard is-a flying duck, think: it has-a flying behavior

– Putting two classes together where one is a member in the other is a composition

Creating systems using composition give flexibilty– You can change the behavior at runtime

Page 89: L02 Software Design

Composition Design Principle

Favor composition over inheritance

Page 90: L02 Software Design

Object Composition Problems with concrete inheritance

– Class hierarchy can get rigid– Difficult to change the implementation

Object Composition is more flexible – Allows the behaviour of an object to be altered

at run time, through delegating part of its behaviour to an interface and allowing callers to set the implementation of that interface

Page 91: L02 Software Design

Summary OO Programming is powerful

– If used correctly– Remember Encapsulation, Interfaces,

Polymorphism Generic programming

– Using classes, abstract classes and interfaces can lead to powerful and flexible programs

Reflection– Powerful for building infrastructure

Page 92: L02 Software Design

Job interview question

You are given the assignment of creating a component that needs to know sales statistics of Lottery tickets. You know that there is a another component in the system, Sale Server, that handles the sale. You need real-time information. What would you suggest?

EXERCISE

Page 93: L02 Software Design

Design Patterns Design pattern is a general solution to a common

problem in software design– Systematic approach for problems that reoccur in

software development– Not complete solution but starting point for design – Not code ready to use– Patterns have names and definitions– Built on common practices

Patterns should not be language dependant– However patterns apply for types of programming

languages

Page 94: L02 Software Design

Next Design Patterns