Download presentation
Presentation is loading. Please wait.
Published byJennifer Alexander Modified over 9 years ago
1
Nov 2005 MSc Slide 1 First we look at a standard Dos based application Combining Decorator & Factory Patterns
2
Nov 2005 MSc Slide 2 class Account{ private int balance; public Account(int b) {balance=b;} public Account(Account acc) {balance=acc.balance;} public int read_bal() {return balance;} public void deposit(int amt) {balance +=amt;} public void withdraw(int amt) {balance -=amt;} } Combining Decorator & Factory Patterns
3
public class Ex1{ public static void Main(){ Account a = new Account(20); int choice=1,amt=0; 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.Write("Enter Choice:"); temp=Console.ReadLine(); choice=Convert.ToInt32(temp); :
4
switch(choice){ case 1: Console.Write("Enter Amount: "); temp=Console.ReadLine(); amt=Convert.ToInt32(temp); a.deposit(amt); break; case 2: Console.Write("Enter Amount: "); temp=Console.ReadLine(); amt=Convert.ToInt32(temp); a.withdraw(amt); break; case 3: int b=a.read_bal(); Console.WriteLine("Balance="+b); break; }}}} }
5
Nov 2005 MSc Slide 5 - we introduce trace printouts public void deposit(int amt){Cosole.WriteLine("deposit()"); balance +=amt;} During Testing Phase
6
Nov 2005 MSc Slide 6 class Account{ private int balance; public Account(int b) {balance=b;} public Account(Account acc) {balance=acc.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;} }
7
Nov 2005 MSc Slide 7 Must be removed after testing What if you need to retest later Different test phases my require different types of traces Unsatisfactory Alternative Solution using Decorator Pattern
8
Nov 2005 MSc Slide 8 Account TestAcc SafeAcc DecTest DecoratorAccount UML Class Diagram
9
Nov 2005 MSc Slide 9 class Account{ private int balance; public Account(int b) {balance=b;} public Account(Account acc) {balance=acc.balance;} public int read_bal() {return balance;} public void deposit(int amt) {balance +=amt;} public void withdraw(int amt) {balance -=amt;} } Combining Decorator & Factory Patterns As Before
10
Nov 2005 MSc Slide 10 class Decorator : Account{ protected Account account; public Decorator(Account acc):base(acc){ account=acc;} } Combining Decorator & Factory Patterns
11
Nov 2005 MSc Slide 11 class 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);} }
12
Nov 2005 MSc Slide 12 public class Ex1{ public static void Main(){ TestAcc a = new TestAcc(new Account(20)); int choice=1,amt=0; 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.Write("Enter Choice:"); temp=Console.ReadLine(); choice=Convert.ToInt32(temp); :
13
Trace Printout
14
public class Ex1{ public static void Main(){ Account a = new Account(20); int choice=1,amt=0; : After Testing we change back
15
Safe Account Seeks confirmation before Deposit, Withdraw We can create other decorators
16
class SafeAcc : Decorator{ public SafeAcc(Account acc):base(acc); {} new public int read_bal() {Console.Write("Enter 1 to confirm: "); string temp=Console.ReadLine(); int choice=Convert.ToInt32(temp); if (choice==1) return account.read_bal(); else return 0;} :
17
new public void deposit(int amt){ Console.Write("Enter 1 to confirm: "); string temp=Console.ReadLine(); int choice=Convert.ToInt32(temp); if (choice==1) account.deposit(amt);} new public void withdraw(int a) { Console.Write("Enter 1 to confirm: "); string temp=Console.ReadLine(); int choice=Convert.ToInt32(temp); if (choice==1) account.withdraw(a);} }
18
public class Ex1{ public static void Main(){ SafeAcc a = new SafeAcc(new Account(20)); int choice=1,amt=0; : After Testing we change back
19
Nov 2005 MSc Slide 19 Confirmation Requested
20
public class Ex1{ public static void Main(){ Account ac=new Account(20); TestAcc a = new TestAcc(new SafeAcc(null,ac),ac); int choice=1,amt=0; : Can combine these
21
Nov 2005 MSc Slide 21 Trace Printout and Confirmation Requested
22
Nov 2005 MSc Slide 22 public class Ex1{ public static void Main(){ Account ac=new Account(20); SafeAcc a = new SafeAcc(new TestAcc(null,ac),ac); int choice=1,amt=0; : Can combine these
23
Nov 2005 MSc Slide 23 Confirmation Requested then Trace Printout
24
class TestAcc : Decorator{ private SafeAcc sacc; public TestAcc(SafeAcc sacc,Account acc):base(acc) {this.sacc=sacc;} 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);} : To achieve this we must modify code of decorators
25
class SafeAcc : Decorator{ private TestAcc tacc; public SafeAcc(TestAcc tacc,Account acc):base(acc) {this.tacc=tacc;} new public int read_bal(){ Console.Write("Enter 1 to confirm: "); string temp=Console.ReadLine(); int choice=Convert.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 temp=Console.ReadLine(); int choice=Convert.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 temp=Console.ReadLine(); int choice=Convert.ToInt32(temp); if (tacc!=null) tacc.withdraw(amt); else account.withdraw(amt);} }
27
1. Account a = new Account(bal); 2. SafeAcc a = new SafeAcc(null,new Account(20)); Or alternative Account ac=new Account(20); SafeAcc a = new SafeAcc(null,ac); 3.TestAcc a = new TestAcc(null,new Account(20)); 4.Account ac=new Account(20); TestAcc a = new TestAcc(new SafeAcc(null,ac),ac); Can add functionality by adding objects Options
28
Improve 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
29
using System; abstract class Decorator :Account{ protected Account account; public Decorator(Account acc):base(acc){ account=acc;} } class AccInterface{ virtual public int read_bal(){return 0;} virtual public void deposit(int amt){} virtual public void withdraw(int amt){}} :
30
using System; abstract class Decorator :Account{ protected Account account; public Decorator(Account acc):base(acc){ account=acc;} } class AccInterface{ virtual public int read_bal(){return 0;} virtual public void deposit(int amt){} virtual public void withdraw(int amt){}} :
31
class Account:AccInterface{ private int balance; public Account(int b) {balance=b;} public Account(Account acc) {balance=acc.balance;} override public int read_bal() {return balance;} override public void deposit(int amt) {balance +=amt;} override public void withdraw(int amt) {balance -=amt;} }
32
class TestAcc : Decorator{ private SafeAcc sacc; public TestAcc(SafeAcc sacc,Account acc):base(acc) {this.sacc=sacc;} 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
33
public class Ex1{ public static void Main(){ Account ac=new Account(20); AccInterface a = new TestAcc(new SafeAcc(null,ac),ac); int choice=1,amt=0; etc Now we can use Polymorphism to get the same result
34
Now we can use a Factory to decide type of Account
35
public 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 t=Console.ReadLine(); int option=Convert.ToInt32(t); AccInterface a = AccountFactory.createAccount(20,option); int choice=1,amt=0; (as before)
36
class AccountFactory{ static public AccInterface createAccount(int bal,int type){ Account ac=new Account(bal); if (type==1) return ac; if (type==2) return new TestAcc(null,ac); if (type==3) return new SafeAcc(null,ac); else return new TestAcc(new SafeAcc(null,ac),ac); }
37
Nov 2005 MSc Slide 37 Input to Factory
38
public class Ex1{ public static void Main(){ Console.Write("Enter Balance:"); string t=Console.ReadLine(); int bal=Convert.ToInt32(t); AccInterface a = AccountFactory.createAccount(bal); int choice=1,amt=0; : (as before) Could also have a Factory Based on a single parameter
39
class AccountFactory{ static public AccInterface createAccount(int bal){ if (bal < 100) return new Account(bal); else return new SafeAcc(null,new Account(bal)); }
40
Nov 2005 MSc Slide 40 Exercise1: Given the class class Counter{ private int value; public Counter(int v){value=v;} public Counter(Counter cc){ value=cc.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
Nov 2005 MSc Slide 41 (i) class UpperLimit extends Decorator{ same as before except increment will only increment if value <20 otherwise will print out “Too High” Hint: public void increment(){if (counter.read_value()<20) (ii) class LowerLimit extends Decorator{ same as before except decrement will only decrement if value >0 otherwise will print out “Too Low” (iii) Want a factory to decide on the of counter See next Dos screen
42
Nov 2005 MSc Slide 42
43
Nov 2005 MSc Slide 43 Exercise 1(b): Now Modify the Application so the Factory is based on just an initial counter value read in from the Console: - Values < 5 will generate a Normal Counter Object - 5-10 inclusive will generate a LowerLimit Object - 11 -15 an UpperLimit Object - Values > 15 will produce one with both an Upper & Lower Limit
44
Nov 2005 MSc Slide 44 Exercise2: Given the class class Display{ private String name; public Display(String n){name=n;} public Display(Display dd){ name=dd.name;} public void print(){System.out.println("\t"+name);} public void setName(String n){name=n;} } Will Display a name: Now we want to decorate the Display (similar to Account Ex)
45
Nov 2005 MSc Slide 45 Normal Display Athlone UpperLine ******************* Athlone LowerLine Athlone ********************* Upper and Lower Line ******************* Athlone *********************
46
Nov 2005 MSc Slide 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
Nov 2005 MSc Slide 47
48
Nov 2005 MSc Slide 48
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.