the state design pattern idea: internal state == object intent: allow an object to alter its...
TRANSCRIPT
![Page 1: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/1.jpg)
The State Design Pattern
• Idea: internal state == Object• Intent: Allow an object to alter its behaviour
when its internal state changes. The object will appear to change its class.
![Page 2: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/2.jpg)
State Design Pattern
Open() Close() Acknowledge()
TCPConnection
Open() Close() Acknowledge()
TCPState*
Open() Close() Acknowledge()
TCPEstablished
Open() Close() Acknowledge()
TCPListen
Open() Close() Acknowledge()
TCPClosed
state->Open()
state
![Page 3: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/3.jpg)
State Pattern• Motivation: some objects may change their behavior at
runtime…– An individual: Prince / Frog
• When kissed, turns into a prince• When cursed, turns into a frog.• If a prince, will go into duel • If a frog, will quack.
– Another individual: Dr. Jekyll / Mr. Hyde• At night: will turn into a Mr. Hyde.• At day: will turn into Dr. Jekyll• If Jekyll: cure patients• If Hyde: murder prostitutes
– A TCP connection: may be open, may be closed.– A Graphic tool: may be a select tool, but may also be a pen
![Page 4: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/4.jpg)
Typical State BehaviorClass C {
field f; method task() {
if (f == someValue)doTaskOneWay;
else if (f == someOtherValue) doTaskInAnotherWay();
} method anotherTask() {
if (f == someValue)doAnotherTaskOneWay;
else if (f == someOtherValue) doAnotherTaskInAnotherWay();
} ….}
Many of the things you do depend
on your state of
mind
![Page 5: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/5.jpg)
General Technique: Replacing Conditionals by Inheritance
Type Function f() { If (condition) doSomething() else doSomethingElse();}
abstract class A { abstract Type f();}
final class IfCondition { final Type f() { doSomething(); }}
final class ElseCondition { final Type f() { doSomethingElse(); }}
![Page 6: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/6.jpg)
State Pattern
• Reaps the “if to inheritance” technique• Useful if many methods exhibit different
behavior depending on the same state variables.
![Page 7: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/7.jpg)
Finite Automaton Example
class Automaton {State currentState = State.initial;State state = State.A;
public void op_a(final Automaton context) {state.op_a(context);
}
public void op_b(final Automaton context) {state.op_b(context);
}…
}
A B
C
aa
a
b
b
b
![Page 8: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/8.jpg)
State as Enumerated TypeClass Automaton {
…enum State {
A {@Override public void op_a(final Automaton context)
{context.state = B;
}
@Override public void op_b(final Automaton context) {
context.state = C;}
},B {…}C {…};
public abstract void op_a(final Automaton context);public abstract void op_b(final Automaton context);
}
![Page 9: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/9.jpg)
State Structure
Request()
Context
Handle()
State*
state->Handle()
Handle()
ConcreteStateA
state
Handle()
ConcreteStateB
Allow a object to alter its behavior when its internal state changes.
![Page 10: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/10.jpg)
State Known Users
MousePressed() ProcessKeyboard() Initialize()
DrawingController
HandleMousePress() HandleMouseRelease() GetCurser() Activate()
Tool*currentTool
CreationTool SelectionTool TextTool
• Easy to factor out similar strategies (using inheritance)
![Page 11: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/11.jpg)
Example: AVL Tree• AVL Tree: A balanced binary search tree.
– Main property: in all nodes• Height of left and right subtrees can differ by at most 1
– Node can be either: • Balanced: same height of left- and right- subtrees • Left tipped: left subtree is higher (by 1)• Right tipped: right subtree is higher (by 1)
– Example: tree with only one node.• Node is balanced
• The challenge– Insertion of more nodes, while maintaining the AVL
property.
![Page 12: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/12.jpg)
An AVL Tree
left
balanced
balanced
balanced
balanced
balanced
balanced
balanced
balanced
rightleft
![Page 13: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/13.jpg)
AVL Insertion Algorithm1. Insert: as in ordinary binary search tree.2. Balance: traverse the insertion path, bottom up:
– Examine subtree:• If height did not increase, stop traversal.
– Examine parent (height of subtree changed)• Continue:
– Balanced: tip in the appropriate direction.• Stop:
– Right inclined and arriving from left, or– Left inclined and arriving from right:
» Make parent balanced» Stop traversal
• Reorganize and stop:– Right tipping: parent is right inclined and arriving from right,– Left tipping: parent is left inclined and arriving from right:
» Make a local reorganization» Stop
![Page 15: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/15.jpg)
AVL Tree Implementationpublic class AVLTree<T extends Comparable<T>>
implements Checkable {
Node<T> root;
public AVLTree() {root = null;
}
public boolean isEmpty() {return root == null;
}
public void clear() {root = null;
}…
}
![Page 16: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/16.jpg)
Inorder Traversalpublic class AVLTree … {
public void inorder(final Visitor<T> v) {inorder(v, root);
}
interface Visitor<T extends Comparable<T>> {void visit(T n);
}
private void inorder(Visitor<T> v, Node<T> n) {if (n == null)
return;inorder(v, n.left);v.visit(n.data);inorder(v, n.right);
}…}
![Page 17: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/17.jpg)
Tree Invariantpublic class AVLTree … implements Checkable {
@Override public void invariant() {inorder(new Visitor<T>() {
T previous = null;
@Override public void visit(T current) {if (previous != null)
positive(current.compareTo(previous));previous = current;
}});if (root != null)
root.invariant();}static class Node<T extends Comparable<T>>
implements Checkable {@Override public void invariant() { … }
}}
![Page 18: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/18.jpg)
Node Invariantpublic class AVLTree …{static class Node<T… > implements Checkable {
Node<T> left, right;T data;BalancingState b = BalancingState.BALANCED;@Override public void invariant() {
final int hl = height(left); nonnegative(hl);final int hr = height(right); nonnegative(hr);switch (hl - hr) {case 1: sure(b == BalancingState.LEFT); break;case 0: sure(b == BalancingState.BALANCED); break;case -1: sure(b == BalancingState.RIGHT); break; default: unreachable();}
if (right != null) right.invariant();if (left != null) left.invariant(); }
}}
![Page 19: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/19.jpg)
Insertion
public class AVLTree …{private static <T…> Node<T> insert(T x, Node<T> n) {if (n == null)return new Node<T>(x);
final int comparison = x.compareTo(n.data);if (comparison == 0) // Found in tree, do nothing.return n;
if (comparison < 0)n.left = insert(x, n.left);
elsen.right = insert(x, n.right);
return n;}
}
![Page 20: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/20.jpg)
Insertionpublic class AVLTree …{public void insert(final T x) {if (find(x) != null) // No need for insertion, nor for rebalancingreturn;
root = insert(x, root);…
}private static <T…> Node<T> insert(T x, Node<T> n) {if (n == null)return new Node<T>(x);
final int comparison = x.compareTo(n.data);if (comparison == 0) // Found in tree, do nothing.return n;
if (comparison < 0)n.left = insert(x, n.left);
elsen.right = insert(x, n.right);
return n;}
}
![Page 21: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/21.jpg)
Rebalancingpublic class AVLTree …{public void insert(final T x) {…root = Defaults.to(balance(root, x), root);
}private static <T ….> Node<T> balance(Node<T> n, T x) {comparison = x.compareTo(n.data);if (comparison == 0) // This is the leaf where the node was inserted.return null;
if (comparison < 0) { // Node was inserted to the left of this nodeNode<T> newLeft = balance(n.left, x);if (newLeft == null) // Height of left subtree increasedreturn n.tipLeft();
n.left = newLeft;return n;
}// Node was inserted to the right of this node…}
}
![Page 22: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/22.jpg)
Delegation to State
public class AVLTree …{
static class Node<T…> {BalancingState b = BalancingState.BALANCED;Node<T> tipLeft() {return b.tipLeft(this);
}
Node<T> tipRight() {return b.tipRight(this);
}}
}
![Page 23: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/23.jpg)
Balancing Factor and the State Patternpublic class AVLTree …{static class Node<T… > implements Checkable {BalancingState b = BalancingState.BALANCED;enum BalancingState {
BALANCED { public <T …> Node<T> tipLeft(Node<T> me) {
me.setState(LEFT);return null; // height has increased
}public <T …> Node<T> tipRight(Node<T> me) {
me.setState(RIGHT);return null; // height has increased
}},LEFT {…},RIGHT {…};public abstract <T…> Node<T> tipLeft(Node<T> n);public abstract <T…> Node<T> tipRight(Node<T> n);
}}}
![Page 24: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/24.jpg)
Actions in an Unbalanced Nodepublic class AVLTree …{static class Node<T… > implements Checkable {BalancingState b = BalancingState.BALANCED;enum BalancingState {
BALANCED {…},LEFT {
public <T …> Node<T> tipRight(Node<T> me) {return me.setState(BALANCED); // height did not change
}public <T …> Node<T> tipLeft(Node<T> me) {
return me.left.pivotLeft(me); // height did not change}
},RIGHT {…};public abstract <T…> Node<T> tipLeft(Node<T> n);public abstract <T …B> Node<T> tipRight(Node<T> n);
}}}
![Page 25: The State Design Pattern Idea: internal state == Object Intent: Allow an object to alter its behaviour when its internal state changes. The object will](https://reader035.vdocuments.net/reader035/viewer/2022062719/56649ecb5503460f94bd9a53/html5/thumbnails/25.jpg)
Delegating Rotation Responsibilityclass AVLTree {static class Node …{
Node<T> pivotLeft(Node<T> parent) {return b.pivotLeft(this, parent);
}enum BalancingState {
BALANCED {…},LEFT {
public <T …> Node<T> tipLeft(Node<T> me) {return me.left.pivotLeft(me); // height did not change
}Node<T> pivotLeft(Node<T> me, Node<T> parent) {
// LEFT LEFT balancing}
},RIGHT {…};<…> Node<T> pivotLeft(Node<T> me,Node<T> parent) {// Default implementation, setting the method contractnonnull(parent);nonnull(me);require(parent.left == me);return parent;
}}}}