ece452/cs446/se464

13
ECE452/CS446/SE464 ECE452/CS446/SE464 Design Patterns: Part I Answers A Tutorial by Peter Kim Based on slides prepared by Krzysztof Pietroszek

Upload: emilie

Post on 05-Jan-2016

73 views

Category:

Documents


5 download

DESCRIPTION

ECE452/CS446/SE464. Design Patterns: Part I Answers A Tutorial by Peter Kim Based on slides prepared by Krzysztof Pietroszek. Problem 1. public class Person { protected String name; … public String getName() { return name; } public void setName(String name) - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: ECE452/CS446/SE464

ECE452/CS446/SE464ECE452/CS446/SE464

Design Patterns: Part IAnswers

A Tutorial by Peter Kim

Based on slides prepared by Krzysztof Pietroszek

Page 2: ECE452/CS446/SE464

Problem 1Problem 1public class GUI { … public void setPerson(Person person) {

nameLabel.setText(person.getName());ageLabel.setText(person.getAge());

}}

public class Person{ protected String name; …

public String getName() { return name; }

public void setName(String name) { this.name = name; }

public int getAge() {…} public void setAge(int age) {…}}

To display Person on GUI, GUI.setPerson(Person) must be invoked explicitly. What design pattern could be used so that changes to Person are more implicitly and “automatically” reflected in GUI and potentially in other classes that are interested in Person? Show a) the design pattern and b) an interaction diagram demonstrating a change in Person

Page 3: ECE452/CS446/SE464

Answer 1a): Observer (behavioural) design Answer 1a): Observer (behavioural) design patternpattern

Person

+setName(name: String): void+getName(): String+setAge(age: int): void+getAge(): int

-name: String-age: int

GUI

+GUI(person: Person): GUI+update(): void

-nameLabel: Label-ageLabel: Label

*1

{ this.person = person; this.person.attach(this); }

{ nameLabel = person.getName(); ageLabel = person.getAge().toString(); }{ this.age = age;

notify(); }{ this.name = name; notify(); }

•What’s the problem between Observer.update() and Subject.getState() here?

•Granularity of updates (e.g. age updated even though only name was changed)

Page 4: ECE452/CS446/SE464

Answer 1b)Answer 1b)

p:Person

gui:GUI

:Programp := new Person()

gui := new GUI(p)

attach(gui)

setAge(23)

notify(AGE)update(AGE)

getAge()

Overlapping execution occurrences on the same lifeline are represented by overlapping rectangles

Page 5: ECE452/CS446/SE464

Problem 2Problem 2● Assume that you are implementing a file system. The

main concepts in a file system are directories and files. A directory may contain several files and directories. Additionally, you would like to treat files and directories in a uniform way as nodes, i.e., you would like to be able to write code that can treat both files and directories using the same interface.

➔ What design pattern could you use to achieve these goals?

➔ Draw a class diagram explaining your design.

Page 6: ECE452/CS446/SE464

Answer 2Answer 2● Composite Pattern

Page 7: ECE452/CS446/SE464

Problem 3: Java API relatedProblem 3: Java API related

What design pattern is java.util.Collections.sort(List, Comparator) method an example of?

Draw a class diagram and draw some sample code.

package java.util;

public interface Comparator{ public int compare (Object arg1, Object arg2); …}

Page 8: ECE452/CS446/SE464

Answer 3: StrategyAnswer 3: Strategy

public class AgeComparator implementsComparator

{

public int compare(Object arg1, arg2)

{

Age a1 = (Age)arg1;

Age a2 = (Age)arg2;

if(a1.getValue() > a1.getValue())

return 1;

else if(a1.getValue() < a2.getValue())

return -1;

return 0;

}

}

Collections.sort(ages, new AgeComparator());

Inside java.util.Collections.sort(.), comparator.compare(Object, Object) is used *somehow*:

void Collections.sort(List list, Comparator comparator)

{

int comparison = comparator.compare(list.get(i), list.get(i+1));

}

Page 9: ECE452/CS446/SE464

Problem 4: Java API relatedProblem 4: Java API related

Consider the following Java I/O streams, where an indentation represents class inheritance (e.g. FileOutputStream extends OutputStream).

OutputStream: the generic output stream.

FileOutputStream: output stream for writing to files.

FilterOutputStream: takes a regular OutputStream as an input and performs some filtering operations on it.

DeflaterOutputStream: performs compression on the input OutputStream.

ZipOutputStream: produces a compressed output of “Zip” format.

GZIPOutputStream: produces a compressed output of “GZIP” format.

What design pattern is evident (hint: FilterOutputStream)? Draw a class diagram and provide a sample code.

Page 10: ECE452/CS446/SE464

Answer 4: Decorator (Structural)Answer 4: Decorator (Structural)public class FilterOutputStream extends OutputStream { /** * The underlying output stream to be filtered. */ protected OutputStream out; /** * Creates an output stream filter built on top of the specified * underlying output stream. */ public FilterOutputStream(OutputStream out) { this.out = out; } public void write(int b) throws IOException { out.write(b); } …}

1

1

public class DeflaterOutputStream extends FilterOutputStream

{

public void write(int b) throws IOException {

bCompressed = compress(b);

super.write(bCompressed);

}

}

Page 11: ECE452/CS446/SE464

Problem 5Problem 5

a) A commonly cited advantage of the Decorator design pattern is that it avoids subclass explosion. Explain this using an example.

b) Commonly cited disadvantages of the Decorator design pattern are that it allows

i) identity crisis and

ii) interface occlusion.

Why are these problems not evident with subclassing? Explain these using an example.

Page 12: ECE452/CS446/SE464

Answer 5a)Answer 5a)Component

Frameable Scrollable Resizable

• N functionalities typically represented in N subclasses

• But representing combinations of N functionalities as subclasses means, for example, {(N choose 1) + (N choose 2) + … + (N choose N) – invalid number of combinations} subclasses

FrameableScrollable

FrameableResizable

ScrollableResizable

FrameableScrollableResizable• Using the Decorator design pattern

• N combinations are represented through, for example, {(N choose 1) + (N choose 2) + … + (N choose N) – invalid number of combinations} objects. However, there are only N classes. Object explosion not as bad as [sub]class explosion as the former is more manageable and much smaller.

Component

Frameable Scrollable Resizable

f: Frameable s: Scrollable r: Resizable3 choose 1

3 choose 2 fs: Frameable fr: Frameable sr: Scrollable

fsr: Frameable3 choose 3

Objects are composed from right to left. E.g. fs means that s:Scrollable is composed by f:Frameable

ComponentDecorator Window1

1

Page 13: ECE452/CS446/SE464

Answer 5b)Answer 5b)

• Identity crisis

• Clients are referencing the undecorated object ‘c’ initially. ‘c’ is decorated with ‘cd’, an instance of ComponentDecorator. Clients must update the reference ‘c’ to ‘cd’. Hard to update all the clients (especially with many scattered object references), e.g. Client1 is not updated.

• With subclassing, there’s only one object so there’s no such problem

• Interface occlusion

• Interface of the component is blocked by the decorator in the sense that the decorator has to explicitly delegate methods to the component

• E.g. If interface of Component class evolves (e.g. dispose() is added), then the implementation of the decorator must also evolve so that the method calls will be delegated to the component (e.g. dispose() calls c.dispose()).

Component

Frameable Scrollable Resizable

ComponentDecorator

1

1

paint(): void

paint(): voiddispose(): void

c.paint();

Client1

Client2

c: Component

cd: ComponentDecorator

Basically, problems arise because there are two objects, whereas with subclassing, there is only one object.