61
06/27/22 1 Design Patterns Week 6: MVC and Other Patterns Jonathan Simon [email protected]

MVC and Other Design Patterns

Embed Size (px)

DESCRIPTION

This is Class 6 on a 6 week course I taught on Software Design Patterns. This course provides an introduction into the MVC patterns and briefly goes over other patterns not covered in detail in the class.Class based on "Head First Design Patterns."

Citation preview

Page 1: MVC and Other Design Patterns

04/13/23 1

Design Patterns

Week 6: MVC and Other Patterns

Jonathan [email protected]

Page 2: MVC and Other Design Patterns

DJView

Pg 534

Two Different User Interfaces View – Shows BPM and Beat in real time Control – Enter BPM and click start button. Increase and

Decrease buttons.

Pg 535 Start and Stop buttons

204/13/23

Page 3: MVC and Other Design Patterns

DJView: Version 1 //Fields

int bpm;

Sequencer sequencer;

public DJView() {

//Display UI Elements

CreateDisplayView();

CreateControlView();

//Enable/Disable UI State

DisableStopMenuItem();

EnableStartMenuItem();

sequencer = new Sequencer();

}304/13/23

Page 4: MVC and Other Design Patterns

DJView: Version 1 public void StartButtonPushed() {

sequencer.start();

bpm = 90;

sequencer.setTempoInBpm(bpm);

DisableStartMenuItem();

EnableStopMenuItem();

DisplayBpm(bpm);

}

public void StopButtonPushed() {

sequencer.turnOff();

bpm = 0;

EnableStartMenuItem();

DisableStopMenuItem();

DisplayBpm(bpm);

} 4

Page 5: MVC and Other Design Patterns

DJView: Version 1public void SetBpm(int bpm) {

this.bpm = bpm;

sequencer.setTempoInBpm(bpm);

DisplayBpm(bpm);

}

public void IncreaseBpm() {

this.bpm = bpm + 1;

sequencer.setTempoInBpm(bpm);

DisplayBpm(bpm);

}

public void DecreaseBpm() {

this.bpm = bpm - 1;

sequencer.setTempoInBpm(bpm);

DisplayBpm(bpm);

}

5

Page 6: MVC and Other Design Patterns

DJView: Version 1

public void UpdateBeat() {

while (true) {

if (sequencer.BeatChanged)

DisplayBeat(sequencer.getBeat());

}

}

604/13/23

Page 7: MVC and Other Design Patterns

DJView: Version 1

704/13/23

Page 8: MVC and Other Design Patterns

Requirement Change… Now we need another screen (ArtistView) to display BPM.

(as well other information just as Song Name, Artist, Album Name, year, etc). Note: ArtistView is not interested in a change in Beat.

How can we display BPM? We can modify function DisplayBpm() to update ArtistView and

DJView whenever a change is made to BPM. What happens when we create another screen, say AlbumView?

804/13/23

Page 9: MVC and Other Design Patterns

So.. We have a few different screens (DJView, ArtistView,

AlbumView) that are all interested whenever we have a change in data state (BPM or Beat). Some screens are interested in change in BPM, others change

Beat, and some changes in both.

Currently, we have to update DJView whenever we want to add another screen that is interested in changes in BPM or Beat.

What pattern is screaming to be used?

904/13/23

Page 10: MVC and Other Design Patterns

Creating a Subject

We need a Subject that contains the data state that we know is changing.

In this example, what should fields should go in our Subject?

How many different events should our Subject expose?

How do we “glue” our Observers to this Subject?

1004/13/23

Page 11: MVC and Other Design Patterns

Subject = BeatModel public class BeatModel {

int bpm;

Sequencer sequencer;

public void initialize() {

sequencer = new Sequencer();

}

public void RegisterObserver(BeatObserver o) { }

public void RemoveObserver(BeatObserver o) { }

public void NotifyBeatObservers() { }

public void RegisterObserver(BPMObserver o) { }

public void RemoveObserver(BPMObserver o) { }

public void NotifyBpmObservers() { }

}

11

Page 12: MVC and Other Design Patterns

BeatObserver and BPMObserver

public interface BeatObserver {

void updateBeat();

}

public interface BPMObserver {

void updateBPM();

}

1204/13/23

Page 13: MVC and Other Design Patterns

DJView: Version 2 //Fields

int bpm;

Sequencer sequencer;

public DJView() {

//Display UI Elements

CreateDisplayView();

CreateControlView();

//Enable/Disable UI State

DisableStopMenuItem();

EnableStartMenuItem();

sequencer = new Sequencer();

}

1304/13/23

Changes???

Page 14: MVC and Other Design Patterns

DJView: Version 2//Fields

BeatModel model;

public DJView() {

//Display UI Elements

CreateDisplayView();

CreateControlView();

//Enable/Disable UI State

DisableStopMenuItem();

EnableStartMenuItem();

model = new BeatModel();

model.initialize();

}

1404/13/23

Page 15: MVC and Other Design Patterns

DJView: Version 2 public void StartButtonPushed() {

sequencer.start();

bpm = 90;

sequencer.setTempoInBpm(bpm);

DisableStartMenuItem();

EnableStopMenuItem();

DisplayBpm(bpm);

}

public void StopButtonPushed() {

sequencer.turnOff();

bpm = 0;

EnableStartMenuItem();

DisableStopMenuItem();

DisplayBpm(bpm);

} 15

Does DJView have a direct reference :To sequencer? To bpm field?

Page 16: MVC and Other Design Patterns

DJView: Version 2public void StartButtonPushed() {

model.on();

DisableStartMenuItem();

EnableStopMenuItem();

DisplayBpm(bpm);

}

public void StopButtonPushed() {

model.off();

EnableStartMenuItem();

DisableStopMenuItem();

DisplayBpm(bpm);

}

1604/13/23

What should we do with this DisplayBpm function?

What interfaces does DJView need to implement? Remember BeatModel…

Page 17: MVC and Other Design Patterns

DJView: Version 2public class DJView : BeatObserver, BPMObserver {

public void updateBeat() {

//Display change in Beat in the UI

}

public void updateBpm() {

int bpm = model.getBpm();

if (bpm == 0)

//Display "offline"

else

//Display "Current BPM" with value

}

}

}

}

1704/13/23What are we missing?

Page 18: MVC and Other Design Patterns

DJView: Version2

public DJView() {

//Display UI Elements

CreateDisplayView();

CreateControlView();

//Enable/Disable UI State

DisableStopMenuItem();

EnableStartMenuItem();

model = new BeatModel();

model.initialize();

model.RegisterObserver((BeatObserver)this);

model.RegisterObserver((BPMObserver)this);

}

1804/13/23

Page 19: MVC and Other Design Patterns

DJView: Version 2public void StartButtonPushed() {

model.on();

DisableStartMenuItem();

EnableStopMenuItem();

}

public void StopButtonPushed() {

model.off();

EnableStartMenuItem();

DisableStopMenuItem();

}

public void SetBpm(int bpm) {

model.setBPM(bpm);

}

public void IncreaseBpm() {

model.increaseBpm();

}

public void DecreaseBpm() {

model.decreaseBpm();

}19

Page 20: MVC and Other Design Patterns

Version 2

2004/13/23

Notice beatObservers and bpmObservers in BeatModel.

Page 21: MVC and Other Design Patterns

View and Model

We now have a View and a Model

The View is also an Observer. It is interested in changes in the Model.

When the Model has a data change, the View gets notified (updateBPM). The View then gets data from the Model (getBPM).

We can have multiple Views all interested in this Model.

2104/13/23

Page 22: MVC and Other Design Patterns

Multiple Views w/One Model

2204/13/23

Question: Does the Model know any specific details about the UI elements on the View?

Page 23: MVC and Other Design Patterns

Definition (Partial): Model

Contains the data, state, and application logic.

State changes can occur internally or externally. (more on this later).

When a change of state occurs, the Model sends a notification message.

The Model doesn’t have any direct references to the Views that need it. (Since the Views registers themselves with the Model).

2304/13/23

Page 24: MVC and Other Design Patterns

Definition (Partial): ViewGraphic User Interface.

It is the “window” to the model.

View registers with the Model for notification of certain events.

When notified by the Model, the View asks the Model for state information.

View must have a direct reference to the Model in order to get data. (can also be an interface the Model uses)

2404/13/23

Page 25: MVC and Other Design Patterns

Requirement Change We need to change all of these views from a Windows

application to a Web application.

We would like to minimize the amount of code that we need to re-write for the new user interface.

Let’s look at the DJView code again..

2504/13/23

Page 26: MVC and Other Design Patterns

DJView: Version 2public DJView() {

CreateDisplayView();

CreateControlView();

DisableStopMenuItem();

EnableStartMenuItem();

//Hidden: Create model, initialize and register observers

}

public void StartButtonPushed() {

model.on();

DisableStartMenuItem();

EnableStopMenuItem();

}

public void updateBeat() { ... }

public void updateBPM() { ... }

26

We know that we cannot re-use UI elements when we change Views.

Page 27: MVC and Other Design Patterns

Challenge

We want to separate elements from DJView that vary from the things that do not vary.

What varies?

What does not vary?

2704/13/23

Page 28: MVC and Other Design Patterns

What Varies Internals of CreateDisplayView() + CreateControlView() Internals of all of the Disable/Enable methods The internals of the updateBeat and updateBPM that has to do

with updating UI How events are associated with UI element

What does not vary The sequence of events. For example, StartButtonPushed has

a specific set of steps. Calling the Model to do something (on(), off()) Registering View with the Model The internals of the updateBPM that has to do with getting data

from the Model

2804/13/23

Page 29: MVC and Other Design Patterns

Inheritance Base View class that contains:

Reference to BeatModel Template Pattern to define known set of steps; use abstract

methods for pieces that need to be implemented by sub class.

Each subclass just defines the UI specific elements.

What problems will we encounter?

2904/13/23

Page 30: MVC and Other Design Patterns

Inheritance (cont)

We can’t inherit form the base View and the specific UI form (which contains a lot of functionality for interacting with UI elements)

We would need to inherit from the Base View and wrap the specific UI element (Windows or Web form) and then expose what we need. (Adapter Pattern!)

This would be painful…

3004/13/23

Page 31: MVC and Other Design Patterns

Composition View just contains the UI elements and functions that

manipulate the UI elements (What Varies)

View associates UI element with a handler. (What Varies)

The UI handler may do a special sequence of events (which may manipulate a combination of model changes and UI updates). This is What Not Varies.

Here is our separation of View and Controller (the New Guy).

3104/13/23

Page 32: MVC and Other Design Patterns

What about the Model?

The View interacts with the Model in two ways:

1) Sends a message to the Controller to update the Model. (setBPM, increase, decrease)

2) Gets notified when Model changes (updateBeat, updateBPM)

3204/13/23

Page 33: MVC and Other Design Patterns

DJView: Version 3 (Pt 1)

public class DJView : BeatObserver, BPMObserver {

BeatModel model;

BeatController controller;

public DJView(BeatModel model, BeatController controller)

{

this.model = model;

this.controller = controller;

model.RegisterObserver((BeatObserver)this);

model.RegisterObserver((BPMObserver)this);

}

public void updateBeat() { . . }

public void updateBPM() { . . }

3304/13/23

Note: The only reason that View needs Model is for registering of events and getting state from Model.

Page 34: MVC and Other Design Patterns

DJView: Version 3 (Pt 2)public void StartButtonPushed() {

controller.start();

}

public void StopButtonPushed() {

controller.stop();

}

public void SetBpm(int bpm) {

controller.setBPM(bpm);

}

public void IncreaseBpm() {

controller.increaseBPM();

}

public void DecreaseBpm() {

controller.decreaseBPM();

}

3404/13/23

The View delegates all actions to the Controller.

Page 35: MVC and Other Design Patterns

DJView: Version 3 (Pt 3)

//Lastly, we have all of the functions that directly manipulate

//UI elements in the View. These functions are called externally

//by the Controller!

public void CreateDisplayView() { }

public void CreateControlView() { }

public void DisableStopMenuItem() { }

public void EnableStopMenuItem() { }

public void DisableStartMenuItem() { }

public void EnableStartMenuItem() { }

3504/13/23

NOTE: If we have to port this View from Windows to Web, here is where the crux of our changes will occur.

Page 36: MVC and Other Design Patterns

BeatControllerpublic class BeatController {

BeatModel model;

DJView view;

public BeatController(BeatModel model)

this.model = model;

view = new DJView(model, this);

view.CreateDisplayView();

view.CreateControlView();

view.DisableStopMenuItem();

view.EnableStartMenuItem();

model.initialize();

}36

Why???

Page 37: MVC and Other Design Patterns

BeatController

public void start() {

model.on();

view.DisableStartMenuItem();

view.EnableStopMenuItem();

}

public void stop() {

model.off();

view.EnableStartMenuItem();

view.DisableStopMenuItem();

}

public void setBPM(int bpm) {

model.setBPM(bpm);

}

3704/13/23

Controller sends a message to Model to update data…and sends a message back to the View.

Note: Not showing the Model here. It is exactly the same!

Page 38: MVC and Other Design Patterns

The Big Picture

3804/13/23

See diagram on page 530.

Page 39: MVC and Other Design Patterns

Definition: Model

Contains the data, state, and application logic.

State changes can occur internally or externally (by a message from the Controller)

When a change of state occurs, the Model sends a notification message to the Views that want to be notified.

The Model doesn’t have any direct references to the Views or Controllers that need it.

3904/13/23

Page 40: MVC and Other Design Patterns

Definition: ViewGraphic User Interface.

It is the “window” to the model.

View registers with the Model for notification of certain events. When notified by the Model, the View asks the Model for state information.

View must have a direct reference to the Model in order to get data. (can also be an interface the Model uses)

View delegates actions to the Controller.

4004/13/23

Page 41: MVC and Other Design Patterns

Definition: Controller

Handles user actions initiated on the View.

Informs the Model of any data changes.

When applicable, tells the View to change it’s UI state.

4104/13/23

Page 42: MVC and Other Design Patterns

Lab: Part I In BeatController.start() function does three things:

Sends on() message to the Model Sends DisableStartMenuItem() message to the View Sends EnableStopMenuItem() message to the View.

Then we get a requirement that the end user needs to change the Mode (Basic or Advanced) at any time. If user calls start() during Basic mode, the same functionality

occurs. If user calls start() during Advanced mode, the Basic mode

functionality occurs, but in addition, the UI displays a video of the song.

What can we do? What pattern can help us?

42

Page 43: MVC and Other Design Patterns

Lab: Part II

Let’s say we need to add permissions. Which object should be modified? (Model, View, Controller)

Let’s say a change in the Model needs to result in the enabling and disabling of certain UI elements in the View. What can we do?

4304/13/23

Page 44: MVC and Other Design Patterns

Answer : Part I BeatController can be an abstract class with default

implementation for all methods, except start (which can be marked abstract)

Create two classes that inherit from BeatController (Basic and Advanced). Each class defines the unique behavior of start.

Associate the View with the appropriate version of BeatController.

Use Strategy Pattern to change behavior at run time.

4404/13/23

Page 45: MVC and Other Design Patterns

Answer: Part II

Controller. We could easily create a Permission object that is accessed by the Controller. This has the benefit of keeping permission-related code out of the View.

Two Answers: The View can easily respond to the change in the Model and set

the appropriate UI elements; however, that is putting more business logic in the View.

Controller can become an Observer of certain events in the Model (in addition to the View!). If a certain change of state occurs in the Model, the Controller can tell the View which UI elements to change.

4504/13/23

Page 46: MVC and Other Design Patterns

Testing

Testing is a lot easier with MVC.

Unit Tests can target the Controller and Model.

It is harder to unit test the View.

4604/13/23

Page 47: MVC and Other Design Patterns

Frameworks for MVC

Spring MVC Java Swing Windows Presentation Foundation (WPF) ASP.NET MVC Framework PureMVC Bistro Apache Struts And many more…

4704/13/23

Page 48: MVC and Other Design Patterns

Model View Presenter (MVP)

Derivative of MVC.

Focuses on the Presentation Layer. For example, interaction of different UI elements on a form.

References http://en.wikipedia.org/wiki/Model-view-presenter http://www.mvcsharp.org/

4804/13/23

Page 49: MVC and Other Design Patterns

Other Patterns

Iterator Composite Builder Façade State Chain of Responsibility Flyweight Memento

4904/13/23

Page 50: MVC and Other Design Patterns

Iterator

GoF Intent: “Provides a way to access the elements of an aggregate object sequentially without exposing its underlying representation.”

There are different types of “aggregate objects” Collection ArrayList List<> Array string[]

5004/13/23

Page 51: MVC and Other Design Patterns

Iterator (cont)

Each of these objects have different ways of looping through and accessing different elements.

Iterator patterns hides the implementation of the aggregate object from the clients that access it.

Advantage: You can change an ArrayList into a List<> without breaking clients that use you it.

5104/13/23

Page 52: MVC and Other Design Patterns

Composite

GoF Intent: “allows you to compose objects into tree structures to represent whole-part hierarchies. Composite lets clients treat individual objects and composition of objects uniformly.”

Think of a tree hierarchy Business objects User Interface elements (Window Panel Button)

A Node (with Children) and a Leaf Node are all treated the same.

5204/13/23

Page 53: MVC and Other Design Patterns

Composite (cont)

Example: Windows form where all UI elements are in a tree. Message is sent to top node to “disable all elements”. The tree is traversed and Disable message is applied to each node in the tree.

Composite and Iterator are often used together.

5304/13/23

Page 54: MVC and Other Design Patterns

Builder

Encapsulate the construction of a product and allow it to be constructed in steps.

Good for the creation of complex objects.

Client sends multiple messages to the Builder for creating certain parts of the structure. Then Builder returns Composite result.

5404/13/23

Page 55: MVC and Other Design Patterns

Facade

“Provides a unified interface to a set of interfaces in a subsystem. Façade defines a higher-level interface that makes the subsystem easier to use”.

Example, communication between Business and Data Layer.

5504/13/23

Page 56: MVC and Other Design Patterns

State Pattern GoF Intent: “Allows an object to alter its behavior when

its internal state changes. The object will appear to change its class.”

Strategy Pattern – behavior change due to an external change. (Remember the setBehavior() method). The Clients had to be aware of the different possible Strategies.

State is basically like Strategy; however, changes occur internally.

5604/13/23

Page 57: MVC and Other Design Patterns

Chain of Responsibility

“Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.”

Each object in chain acts as a handler. If it cannot handle the request, passes it to the next object in the chain.

Often using in Windows system for handling events generated by keyboard or mouse.

5704/13/23

Page 58: MVC and Other Design Patterns

Flyweight

GoF Intent: “Use sharing to support large numbers of fine-grained objects efficiently.”

Addresses memory issues.

Instead of having 100 large objects that take up memory: One stateless object Manager object that contains the state of the 100 objects

Single instances will not be able to behave independently from other instances. (Probably better for read-only purposes!)

5804/13/23

Page 59: MVC and Other Design Patterns

Memento

Be able to return object to a previous state.

Handle undo.

5904/13/23

Page 60: MVC and Other Design Patterns

Next Steps?

Read the rest of the book!

Buy the Gang of Four book to get more details on the patterns mentioned in this book.

Understand commonly used frameworks MVC Spring Dependency Injection

6004/13/23

Page 61: MVC and Other Design Patterns

Martin Fowler

http://www.martinfowler.com/ Refactoring: Improving the Design of Existing Code Patterns of Enterprise Application Architecture

6104/13/23