Software Eningeering Lecture 10 Design Patterns 3 Patterns

  • Slides: 41
Download presentation
Software Eningeering Lecture 10 – Design Patterns 3

Software Eningeering Lecture 10 – Design Patterns 3

Patterns covered • Creational – Abstract Factory, Builder, Factory Method, Prototype, Singleton • Structural

Patterns covered • Creational – Abstract Factory, Builder, Factory Method, Prototype, Singleton • Structural – Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy • Behavioral – Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, Visitor

Behavioural patterns • Concerned with algorithms and assignment of responsibilities. – Complex control-flow that’s

Behavioural patterns • Concerned with algorithms and assignment of responsibilities. – Complex control-flow that’s hard to follow at runtime – class: use inheritance to distribute behaviour between classes – object: object composition to, for example, describe how a group of objects should cooperate

Observer – Problem/Applicability • Keep consistency between related objects • You might not know

Observer – Problem/Applicability • Keep consistency between related objects • You might not know beforehand which classes are interested in the state change information

Observer – Solution Subject Observer observers +Update() +Attach(Observer) +Detach(Observer) +Notify() For all o in

Observer – Solution Subject Observer observers +Update() +Attach(Observer) +Detach(Observer) +Notify() For all o in observers { o->Update() } subject Concrete. Subject Concrete. Observer -observer. State -subject. State +Update() +Get. State() +Set. State() observer. State = subject->Get. State() return subject. State

Observer – Example 1. public interface Position. Listener { 2. public void position. Update();

Observer – Example 1. public interface Position. Listener { 2. public void position. Update(); 3. } 4. 5. public abstract class Position. Device { 6. private Vector listeners; 7. public void add. Position. Listener(Position. Listener pl) { 8. listeners. add(pl); 9. } 10. public void remove. Position. Listener(Position. Listener pl) { 11. listeners. remove(pl); 12. } 13. 14. public void dispatch. Position() { 15. Position. Listener pl = null; 16. Enumeration e = listeners. elements(); 17. while (e. has. More. Elements()) { 18. pl = (Position. Listener)e. next. Element(); 19. pl. position. Update(); 20. }}}

Observer – Example 1. public class Push. Position. Device extends Position. Device { 2.

Observer – Example 1. public class Push. Position. Device extends Position. Device { 2. private Coordinate current. Coord; 3. public void set. Position(Coordinate c) { 4. this. current. Coord = c; 5. dispatch. Position(); 6. } 7. 8. public Coordinate get. Position() { 9. return this. current. Coord; 10. } 11. }

Observer - Example 1. public class Position. Observer implements Position. Listener { 2. private

Observer - Example 1. public class Position. Observer implements Position. Listener { 2. private Push. Postion. Device subject; 3. 4. public Position. Observer() { 5. subject = new Push. Position. Device(); 6. subject. add. Position. Listener(this); 7. } 8. 9. public void position. Update() { 10. Coordinate c = subject. get. Position(); 11. // paint position on map 12. } 13. }

Observer - Consequences • Abstract coupling between Subject and Observer • Support for broadcast

Observer - Consequences • Abstract coupling between Subject and Observer • Support for broadcast communication • Unexpected updates

Observer – Implementation Issues • • • Observing more than one subject Who triggers

Observer – Implementation Issues • • • Observing more than one subject Who triggers the update? Dangling references to deleted subjects Notify at the right time The update protocol

State – Problem/Applicability • Imagine you have a system which behaves differently depending on

State – Problem/Applicability • Imagine you have a system which behaves differently depending on which state it is in • Putting the different behaviour in if-else paragraphs might make your code hard to follow, it also makes it hard to change

State-diagram

State-diagram

State – Solution Put the different states in different classes and use a Statepattern

State – Solution Put the different states in different classes and use a Statepattern to let your object alter its behaviour when its internal state changes. Context + Request() State + Handle() state->Handle() Concrete. State. A + Handle() Concrete. State. B + Handle()

State – Example • Example (from the book) – TCP connection – If the

State – Example • Example (from the book) – TCP connection – If the connection is closed we can do an active open and a passive open – If a connection is established we can transmit info and close the connection – …

State – Example • Without State pattern: 1. public class TCPConnection { 2. private

State – Example • Without State pattern: 1. public class TCPConnection { 2. private int state; 3. public TCPConnection() { 4. state =TCP_CLOSED; 5. } 6. 7. public void active. Open() { 8. switch(this. state) { 9. case TCP_CLOSED: 10. // do whatever 11. case TCP_LISTENING: 12. //do something else 13. … 14. } 15. }} • With State pattern: B 1. public class TCPConnection { B 2. private TCPState state; B 3. B 4. public TCPConnection() { B 5. state = new TCPClosed(); B 6. } B 7. B 8. public void active. Open() { B 9 state. active. Open(this); B 10. } B 11. B 12. public void passive. Open() { B 13. state. passive. Open(this); B 14. } B 15. }

State – TCPState // Implements general behaviour for listed methods 1. abstract class TCPState

State – TCPState // Implements general behaviour for listed methods 1. abstract class TCPState { 2. public void active. Open(TCPConnection tcp) {} 3. public void passive. Open(TCPConnection tcp){} 4. public void acknowledge(TCPConnection tcp) {} 5. public void transmit(TCPConnection tcp) {} 6. public void close(TCPConnection tcp) {} 7. . 8. } Implement with or without error handling

State – Example 1. public class TCPClosed extends TCPState { 2. public void active.

State – Example 1. public class TCPClosed extends TCPState { 2. public void active. Open(TCPConnection tcp) { 3. //do stuff 4. tcp. set. State(new TCPEstablished()); 5. } 6. 7. public void passive. Open(TCPConnection tcp) { 8. //do stuff 9. tcp. set. State(new TCPListening()); 10. } 11. } B 1. public class TCPListening extends TCPState { B 2. public void acknowledge(TCPConnection tcp) { B 3. //do stuff B 4. tcp. set. State(new TCPEstablished()); B 5. } B 6. }

State – Consequences • It localizes state-specific behaviour and partitions behaviour for different states

State – Consequences • It localizes state-specific behaviour and partitions behaviour for different states • It makes state transitions explicit

State – Implementation Issues • Who defines state transitions? • Creating and destroying State

State – Implementation Issues • Who defines state transitions? • Creating and destroying State objects

Strategy – Problem/Applicability • When many related classes differ only in their behaviour •

Strategy – Problem/Applicability • When many related classes differ only in their behaviour • When you need different variants of an algorithm • When an algorithm uses data that clients shouldn’t know about • When a class defines many behaviours, and these appear as multiple conditional statements in its operations

Strategy – Solution Put each algorithm in a separate class and use the Strategy

Strategy – Solution Put each algorithm in a separate class and use the Strategy pattern to change between algorithms Context + Context. Interface() strategy Concrete. Strategy. A + Algorithm. Interface() Strategy + Algorithm. Interface() Concrete. Strategy. B + Algorithm. Interface()

Strategy -- example A 1. // Abstract Strategy class A 2. public abstract class

Strategy -- example A 1. // Abstract Strategy class A 2. public abstract class Sort. Strategy { A 3. public abstract void sort(); A 4. } B 1. // Context class B 2. public class Address. Book { B 3. //Default Algorithm B 4. private Sort. Strategy strategy = new Sort. By. Name(); B 5. B 6. public void change. Strategy(Sort. Strategy new. Strategy) { B 7. this. strategy = new. Strategy; B 8. } B 9. B 10. public void sort() { B 11. strategy. sort(); B 12. } }

Strategy – example cont. A 1. public class Sort. By. Name extends Sort. Strategy{

Strategy – example cont. A 1. public class Sort. By. Name extends Sort. Strategy{ // Concrete. Strategy. A class A 2. public void sort(){ A 3. // implementation A 4. } } B 1. public class Sort. By. Age extends Sort. Strategy{ // Concrete. Strategy. B class B 2. public void sort(){ B 3. // implementation B 4. } } C 1. public class Test { C 2. public static void main(String [] argv) { C 3. Address. Book ab = create. Address. Book(“filename”); C 4. ab. sort(); C 5. ab. show. First(); C 6. ab. set. Strategy(new Sort. By. Age()); C 7. ab. sort(); C 8. ab. show. First(); C 9. }}

Strategy – Consequences • Families of related algorithms • An alternative to subclassing •

Strategy – Consequences • Families of related algorithms • An alternative to subclassing • Strategies eliminate conditional statements • A choice of implementations • Clients must be aware of different Strategies • Communication overhead between Strategy and Context • Increased number of objects

Let’s have a break =)

Let’s have a break =)

Mediator – Problem/Applicability • Object-oriented programming encourages distribution of behaviour • Interconnections tend to

Mediator – Problem/Applicability • Object-oriented programming encourages distribution of behaviour • Interconnections tend to reduce usability Class 1 Class 4 Class 2 Class 3

Mediator – Problem/Applicability • When a set of objects communicate in welldefined but complex

Mediator – Problem/Applicability • When a set of objects communicate in welldefined but complex ways • When reusing an object is difficult because it refers to and communicates with many other objects • When a behaviour that’s distributed between several classes should be customizable without a lot of subclassing

Mediator – Solution mediator Mediator Concrete. Mediator Colleague Concrete. Colleague 1 Class 4 Mediator.

Mediator – Solution mediator Mediator Concrete. Mediator Colleague Concrete. Colleague 1 Class 4 Mediator. Class 2 Class 3

Not using Mediator Note how the My. Button class needs to know about the

Not using Mediator Note how the My. Button class needs to know about the Dialog and Checkbox, and how the My. Check. Box needs to know about Radio. Button and Button… Complex communication 1. public class My. Button extends Button { 2. private Dialog dialog; 3. private Checkbox cb 1, cb 2; 4. 5. //called when button is pressed 6. public void press() { 7. boolean checked = this. cb 1. checked(); 8. this. cb 2. set. Checked(checked); 9. this. dialog. update(); 10. } 11. …. 12. } B 1. public class My. Check. Box B 2. extends Checkbox { B 3. private Radio. Button rb; B 4. private Button button; B 5. B 6. //called when box gets checked B 7. public void checked() { B 8. this. button. enable(); B 9. } B 10. …. B 11. }

Mediator – Example Here we let the My. Mediator class handle all the communication.

Mediator – Example Here we let the My. Mediator class handle all the communication. This makes the My. Button class a lot easier to read 1. public class My. Mediator { 2. private Dialog dialog; 3. private Checkbox cb 1, cb 2; 4. private Button button; 5. private Radio. Button rb; 6. 7. public void pressed. Button() { 8. boolean checked = this. cb 1. checked(); 9. this. cb 2. set. Checked(checked); 10. this. dialog. update(); 11. } 12. …. 13. } B 1. public class My. Button B 2. extends Button { B 3. private My. Mediator mediator; B 4. B 5. public void press() { B 6. this. mediator. pressed. Button(); B 7. } B 8. …. B 9. }

Mediator – Consequences • It limits subclassing • It decouples colleagues • It simplifies

Mediator – Consequences • It limits subclassing • It decouples colleagues • It simplifies object protocols • It abstracts how objects cooperate • It centralizes control

Command – Problem • You want to encapsulate a request as an object •

Command – Problem • You want to encapsulate a request as an object • You want to be able to issue requests without knowing anything about the operation being requested

Command – Solution Invoker Command +execute() : void Client Receiver +action(): void receiver instantiates

Command – Solution Invoker Command +execute() : void Client Receiver +action(): void receiver instantiates Concrete. Command -state: State +execute(): void receiver->action();

Command – Example JFrame <<Action. Listener>> GUI -init. Menu() instantiate Command Exit. Command Open.

Command – Example JFrame <<Action. Listener>> GUI -init. Menu() instantiate Command Exit. Command Open. Command JMenu. Item My. Menu. Item command

Command – Example A 1. public interface Command { A 2. public void execute();

Command – Example A 1. public interface Command { A 2. public void execute(); A 3. } 1. import javax. swing. JMenu. Item; 2. public class My. Menu. Item extends JMenu. Item { 3. private Command command; 4. 5. public My. Menu. Item(Command command, String label) { 6. super(label); 7. this. command = command; 8. } 9. 10. public void execute. Command() { 11. if (command != null) { 12. command. execute(); 13. }}}

Command – Example 1. import java. awt. event. *; 2. import javax. swing. *;

Command – Example 1. import java. awt. event. *; 2. import javax. swing. *; 3. public class GUI extends JFrame implements Action. Listener { 4. 5. public GUI() { 6. super(); 7. init. Menu(); 8. add. Window. Listener(new Window. Adapter() { 9. public void window. Closing() { 10. System. exit(0); 11. } 12. }); 13. pack(); 14. }

Command – Example 1. private void init. Menu() { 2. JMenu. Bar bar =

Command – Example 1. private void init. Menu() { 2. JMenu. Bar bar = new JMenu. Bar(); 3. JMenu menu = new JMenu("File"); 4. JMenu. Item item = new My. Menu. Item(new Open. Command(), "Open"); 5. item. add. Action. Listener(this); 6. menu. add(item); 7. item = new My. Menu. Item(new Exit. Command(), "Exit"); 8. item. add. Action. Listener(this); 9. menu. add(item); 10. bar. add(menu); 11. this. set. JMenu. Bar(bar); 12. } 13. 14. public void action. Performed(Action. Event e) { 15. My. Menu. Item item = (My. Menu. Item) e. get. Source(); 16. item. execute. Command(); 17. }}

Command – Applicability • Use when you want to: – specify, queue, and execute

Command – Applicability • Use when you want to: – specify, queue, and execute requests at different times – support undo – support logging changes

Command - Consequences • Decouples invoker from performer • Easy to add new commands

Command - Consequences • Decouples invoker from performer • Easy to add new commands

Summary • Patterns – Creational – Structural – Behavioural

Summary • Patterns – Creational – Structural – Behavioural

Questions?

Questions?