Sie sind auf Seite 1von 69

Design Patterns

Reading 1

Object Oriented Design and Patterns

Chapter 5: Patterns and GUI Programming

5.1. Iterator as a Pattern

5.2. The Pattern Concept

5.3. The OBSERVER Pattern

5.4. Layout Managers...

5.5. Components, Containers,...

5.6. Scroll Bars and DECORATOR

5.7. How to Recognize Patterns

5.8. Putting Patterns to Work

This reading is required and will be covered on


quizzes and exams

Reading 2

Game Programming Patterns

Introduction

Architecture, Performance, and Games

Design Patterns Revisited Command

This reading is required and will be covered on


quizzes and exams

Overview

A design pattern is a way of solving a problem that


occurs repeatedly in a single program, or
commonly in many programs
Patterns allow us to decouple program elements,
giving us specific conceptual advantages
The patterns we will discuss now include
COMMAND, ITERATOR, FACTORY METHOD,
OBSERVER
Model View Controller architecture is a way of
separating functionality in GUI programs that uses
the OBSERVER pattern

Why?

Why study design patterns?

We've all worked with poorly designed code bases

The appropriate question is "why study software


architecture?"
Small changes cause a cascade of bugs in other parts
of the software
Large changes are difficult or impossible because the
code base is too complex and poorly structured for one
programmer to grasp

What about well designed code bases?

Small changes are easy and quick


Large changes are made easier because the
architecture is decoupled and well documented
See excerpt from GPP

Scenario

Your boss asks you to fix a bug

Your software uses a linked list to store data


But the program bugs out whenever it has to access the
data at two points at the same time, which is required
for a new feature being built by someone else
Your task is to allow two or more simultaneous access
points into the linked list
How do you do it?

What is a Design Pattern?

A Pattern Language: Towns, Buildings, Construction


In 1977, architect Christoph Alexander (and others)
published a book called A Pattern Language:
Towns, Buildings, Construction

This book described strategies for solving common


architectural problems

It described a step-by-step process to design and


construct buildings according to the needs of its users
AND it described common problems in all building
projects, with ways for solving them

These are called design patterns

It described 253 patterns, which together form a pattern


language a language of strategies for solving design
problems

Design Patterns
Design patterns in any domain have two basic
parts

1. The problem (or context)

2. The solution

The problem and solution are stated generally, to


apply to all varieties of a reocurring situation

Christoph Alexander: "Each pattern describes a


problem which occurs over and over again in our
environment, and then describes the core of the
solution to that problem, in such a way that you can use
this solution a million times over, without ever doing it
the same way twice."

Pattern 23: Parallel Roads

Alexander's patterns dealt with problems of


designing communities or campuses
Problem: Grid layout of roads leads to traffic
congestion and gridlock
Solution: Use long, parallel one-way roads

Keep parallel roads around 100 yards apart to allow use


of the intervening space

Pattern 127: Intimacy Gradient

Alexander's patterns also dealt with designing


homes
Problem: Some rooms are more private than others

Guests should not be admitted to bedrooms, for


example

Solution: Lay out spaces so that they create a


sequence which begins with the entrace and most
public parts of a building, then proceeds to the
slightly more private areas, and ends with the most
private domain

Pattern 132: Short Passages

Problem: Long hallways are sterile, intimidating,


and not very useful
Solution: Keep hallways short, and make them as
much like a room as possible

Include windows on one side

Carpet

Nooks

Book shelves

Unique shapes

Design Patterns in Software

Design patterns were quickly adopted for software


design, and famously recommended by the gang of
four book on software design patterns

Design Patterns: Elements of Reusable Design

As in architecture, a design pattern is a common


problem and a list of suggestions for addressing
that problem
It is usually a problem that occurs repeatedly

So the same, or a similar solution, can be used in every


case
The framework for solving one problem can be applied
in many areas of the software

This makes the software easier to understand, modify, and


maintain

The COMMAND Pattern

City-Building Game

You are designing a game where players can


design, construct, and manage their own city
Users can pick from a selection of structures,
including buildings, roads, and parks, then place
them on a grid

City-Building Game

Your game is aimed at consoles, so you build an


interface for controllers

Button A = pick a structure

Button B = place a structure

You add event handlers to buttons A and B, then move


on to the next task

A few months down the line, your company decides


that the game will also be released on PCs and
mobile devices

Now your event handlers are obsolete


How do you change your code to work for all types of
devices?

The COMMAND Pattern

Problem / Context

Solution

You want to reconfigure the function of buttons based


on the device and the user's preferences
Turn each user interaction into an object
Objects can then be associated with particular keys,
buttons, or GUI elements based on user settings

The COMMAND pattern essentially says that user


interactions can be managed and interpreted more
easily if we wrap them in objects

Turn method calls into objects / callbacks

Applying the COMMAND Pattern

In our city building game, we can create a


Command class, and two separate subclasses

Command

execute method - defines what this action actually does


PickStructure subclass

PlaceStructure subclass

Stores the selected structure


Stores the selected structure, and the location

Then, our input handler can store an array of type


Command

Command[] inputActions;

inputActions[0] = PickStructure

When A is pressed, call inputActions[0].execute

Undo

Using the COMMAND pattern also introduces a


second benefit: actions can be stored
We can add an undo method to our Command
superclass

Command

execute
undo

Then Commands can be stored in a stack, and if


the user wants to UNDO a building placement, all
we have to do is pop the top element from the
stack, and call undo

Undo

Undo will only work because command objects


have a state

They store both an action (method) and the way to do


that action (arguments)
Commands can be reversed because the undo method
knows how to do the opposite of what it did before,
using the stored state

It doesn't just remove any building, it removes the one at the


location where you placed one

COMMAND Pattern in Java

AbstractAction

In Java, the COMMAND pattern can be realized


using the AbstractAction superclass

AbstractAction is an abstract class that implements the


Action interface
The Action interface is a sub-interface of ActionListener

We can extend AbstractAction for each action the user


can perform

it has the actionPerformed method plus some constants and


methods for handling state

Objects of type AbstractAction can then be assigned to GUI


elements, such as buttons or menu items

Note the change in terminology

Command = AbstractAction

execute = actionPerformed

ConsoleAction and GuiAction

These two classes define two ways of showing


output to the user

Note the use of getValue(String) and putValue(String)

class GuiAction extends AbstractAction


{
...
}
class ConsoleAction extends AbstractAction
{
public ConsoleAction(String text, String desc)
{
super(text); // set the NAME value
putValue(SHORT_DESCRIPTION, desc);
}
public void actionPerformed(ActionEvent e)
{
System.out.println(getValue(NAME) + " " + getValue(SHORT_DESCRIPTION));
}
}

Attaching Actions

Attaching actions is as easy as calling setAction on


the JComponent that should execute that action

JButton btn1 = new JButton();


btn1.setAction(new GuiAction("GuiAction", "This is a GuiAction!"));
pnlTop.add(btn1);
JButton btn2 = new JButton();
btn2.setAction(new ConsoleAction("ConsoleAction", "This is a ConsoleAction!"));
pnlTop.add(btn2);

Menus

Actions can also be attached to menus at the top of


the window (File, Edit ... etc)

To create a menu, use JMenuBar, JMenu, and


JMenuItem

Set an action by calling setAction on a menu item


// create a new menu
JMenuBar myMenu = new JMenuBar();
JMenu mnuClickMe1 = new JMenu("Click Me!");
myMenu.add(mnuClickMe1);
JMenuItem mnuCat = new JMenuItem("Cat");
mnuCat.setAction(new GuiAction("GuiAction",
"This is a GuiAction!", new ImageIcon("nyan.png")));
mnuClickMe1.add(mnuCat);
myWindow.setJMenuBar(myMenu);

The ITERATOR Pattern

Traversing a Collection

Say we have a linked list class

How do we grant a class user access to the elements?

We could make a public Current pointer that points to a Node,


and let the user manipulate it as they like

We could make a method called next() that manipulates a


private pointer

But doesn't this violate encapsulation? Demeter's Law?

But this still allows the user to manipulate the internal state
And what if the user wants to look at two elements at once?

Why does the user have to know about a collection


at all?

A class user shouldn't have to know which data


structure you are using, just that it is a collection

The ITERATOR Pattern

Problem / Context

A class needs access to the elements stored in an


aggregate / collection

The aggregate / collection should not expose its internal


structure
There may be multiple clients that need simultaneous access

Solution

Define an iterator class that fetches one element at a


time
Each iterator keeps track of its own position with its own
internal state
Use a common interface that is broad enough to be
used by other aggregates

The ITERATOR Pattern

Client = the calling program


Iterator interface defines methods for accessing
and traversing elements

Concrete Iterator implements the Iterator interface and


stores the current position of the iterator

ITERATOR in Java

The Iterator interface defines the ITERATOR


pattern in Java

Defines three methods

hasNext, next, and remove

Typically implemented as an inner class on a


collection

A method returns an Iterator implementation

public LinkedListIterator getLinkedListIterator()


public MyIterator getMyIterator()

Breaking Encapsulation

Using the ITERATOR pattern like this still breaks


encapsulation

The class user must know which type of iterator your


class returns
AND he must know which method to call to get an
iterator from your class

Is there a design pattern to address this?

The FACTORY METHOD Pattern

Problem / Context

A program uses many types of classes that do X, and


must get objects to do X in the same way each time

Solution

A program uses many aggregator classes, and must get


iterators from each one

Define an interface with a single method that returns an


iterator
All classes will use the same method to return an
implementation of the same interface

The FACTORY METHOD pattern means that a


calling class need not know anything about classes
that do an activity

All it knows is they have one method with a specific


name that performs that task

The FACTORY METHOD Pattern

Aggregate interface defines methods for creating


an Iterator

Concrete Aggregate implements the Aggregate


interface and returns an instance of the Concrete
Iterator

FACTORY METHOD in Java

The FACTORY METHOD pattern is used in a lot of


different places in Java
The Iterable interface is one example

It has a single method

Iterator<T> iterator()

For all of the JCF collections, and any collection that


implements Iterable, a class user doesn't need to know
anything about the underlying implementation

returns an iterator over a set of elements of type T

or even the iterator inner class

Iterable is the interface that enables the enhanced for


loop

Example
public class LinkedList implements Iterable
{
public Node First;
public Node Last;
...
@Override
public java.util.Iterator iterator()
{
return new LinkedListIterator();
}
class LinkedListIterator implements Iterator<Object>
{
...
@Override
public boolean hasNext()
{
...
}
@Override
public Object next()
{
...
}
@Override
public void remove()
{
...
}
}
}

The OBSERVER Pattern

Event Driven Architecture

Programs used to be one long list of statements

Event driven architecture is a way of triggering


code based on actions by the user or some other
entity

The code isn't processed in a preset order, but in


whatever order is dictated by events

All modern GUIs rely on events

The first statement is executed, then the next, and the


next. Maybe there is a method call, which executes in
order. And eventually, the program ends because it runs
out of code.

In Java, when a JButton is clicked, it triggers the code


for the appropriate event listeners

This means that one bit of code must be capable of


watching for events in another bit of code

The OBSERVER Pattern

Problem / Context

A source object (A) is the source of events

An observer object (B) should respond to the events

Solution

Define an observer interface type


The source object (A) maintains a collection of objects
that implement the observer interface

and a way to add new observers

Whenever an event occurs, the source object (A)


notifies all observer objects (B)

The OBSERVER Pattern UML

Subject

Stores a list of its observers

provides a method for attaching observers

Observer interface defines a method that is called


when something occurs

Concrete Observer implements the Observer interface

The OBSERVER Pattern UML

In Java, Observer = Listener

Subject is a button, or anything that can detect events

Observer interface is a listener, like ActionListener

attach = addActionListener
notify = actionPerformed

Concrete Observer is the class that implements the


listener

The OBSERVER Pattern


in a Cellular Automaton

Cellular Automata

We previously discussed cellular automata in the


lecture on class design
A cellular automaton is a way to model a discrete,
dynamic system

https://www.youtube.com/watch?v=7j1RGylsA40
We focused on elementary cellular automata

A grid of values that changes over time

A single row of cells that can be on or off based on the


rules in the rule set
https://www.youtube.com/watch?v=SBJ7VqIX9zc

We designed a CA class to compute an elementary


cellular automaton using a rule set implemented as
an interface

Displaying an Elementary CA

A class for a CA is not particularly useful on its own

Part of the fun of a cellular automaton is watching the


patterns evolve in real time

How can we build a custom JComponent that will


display an elementary CA without coupling it to one
particular CA implementation or rule set?

We can use the OBSERVER pattern


The CA will hold a list of observers, which will listen for
events
The CA will throw events whenever it is updated
If anything is listening, then it can update itself
accordingly

Displaying an Elementary CA

OBSERVER pattern

CA aggregates observers
Whenever the CA changes, it notifies its observers,
which can update appropriately

Observers may be GUI components or music generators ...

Modifying the CA Class

We will use the ActionListener interface

CA will now store an ArrayList of ActionListeners

It will add an addActionListener method

And whenever the Update method is called, each


listener will be informed of the change

public class CA
{
private ArrayList<ActionListener> ActionListeners;
...
public void addActionListener(ActionListener NewActionListener)
{
if( NewActionListener != null ) ActionListeners.add(NewActionListener);
}
...
public void Update()
{
Cells = Ruleset.Calculate(Cells);

// tell all the listeners that an action occurred


if( ActionListeners != null && ActionListeners.size() > 0 )
{
ActionEvent UpdateEvent = new ActionEvent(this, 1, "Cells updated");
for( ActionListener a : ActionListeners ) a.actionPerformed(UpdateEvent);
}
}
}

Building the View

Then we just need to build a JComponent subclass


that implements ActionListener by drawing the CA
on screen
Override the actionPerformed method to respond to
the CA

Get the information from the event source

e.getSource

Call repaint() to trigger the paintComponent method


/**
* Respond to events from the automaton.
*/
@Override
public void actionPerformed(ActionEvent e)
{
Cells = ((CA)e.getSource()).GetCells();
MaxValue = ((CA)e.getSource()).GetMaximum();
repaint();
}

Building the View

Override the paintComponent method from the


JComponent class to draw the CA on screen
@Override
protected void paintComponent(Graphics g)
{
if (isOpaque())
{
//paint background
g.setColor(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
}
if (Cells != null)
{
Graphics2D g2d = (Graphics2D)g.create();
// Paint the cells. 0 = white, 1 = black
int CellHeight = this.getHeight() - 1;
double CellWidth = this.getWidth() / Cells.length;
int ColorIncrement = 255 / MaxValue;
for( int i = 0; i < Cells.length; i++ )
{
int NewColor = Cells[i] * ColorIncrement;
g2d.setColor(new Color(NewColor, NewColor, NewColor));
g2d.fillRect((int)(i * CellWidth), 0, (int)CellWidth, CellHeight);
}
g2d.dispose(); //clean up
}
}

Putting it Together

To use the class, instantiate a Ruleset, then a CA,


then a CellView, and add the CellView as a listener
to the CA
// instantiate the rule set
MyRuleset Rules = new MyRuleset();
CA Automaton = new CA(Size, Rules);
// instantiate the view
CA_View CellView = new CA_View();
// tell the CA_View to listen to the CA
Automaton.addActionListener(CellView);
// add the CA_View to the window
myWindow.getContentPane().add(CellView);
// tell the CA to start running
Automaton.Start();

Model View Controller

What is MVC?

MVC is a software architecture designed to


separate the front end from the back end

The front end is the GUI

The back end is the data handling code

Ultimately, the point of MVC is to decouple the front end


from the back end

Two objects are decoupled when they don't rely on each other
So the front end shouldn't rely on one particular back end
implementation
And the back end should rely on one particular GUI

How can we decouple two objects in Java?

Polymorphism

The front end only needs to know that the back end supports saving,
and the back end only needs to know that the front end supports
displaying

Model

the class that holds the actual data

View

the objects that are seen by the user

Typically the view is the GUI

Controller

accepts input

sends commands or information to the model

Three Parts of MVC

The controller can take multiple forms or even be


subsumed within the view
Typically, the controller is the event handlers that handle
events from the user and pass data to the model

Data flows from Controller > Model > View

Typical MVC Implementation

Data flows from the user, through the controller, to


the model, then finally to the view

Design Patterns in MVC

Either OBSERVER or COMMAND pattern can be


used to implement MVC architecture

If OBSERVER, then the model listens for events from


the controller, and the view listens for events from the
model
If COMMAND, then the controller sends commands to
the model and the view
The point is that the Model, View, and Controller
classes are decoupled by a command or observer
interface

So no class directly references the others

MVC Sequence Diagram

Controllers update model


Model tells views that data has changed
Views redraw

Course editor

MVC Example

Drawbacks

PATTERNS EVERYWHERE!

It's easy to start thinking that every aspect of a


program should be derived from a design pattern
After all, if patterns make some aspects of a
program so much more clear, shouldn't they be
applied everywhere

Can't every programming style be turned into a pattern?

Patterns may introduce two negative aspects into


your code base

1. Increased complexity (code bloat)


2. Increased overhead and run time

Increased Complexity

There are disadvantages to design patterns

Every pattern is a trade-off to a degree

See excerpt from Game Programming Patterns

Whenever you add a layer of abstraction or a place


where extensibility is supported, youre speculating that
you will need that flexibility later. Youre adding code
and complexity to your game that takes time to develop,
debug, and maintain.
When people get overzealous about this, you get a
codebase whose architecture has spiraled out of
control. Youve got interfaces and abstractions
everywhere. Plug-in systems, abstract base classes,
virtual methods galore, and all sorts of extension points.
the layers of abstraction themselves end up filling up
your mental scratch disk.

Increased Run Time

Patterns are used to decouple an algorithm from a


specific implementation
Whenever you do this, you introduce additional
classes and interfaces that may not be necessary
for a non-patterned implementation
There is a small hit to performance when you do
this

VERY SMALL

Still, if performance is critical, as in video games,


then you need to weigh the introduction of a pattern
carefully against the other demands on your
software

Anti-Patterns

Anti-Patterns

Patterns are typically used to lead a developer


toward a flexible solution
ANTI-patterns are used to lead a developer AWAY
from a bad solution
Anti-patterns are solutions that are commonly used,
but may be ineffective or counterproductive
Anti-patterns can be used to guide software
development, management, and business
decisions
Many examples of anti-patterns are compiled on
wikipedia

http://en.wikipedia.org/wiki/Anti-pattern

Blob

A system class that encapsulates unrelated


responsibilities

God Object

Anti-Pattern Examples

A system class that encapsulates too many


responsibilities

Poltergeist

A short-lived class with no significant responsibilities

Data formatting classes sometimes

Magic-Numbers

Using unexplained numbers in a method

See GUI and printing code

Anti-Pattern Examples

Object Orgy

Error Hiding

Public properties and methods expose internal state of


objects to other objects
Using exception-handling to hide bugs from developers
or users

Sequential Coupling

A class that requires its public methods to be called in a


specific order

Scenario

Scenario

Your boss asks you to fix a bug

Your software uses a linked list to store data


But the program bugs out whenever it has to access the
data at two points at the same time, which is required
for a new feature being built by someone else
Your task is to allow two or more simultaneous access
points into the linked list
How do you do it?

Use the ITERATOR and FACTORY METHOD


patterns

Write a method to return an iterator that maintains its


own internal state
Each calling class can use the method to get as many
iterators as they choose

Questions?

More

Links

A Pattern Language: Towns, Buildings,


Construction

The Oregon Experiment

http://gameprogrammingpatterns.com/

Anti-Patterns

http://www.jacana.plus.com/pattern/P0.htm

Game Programming Patterns

http://en.wikipedia.org/wiki/Oregon_Experiment

Pattern Language Online

http://en.wikipedia.org/wiki/A_Pattern_Language

http://en.wikipedia.org/wiki/Anti-pattern

r/cellular_automata

Links

http://www.reddit.com/r/cellular_automata/

Das könnte Ihnen auch gefallen