Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "ECE452/CS446/SE464 Design Patterns: Part I Answers A Tutorial by Peter Kim Based on slides prepared by Krzysztof Pietroszek."— Presentation transcript:

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

2 Problem 1 public 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

3 Answer 1a): Observer (behavioural) design pattern 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)

4 Answer 1b) p:Person gui:GUI :Program p := 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

5 Problem 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.

6 Answer 2 ● Composite Pattern

7 Problem 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); … }

8 Answer 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)); … }

9 Problem 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.

10 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); }

11 Problem 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.

12 Answer 5a) Component FrameableScrollableResizable 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 Frameable Scrollable Frameable Resizable Scrollable Resizable FrameableScrollable Resizable 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 FrameableScrollableResizable f: Frameables: Scrollabler: Resizable3 choose 1 3 choose 2fs: Frameablefr: Frameablesr: Scrollable fsr: Frameable3 choose 3 Objects are composed from right to left. E.g. fs means that s:Scrollable is composed by f:Frameable ComponentDecoratorWindow 1 1

13 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 FrameableScrollableResizable ComponentDecorator 1 1 paint(): void dispose(): 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.


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

Similar presentations


Ads by Google