Title: First we look at a standard Dos based application
1Combining Decorator Factory Patterns
First we look at a standard Dos based application
2Combining Decorator Factory Patterns
class Account private int balance public
Account(int b)
balanceb public Account(Account acc)
balanceacc.balance public int
read_bal() return
balance public void deposit(int amt)
balance amt public void withdraw(int
amt) balance -amt
3public class Ex1 public static void Main()
Account a new Account(20) int
choice1,amt0 string temp
while(choice!4) Console.WriteLine() Console
.WriteLine("1 Deposit") Console.WriteLine("2
Withdraw") Console.WriteLine("3 Read
Bal") Console.WriteLine("4 Exit") Console.W
rite("Enter Choice")
tempConsole.ReadLine()
choiceConvert.ToInt32(temp)
4switch(choice) case 1 Console.Write("Enter
Amount ") tempConsole.ReadLine()
amtConvert.ToInt32(temp) a.deposit(amt)
break case 2 Console.Write("Enter Amount
")
tempConsole.ReadLine() amtConvert.ToInt32(temp)
a.withdraw(amt) break case
3 int ba.read_bal()
Console.WriteLine("Balance"b)
break
5During Testing Phase
- we introduce trace printouts public void
deposit(int amt)Cosole.WriteLine("deposit()")
balance amt
6class Account private int balance public
Account(int b)
balanceb public Account(Account acc)
balanceacc.balance public int
read_bal() Console.WriteLine(read_bal()")
return
balance public void deposit(int amt)
Console.WriteLine(deposit()")
balance
amt public void withdraw(int amt)
Console.WriteLine(
withdraw()")
balance -amt
7Unsatisfactory
- Must be removed after testing
- What if you need to retest later
- Different test phases my require different types
of traces
Alternative Solution using Decorator Pattern
8UML Class Diagram
Account
Decorator
Account
SafeAcc
TestAcc
DecTest
9Combining Decorator Factory Patterns
class Account private int balance public
Account(int b)
balanceb public Account(Account acc)
balanceacc.balance public int
read_bal() return
balance public void deposit(int amt)
balance amt public void withdraw(int
amt) balance -amt
As Before
10Combining Decorator Factory Patterns
class Decorator Account protected Account
account public Decorator(Account
acc)base(acc) accountacc
11class TestAcc Decorator public
TestAcc(Account acc)base(acc) new public
int read_bal() print("read_bal()")
return account.read_bal() new
public void deposit(int amt)print("deposit()")
account.deposit(amt) new public void
withdraw(int amt) print("withdraw()")
account.withdraw(amt)
public void print(String s)
Console.WriteLine(s)
12public class Ex1 public static void Main()
TestAcc a new TestAcc(new Account(20))
int choice1,amt0 string temp
while(choice!4) Console.WriteLine() Console
.WriteLine("1 Deposit") Console.WriteLine("2
Withdraw") Console.WriteLine("3 Read
Bal") Console.WriteLine("4 Exit") Console.W
rite("Enter Choice")
tempConsole.ReadLine()
choiceConvert.ToInt32(temp)
13Trace Printout
14After Testing we change back
public class Ex1 public static void Main()
Account a new Account(20) int
choice1,amt0
15We can create other decorators
- Safe Account
- Seeks confirmation before Deposit, Withdraw
16class SafeAcc Decorator public
SafeAcc(Account acc)base(acc)
new public int read_bal()
Console.Write("Enter 1 to confirm ")
string tempConsole.ReadLine()
int choiceConvert.ToInt32(temp)
if (choice1) return
account.read_bal() else
return 0
17 new public void deposit(int amt)
Console.Write("Enter 1 to confirm ")
string tempConsole.ReadLine()
int choiceConvert.ToInt32(temp)
if (choice1)
account.deposit(amt) new public void
withdraw(int a)
Console.Write("Enter 1 to confirm ")
string tempConsole.ReadLine()
int choiceConvert.ToInt32(temp)
if (choice1) account.withdraw(a)
18After Testing we change back
public class Ex1 public static void Main()
SafeAcc a new SafeAcc(new Account(20))
int choice1,amt0
19Confirmation Requested
20Can combine these
public class Ex1 public static void Main()
Account acnew Account(20) TestAcc a
new TestAcc(new SafeAcc(null,ac),ac)
int choice1,amt0
21Trace Printout and Confirmation Requested
22Can combine these
public class Ex1 public static void Main()
Account acnew Account(20) SafeAcc a
new SafeAcc(new TestAcc(null,ac),ac) int
choice1,amt0
23Confirmation Requested then Trace Printout
24To achieve this we must modify code of decorators
class TestAcc Decorator private
SafeAcc sacc public TestAcc(SafeAcc
sacc,Account acc)base(acc)
this.saccsacc new public int
read_bal() print("read_bal()") if
(sacc!null) return sacc.read_bal()
else return account.read_bal()
new public void deposit(int amt)print("deposit()"
) if (sacc!null)
sacc.deposit(amt) else
account.deposit(amt)
25class SafeAcc Decorator private
TestAcc tacc public SafeAcc(TestAcc
tacc,Account acc)base(acc)
this.tacctacc new public int read_bal()
Console.Write("Enter 1 to
confirm ") string
tempConsole.ReadLine() int
choiceConvert.ToInt32(temp)
if (tacc!null) return tacc.read_bal()
else return account.read_bal()
26 new public void deposit(int amt)
Console.Write("Enter 1 to confirm ")
string tempConsole.ReadLine()
int choiceConvert.ToInt32(temp)
if (tacc!null) tacc.deposit(amt)
else account.deposit(amt)
new public void withdraw(int amt)
Console.Write("Enter 1 to confirm ")
string tempConsole.ReadLine()
int choiceConvert.ToInt32(temp)
if (tacc!null)
tacc.withdraw(amt) else
account.withdraw(amt)
27Can add functionality by adding objects
Options
- 1. Account a new Account(bal)
- 2. SafeAcc a new SafeAcc(null,new
Account(20)) - Or alternative
- Account acnew Account(20)
- SafeAcc a new SafeAcc(null,ac)
-
- TestAcc a new TestAcc(null,new Account(20))
- Account acnew Account(20)
- TestAcc a new TestAcc(new
SafeAcc(null,ac),ac)
28Improve by using Factory Pattern
Factory creates an Account object based on data
In the following example base choice on user
input Better solution would be to read value
from a configuration file Could change the value
in file after test etc First We must make some
minor changes to introduce Polymorphism
29using System abstract class Decorator
Account protected Account account public
Decorator(Account acc)base(acc)
accountacc class AccInterface virtual
public int read_bal()return 0 virtual public
void deposit(int amt) virtual public void
withdraw(int amt)
30using System abstract class Decorator
Account protected Account account public
Decorator(Account acc)base(acc)
accountacc class AccInterface virtual
public int read_bal()return 0 virtual public
void deposit(int amt) virtual public void
withdraw(int amt)
31class AccountAccInterface private int
balance public Account(int b)
balanceb public Account(Account acc)
balanceacc.balance override
public int read_bal() return
balance override public void deposit(int
amt) balance
amt override public void withdraw(int amt)
balance -amt
32class TestAcc Decorator private
SafeAcc sacc public TestAcc(SafeAcc
sacc,Account acc)base(acc)
this.saccsacc override public int
read_bal() print("read_bal()") if
(sacc!null) return sacc.read_bal()
else return account.read_bal()
override public void deposit(int
amt)print("deposit()") if
(sacc!null) sacc.deposit(amt)
else account.deposit(amt) etc
33Now we can use Polymorphism to get the same result
public class Ex1 public static void Main()
Account acnew Account(20)
AccInterface a new TestAcc(new
SafeAcc(null,ac),ac) int
choice1,amt0 etc
34Now we can use a Factory to decide type of Account
35public class Ex1 public static void Main()
Console.WriteLine("Enter Account Type")
Console.WriteLine("1 Normal")
Console.WriteLine("2 Test")
Console.WriteLine("3 Safe")
Console.WriteLine("4 Safe and Test")
Console.Write("Enter Choice")
string tConsole.ReadLine() int
optionConvert.ToInt32(t) AccInterface a
AccountFactory.createAccou
nt(20,option) int
choice1,amt0 (as
before)
36class AccountFactory static public AccInterface
createAccount(int bal,int type) Account acnew
Account(bal) if (type1) return ac if
(type2) return new TestAcc(null,ac) if
(type3) return new SafeAcc(null,ac) else
return new TestAcc(new
SafeAcc(null,ac),ac)
37Input to Factory
38Could also have a Factory Based on a single
parameter
public class Ex1 public static void Main()
Console.Write("Enter Balance")
string tConsole.ReadLine() int
balConvert.ToInt32(t) AccInterface a
AccountFactory.createAccount(bal) int
choice1,amt0
(as before)
39 class AccountFactory static public
AccInterface createAccount(int bal) if (bal
lt 100) return new Account(bal) else return
new SafeAcc(null,new Account(bal))
40Exercise1 Given the class class
Counter private int value public Counter(int
v)valuev public Counter(Counter cc)
valuecc.value public int read_value()return
value public void increment()value public
void decrement()
value-- Now we want to decorate the Counter
(similar to Account Ex)
41(i) class UpperLimit extends Decorator same as
before except increment will only increment if
value lt20 otherwise will print out Too High
Hint public void increment()if
(counter.read_value()lt20) (ii) class LowerLimit
extends Decorator same as before except
decrement will only decrement if value
gt0 otherwise will print out Too Low (iii)
Want a factory to decide on the of counter
See next Dos screen
42(No Transcript)
43Exercise 1(b) Now Modify the Application so the
Factory is based on just an initial counter value
read in from the Console - Values lt 5 will
generate a Normal Counter Object - 5-10 inclusive
will generate a LowerLimit Object - 11 -15 an
UpperLimit Object - Values gt 15 will produce one
with both an Upper Lower Limit
44Exercise2 Given the class class
Display private String name public
Display(String n)namen public Display(Display
dd) namedd.name public void
print()System.out.println("\t"name) public
void setName(String n)namen Will Display a
name Now we want to decorate the Display
(similar to Account Ex)
45Normal Display Athlone UpperLine
Athlone LowerLine Athlone
Upper and Lower Line
Athlone
46(a) class UpperLine extends Decorator print a
line of before name (b) class LowerLine
extends Decorator print a line of after
name (c) Want a factory to decide on the of
Display Type See next Dos screen
47(No Transcript)
48(No Transcript)