Date post: | 29-Dec-2015 |
Category: |
Documents |
Upload: | gervais-marshall |
View: | 220 times |
Download: | 1 times |
More Design Patterns In Delphi
Jim Cooper
Falafel Software
Session Code: D3.03Track: Delphi
Topics
Discuss some lesser known patterns from the GoF
Examine example code for an application
Somewhat contrived, but we only have an hour
Assume some knowledge of patterns
Most important point is that a pattern is not a code template
Example
A necessarily small piece of software
Read and display CSV files
Read and display XML files
Will automatically detect the type of file being read, and parse it appropriately
Used refactorings on this code. An example is in the Refactorings paper
Parsing CSV files
Comma delimited text
Stuff,123,”More, with comma”,,Last
Often would use a state machine
Models a set of states
From each state, particular inputs cause transitions to other states
Finite State Machine
This example is from ToD, with the kind permission of Julian Bucknall
State Pattern
“Allow an object to alter its behaviour when its internal state changes. The object will appear to
change its class”
Cannot actually change class, so we mimic that
Participants are context (interface to external systems) and states.
State Pattern - Code
Context is TCsvParser
All states derive from TCsvParserState – one for each state in the FSM
Note caching of state objects
Sometimes need to create and destroy states on the fly
State objects often need access to the context
Parsing XML Files
Won’t attempt a full-blown parser!
Only allow a subset of XML, but we still have a small language
Use a recursive descent compiler
See the Dragon Book for details
Output is an abstract syntax tree, where each node represents an element of the language
Grammar
XmlDoc -> Prolog0..1 TagList0..1
Prolog -> <?xml PrologData?>TagList -> Node*Node -> StartTag [Data | TagList] EndTagStartTag -> <TagName>EndTag -> </TagName>PrologData -> [Any printable chars except <,>,/ and ? ]*Data -> [Any printable chars except <,> and / ]*TagName -> [Any printable chars except <,>,/,space,?]+
Ignore DTDs, attributes, escaped characters (e.g. <), structure of prolog data and empty element tags
Example XML file
We will be able to parse things like this:
<?xml version="1.0"?>
<List>
<SomeStuff>Stuff 1 is here</SomeStuff>
<SomeStuff>Stuff 2 is here</SomeStuff>
<SomeStuff>Stuff 3 is here</SomeStuff>
<SomeStuff>Stuff 4 is here</SomeStuff>
</List>
Interpreter Pattern
“Given a language, define a representation for its grammar along with an interpreter that uses the
representation to interpret sentences in the grammar”
Definition of “interpret” is broad, and includes other things than executing instructions
Interpreter Pattern - 2
We will be defining a class for each element in the grammar, so this pattern works best if the grammar is not too complex
Can be inefficient way to represent data
Recursive descent compilers have similar limitations and are a good match for feeding the interpreter
Interpreter Pattern - Code
Requires client to build syntax tree
Base class of tree is the abstract expression class
Has abstract method to perform interpret operation – Search and Replace in our case
Will allow operation on just Data or Tags as well, so need to understand document structure
Interpreter Pattern – Code 2
Subclass for each grammar element
Terminal expressions (refactored out) PrologData, Data, TagName
Actually do search and replace on these elements
Nonterminal expressions Made up of other expressions
Call SearchAndReplace on those other expressions
Visitor Pattern
“Represent an operation to be performed on the elements of an object structure. Visitor lets you
define a new operation without changing the classes of the elements on which it operates.”
Moves operations from tree nodes to another class
Visitor Pattern - Code
Declare a Visitor class, which has a Visit method for each node type in the object structure
Can use method overloading in Delphi
Methods virtual so visitor descendants can choose which to implement
Accept method in base expression class – note similarity with S&R
Visitor Pattern - 2
Implementing new visitors requires a new visitor class, but no changes to the syntax tree
Similar operations are grouped together
Can break encapsulation by needing to know too much about nodes
Changing the object structure will break visitor classes
Documents
Store some information about the document we are looking at
Used as a context in many patterns
Uses a stringlist to hold the text
Strategy Pattern
“Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy
lets the algorithm vary independently from clients that use it. ”
This pattern is a way to use different techniques for the same operation
Strategy Pattern - Code
Hide details of S&R and pretty printing from users of document
In our case, have 2 operations per strategy, and one strategy per file type
Base class is abstract to force implementation in descendants
Note access to context (Document)
Strategy Pattern - 2
Could subclass context to have 2 document classes
Mixes algorithms with document
Can be difficult to structure hierarchy, especially if several operations
More objects in system
Strategy and context can be closely coupled
Can have default algorithms
Command Pattern
“Encapsulate a request as an object, thereby letting you parameterise clients with different requests,
queue or log requests, and support undoable operations.”
Want to be able to undo operations
Delphi actions are an example of the Command pattern
Command Pattern - Code
Abstract base command class
Execute and Rollback methods
Use Template pattern
Descendant class for each command
Need a reference to the document (the receiver)
Not always needed
Separates out command logic
Memento Pattern
“Without violating encapsulation, capture and externalise an object’s internal state so that the
object can be restored to this state later.”
Stores an object’s state
We will use it to support undo operations
Memento Pattern - 2
Normally need 3 types of object
Memento – stores state information
Caretaker – stores the memento(s)
Originator – creates mementos, and uses them to go back to earlier state
Memento class needs a lot of info about the originators
To avoid encapsulation problems declare both in the same unit
Memento Pattern - Code
Document class is our originator
Memento is simple, just stores document text - usually more complex
Memento property accessors get and set document state
Use memento in pretty printing command/rollback
Need a list of commands, so...
Facade Pattern
“Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level
interface that makes the subsystem easier to use.”
Hides a complex subsystem behind a simple interface
Particularly good if subsystem has many tightly coupled classes
Facade Pattern - 2
Reduces coupling between elements of the subsystem and clients
Can change subsystem without affecting clients
Subsystem objects should not normally know about the facade
Facade Pattern - Code
We have a facade to hide the commands and the undo/redo list
Also hides document from the UI
UI code is now one line of code per menu item
Facade is normally a Singleton
References
Design Patterns. Elements of Reusable Object-Oriented Software
Gamma, Helm, Johnson, Vlissides Some find this too abstract
Questions?
33
Evaluatieformulier
Vul je evaluatieformulier in en maak kans op waanzinnige prijzen!!
Session Code: D3.03