GEPAS Gene Expression Pattern Analysis Suite Ka-Lok Ng Dept. of Bioinformatics Asia University.
1 Dept. of Computer Science & Engineering, York University, Toronto CSE3311 Software Design State...
-
Upload
augustus-daniels -
Category
Documents
-
view
215 -
download
2
Transcript of 1 Dept. of Computer Science & Engineering, York University, Toronto CSE3311 Software Design State...
1Dept. of Computer Science & Engineering, York University, Toronto
CSE3311 Software Design
State Pattern
2
Problem
You are developing a program to keep track of movies for a video store. There are three movie types: regular, children’s, and new releases.
The charge for a movie will depend on the length of the rental and its type. Also, customers receive a number of frequent renter points that depend on the type of the movie rented.
We need the ability to calculate the price and frequent renter points that accrue to a customer renting a movie. Develop a BON diagram demonstrating the classes you might include in this system along with their relationships. Do not be concerned with user interface classes.
3
First Design
class MOVIE1 createmake
feature {NONE} – Initializationmake(n,t: STRING) isdo
name := ntype := t
end
featurename: STRING
type: STRING
4
First Design
price(days_rented: INTEGER): REAL isrequire
positive_days: days_rented >= 0do
if type.is_equal("REG") thenResult := 2if days_rented > 2 then
Result := Result + (days_rented - 2) * 1.5end
elseif type.is_equal("NEW") thenResult := days_rented * 3
elseif type.is_equal("CHI") thenResult := 1.5if days_rented > 3 then
Result := Result + (days_rented - 3) * 1.5end
endend
5
First Designpoints: INTEGER -- frequent renter points do if type.is_equal("REG") then
Result := 100elseif type.is_equal("NEW") then
Result := 200elseif type.is_equal("CHI") then
Result := 150end
end
set_type(t: STRING)do
type := t.twinend
end -- class MOVIE1
How will we change the state from NEW to REG?
6
First Design test class
makelocal
m1, m2, m3: MOVIE1do
-- Design 1: It works but changes are very cumbersome
print("Design1%N")create m1.make("Casablanca", "REG")create m2.make("Bambi", "CHI")create m3.make("The Lord of the Rings", "NEW")print (m1.price(2).out + "%N")print (m2.price(1).out + "%N")print (m3.price(5).out + "%N")print (m3.points.out + " points%N")m3.set_type ("REG")print("The new price for The Lord of the Rings is: ")print (m3.points.out + " points%N%N")
end
7
Critique?
Suppose we need to add a new state ADVENTURE_MOVIE?
price is calculated differently frequent renter points is calculated different
Will need to change multiple places (price and points routine logic)
there may be many more type dependent routines such as special_discount etc.
Single Choice Principle Violated
8
Design Two
price*points*
• Change state (e.g.state ”reg”, “chi”) from class STRING to a class MOVIE2 • Use polymorphism and dynamic binding to delegate calculation of price and points to MOVIE2• Adding a new state is easy• Removes if … elseif … elseif … end statements in class MOVIE1
9
Second Design test class make is
-- Creation procedure.local
m1, m2, m3: MOVIE1m4, m5, m6: MOVIE2
do-- Design 1: It works but changes are very cumbersome-- Design2: Takes advantage of polymorphism
print("Design2%N")create {REGULAR} m4.make("Casablanca")create {CHILDRENS} m5.make("Bambi")create {NEW} m6.make("The Lord of the Rings")print (m4.price(2).out + "%N")print (m5.price(1).out + "%N")print (m6.price(5).out + "%N")print (m6.points.out + " points%N")
print("How to change 'Lord of Rings' to regular???%N%N")end
Position of Single Choice
Delegate price & points to MOVIE2(polymorphism + dynamic binding)
10
Final Design!
price*points*
pricepointsset_type
Delegate price & points to MOVIE_STATE
• Dynamic change of the state• Single choice happens here
11
Final Designclass MOVIE3 create
makefeature {NONE} – Initialization
make(n,t: STRING) isdo name := n; set_type(t) end
featurename: STRINGtype: MOVIE_STATE
set_type (t: STRING)do
if t.is_equal("NEW") then create {NEW_STATE} typeelseif t.is_equal("REG") then create {REGULAR_STATE} typeelseif t.is_equal("CHI") then create {CHILDRENS_STATE} typeend
end
price (days_rented: INTEGER): REAL isdo Result := type.price(days_rented) end
points: INTEGERdo Result := type.points end
end
Single Choice
Delegate price & points to MOVIE_STATE
12
Final Design test class Design 1: It works but changes are very cumbersome Design2: Takes advantage of polymorphism, but what if "The Lord of the Rings" is no longer a NEW movie? Design 3: Polymorphism is now delegated to the state object. Adding a new state is trivial make
localm7, m8, m9: MOVIE3
docreate m7.make("Casablanca", "REG")create m8.make("Bambi", "CHI")create m9.make("The Lord of the Rings", "NEW")print (m7.price(2).out + "%N")print (m8.price(1).out + "%N")print (m9.price(5).out + "%N")print (m9.points.out + " points%N")m9.set_type ("REG")print("The new price for The Lord of the Rings is: ")print (m9.price(5).out + "%N")print (m9.points.out + " points%N")
end
13
State Pattern: allows an object to alter its behaviour when its internal state changes. The object will appear to change its class
By encapulating each state we localize any changes that will need to be made (e.g. price and points) to that state (behaviour)
16
State vs. Strategy
The class diagrams are similar but they differ in intent
State Behaviours are constantly changing over time and the client
(context) knows very little about how those different behaviours work
Encapsulate behaviours in state objects and set change in the context
Alternative to putting a lot of conditionals in the context
Strategy Client knows quite a lot about what behaviour (state) is most
appropriate e.g. we know that a mallard duck has typical flying behaviour and a decoy duck never flies
Change in state less usual Flexible alternative to subclassing