Software engineering and GUI design
Behavioral design patterns Interpreter, Memento, State
Stragety, Template method
1
http://users.nik.uni-obuda.hu/prog4/
2
Purpose Design pattern Short description
Behavioral Iterator foreach () { }
Chain of resp. Execute a process using multiple process executors Visitor Separate caller and called instance – multiple
visitors/visitees: IVisitor.Visit(IVisitorAcceptor) IVisitorAcceptor.Accept(IVisitor)
Command Encapsulate a request/method call into an instance Observer Separate caller and called instance (using events)
Mediator Fully separate caller and called instance (using central hub)
State State instances that control state transitions Interpreter Convert arbitrary input to arbitrary output Memento Restore previous state
Strategy Full implementation/process in the descendants
Depend on abstract base class in constructor
Dependency injection (via Abstract) Template method Define individual steps in the descendants
Usage of virtual methods and method polymorphism
Behavioral Design Patterns
3
Purpose
Creational Structural Behavioral
Scope Class Factory method Adapter Interpreter
Template method
Object Abstract factory Builder
Prototype Singleton
Adapter Bridge Composite Decorator Facade Flyweight Proxy
Chain of responsibility Command
Iterator Mediator Memento Observer State Strategy Visitor
Interpreter
4
expression ::= literal | alternation | sequence | repetition | '(' expression ')'
alternation ::= expression '|' expression sequence ::= expression '&' expression repetition ::= expression '*'
literal ::= 'a' | 'b' | 'c' | ... { 'a' | 'b' | 'c' | ... }*
Interpreter
5
raining & (dogs | cats) *
Interpreter
6
Interpreter
• In principle: using formal language/grammar rules of expressions, convert arbitrary input to arbitrary output
• Too generic, rarely useable, complicated pattern
• Only useable with simple languages (with a complex grammar, the class hierarchy can get extremely complex)
• The class hierarchy is not optimal regarding memory and cpu issues, either
– For example, regular expressions are processed using much more efficient and faster “state machine” methods instead of slow and painful syntax trees
7
Interpreter – C#
8
CALL O
R GET INFO
Interpreter – C#
9
Interpreter – C#
10
Interpreter – C#
11
Interpreter – C#
12
• This is a more common use case: an Expression will not produce a final output on its own, but rather multiple Expressions are called after each other, and they gradually modify the output property of the context
Interpreter – C#
13
Interpreter – C#
14
Interpreter – C#
15
Interpreter – C#
16
Memento
17
• Save and restore previous state
• Originator = original object
Memento = store a single state (OOP: private class?) Caretaker = handle multiple states (OOP: private class?)
• The Originator is responsible for saving its own state into a
Memento instance, and restore its state from a Memento instance
Memento – C#
18
• The Save()’s parameter: the important data (the full instance is rare, as most of the times, private datafields are also saved)
Memento – C#
19
Memento – C#
20
Memento – C#
21
State
22
• „Memento” state = full object state, the important data fields/properties
• „State” state = one single data field, that stores the current status of the instance
State
• State chains can get complex, especially with many states / state transitions
• Without the pattern: „spagetti-code”, same or similar chain of complex checks in multiple business logic methods
23
State – Implementation alternatives
• Common implementation rules
– Context class, with a single State property
– Every different state requires a different suitable class – The state-classes have state-changing methods
– In the state-changing methods, we perform business logic checks / conditions and then we change the state:
24
• Variants
– State-changing methods = business logic methods E.g. bug tickets, Proposed, Open, Resolved, Closed MoveForward(), MoveBackward(), Reject(), Reopen()
– State-changing method = a single state supervisor method E.g. bank accounts, Bronze, Silver, Gold
Deposit(), Withdraw(), PayInterest()
State – C#, Tickets
25
State – C#, Tickets
26
State – variant 1
• Typical modell: State Transition Table
– F(currentState, operation) Conditions + New state
• Pro
– VERY easy, clear structure – Easy to extend
– Every code has its clear place
• Con
– Many states, many BL MANY2 methods, mostly empty
(STT: 1 cell = 1 method; UML State Diagram: 1 possible arrow = 1 method)
– „S”OLID violation? Does not define logic, but knows about…
• Can be good if you have few states/operations but lots of state changes (implements them into a good structure)
• Disturbing if many states/operations (LOTS OF empty methods)
27
State – C#, bank account
28
State – C#, bank account
29
State – C#, bank account
30
State – variant 2
• Typical model: UML state diagram
• „Prettier” solution
– Better suited for the SOLID principles
– The state classes have ZERO business logic code – No unnecessary empty methods
– However: we extract the state changed from the Context class, BUT the Context must know when a state change might occur – this is not obviously nice
• The EnsureState() method can get too complex
– Every state in the UML diagram means one EnsureState method – With complex state systems, this method can get too big
– Solution: Chain of Responsibility, but this increases the number of classes
31
Behavioral Design Patterns
32
Purpose
Creational Structural Behavioral
Scope Class Factory method Adapter Interpreter
Template method
Object Abstract factory Builder
Prototype Singleton
Adapter Bridge Composite Decorator Facade Flyweight Proxy
Chain of responsibility Command
Iterator Mediator Memento Observer State Strategy Visitor
Strategy, Template method
• Basic patterns describing the main OOP principles
– Describes the meaningful use of virtual methods (S”OL”ID) – Dependency injection (with abstract classes: SOLI”D”)
– Related (structural) patterns: Adapter, Bridge
• Used every day, even with the most simple programs
– Strategy: a full operation is dependent on the descendant class (DI with base class)
– Template: the operation is defined by the base class, some steps can be defined in the descendants (virtual methods, DI with
base class)
– Adapter: How can we substitute a class/interface with a different one (DI with interface)
– Bridge: Decomposition of hierarchies (DI with base class)
• Dependency Injection???
– GoF(1994); Martin Fowler (2004) 33
Strategy
34
Strategy – C#
35
Template method
36
Template method – C#
37
Template method – C#
38
Strategy, Template method
• Practically the most widely used design patterns in any system (of any size!)
• Strategy: „How to implement and use a library hierarchy?”
– The base class (interface?) is fixed
– We write code that uses the base class
– Any descendant instance can be used later – Our code calls the hierarchy’s code
• Template: „How to implement and use a framework?”
– The base class defines the possibilities
– The base class is used by a full business logic/process
– We write code that utilizes the rules/possibilities of the base class (usually only a fraction of those)
– The externally defined business process will call our code
39
Strategy = ASP.NET Core Identity
• A completely generic approach, does not care which descendant (= login implementation) is used
40
• PROG3, PROG4: The Logic does not care which data storage implementation is used
Template
= MVC
Framewor k
41
• PROG4
– During the render process, the WPF will SOMEWHERE call the OnRender() method of the FrameworkElement descendants – WPF will SOMEHOW call the event handler/Command member – ASP.NET will SOMEHOW call the Action handler method
Thank you for your attention
Behavioral design patterns Interpreter, Memento, State
Stragety, Template method
42