Decorator Design Pattern
Decorator Design Pattern
E"ample
Consider you have a following computer class with a description method:
1.1/
A ter some time you need to add to the description method a disk0
2.1/
#n this way i you need again and again modi ication to your class then it is di icult to manage since you need to touch the actual class again and again. To sol'e the a!o'e pro!lem$ Decorator pattern comes as a rescue. The design pattern suggests you to create a wrapper class and place the instance o the class to the wrapper class and wrapper class allow you to add new unctionality i.e. changing the description method. #n this way you do not need to modi y the computer class.
2.1/
Solution #n order to sol'e the a!o'e pro!lem you can design the classes as ollows0
3ere 4onitor description method calls Disk description method and Disk description method in turn call )omputer method. 3ow to code the a!o'e Decorator design pattern. o )omputer class which has a minimal description
4.1/
o &e need a !asis o Decorator class which is the a!stract class as well as the deri'ed class rom the main )omputer class.
o &hen Disk come to the ta!le then we can design Disk decorator as ollows0
5.1/
o Similarly i you need another Decorator e.g. )D then you can design that as ollows0
o Similarly i you need another Decorator e.g. 4onitor then you can design that as ollows. Do not orget that in the constructor you can pass )D o!"ect or )omputer c parameter since )D is itsel a )omputer type.
+.1/
o The ollowing way you can use the decorator patterns in the claient program.
o The output will !e 6 1ou are getting a computer and a disk and a monitor and a )D and a )D
The idea !ehind a decorator pattern is that you can customi7e your o!"ects !y adding multiple wrappers o'er and o'er again e'en the same wrapper twice or more times.
So using Decorator pattern you can customi7e your o!"ect each time using a wrapper without modi ying your codes.
-.1/
Decorator Applica!ility
&hen you need to add responsi!ilities to indi'idual o!"ects 6 6 dynamically and transparently$ that is$ without a ecting other o!"ects responsi!ilities that can !e withdrawn
when e%tension !y su!classing is not practical 6 large num!er o independent e%tensions are possi!le and would produce an e%plosion o su!classes to support e'ery com!ination 6 a class de inition may !e hidden or otherwise una'aila!le or su!classing
Decorator Ad'antages
Pro'ide an alternati'e to su!classing. 8esponsi!ilities can !e added . remo'ed at run9time !y attaching and detaching them Pro'iding di erent Decorator classes or a speci ic )omponent class lets you mi% and match responsi!ilities *asy to add a property twice Pay9as9you9go approach o don:t !loat$ !ut e%tend using ine9grained Decorator classes Functionality can !e composed rom simple pieces o thus$ an application does not need to pay or eatures it doesn:t use A ine9grained Decorator hierarchy is easy to e%tend
Decorator Disad'antages
,.1/
;ots o ;ittle <!"ects o a design that uses Decorator o ten results in systems o composed o lots o little o!"ects that all look alike o o!"ects di er only in the way they are interconnected$ not in their class or in the 'alue o their 'aria!les o these systems are easy to customise !y those who understand them$ they can !e hard to learn and de!ug
E"ample
)onsider a situation where we need a data!ase connection depending on the user@s choice0 (#( &eek 1$ )S* +0,-
/.1/
#n one way you can sol'e the a!o'e pro!lem using the ollowing unction0
#n the a!o'e$ <racle)onnection$ S>lSer'er)onnection etc. need to !e same class as )onnection which Factory Design Pattern Pro'ides.
Solution #rom $a!tory %attern 1ou need a actory pattern to make the !etter solution or the a!o'e pro!lem. #n the Factory Pattern$ a actory method de ines what unctions must !e a'aila!le in the non9a!stract or concrete actory. These unctions must !e a!le to create o!"ects that are e%tensions o a speci ic class. &hich e%act su!class is created will depend on the 'alue o a parameter passed to the unction. The irst 'ersion o the Factory class is as ollows$ The )reate)onnectionE? is called creational method. &e need to make the )onnection a!stract class in order to support )reate)onnectionE? method o Factory Design Pattern
10.1/
Gow ha'e a look how Factory Design Pattern pro'ides the solution. o Step 1: Abstract class of the class that Factory creates
11.1/
o Step 3: The following way you can test the above factory design pattern.
12.1/
So the idea here is that the code which changes a lot when design changes Ein our case )reate)onnectionE??$ e%tract that code and put into a Factory class and that Factory is responsi!le to create o!"ects.
12.1/
allowed to update the 'alues o the 'alue o!"ect itsel 9 updata!le 'alue o!"ects lead to aliasing pro!lems. #n n9tier so tware architecture 'alue o!"ect pattern is applied when data is trans erred rom data!ase to H< E'alue o!"ect tier?.
E"ample
)onsider a tool !o% class in php which carries only nails.
//ToolBox.php class ToolBox { private $_nails; public function getNails() { return $this- _nails; ! public function setNails(Nails $nails) { $this- _nails " $nails; ! ! //Nails.php class Nails { private $_#uantit$; public function __construct($#uantit$) { $this- _#uantit$ " (int) $#uantit$; !
14.1/
public function a%%(Nails $nails) { $this- _#uantit$ &" $nails- count(); ! public function count() { return $this- _#uantit$; ! private function __to'tring() { return (string) $this- _#uantit$; ! !
//testtoolBox.php $($ToolBox " ne) ToolBox; $$ourToolBox " ne) ToolBox; //*sing t)ent$ Nails $t)ent$Nails " ne) Nails(+,); //'tart out )ith e#ual nu(ber of nails. $($ToolBox- setNails($t)ent$Nails); $$ourToolBox- setNails($t)ent$Nails); //-ere.s another /,, nails. $$ourToolBox- getNails()- a%%(ne) Nails(/,,)); echo 01our nails2 {$$ourToolBox- getNails()!3br/ 0; echo 04$ nails2 {$($ToolBox- getNails()!3br/ 0;
1ou pro!a!ly already noticed that pro!lem is that we are !oth using the same Gails o!"ect. #n this case the pro!lem may !e easy to spot and a'oid$ !ut as your application !ecomes !igger$ pre'enting this type o mishap can sa'e you a huge headache. Another mayor !ene it o using Halue <!"ects is they ena!le you to encapsulate type9speci ic operations. 4artin Fowler does a great "o! at demonstrating this with his 4oney pattern$ which encapsulates the handling o rounding currency.
15.1/
The key to creating Halue <!"ects is making them immuta!le. =ecause Halue <!"ects@ e>uality don@t depend on their identity$ simply creating a new o!"ect when the 'alue changes$ accomplishes this using the ollowing code0
public function a%%(Nails $nails) { return ne) Nails($this- _#uantit$ & $nails- count()); ! //-ere.s another /,, nails. $$ourToolBox- setNails( $$ourToolBox- getNails()- a%%(ne) Nails(/,,)) );
&a' E"er!ise
Ji'en the ollowing code$ complete the code or a =oatFactory class so it can !e used to create !ig and small !oat o!"ects0
pu!lic inter ace =oat K int ma%)apacityA int topSpeedE ? L class )ruiseShip implements =oat K .. !ig !oat int topSpeedE ? K return 20A L L class Speed=oat implements =oat K .. small !oat int topSpeedE ? K return 40A L L =oat my=ig=oat M =oatFactory. =oat mySmall=oat M =oatFactory.createEBsmallC?A pu!lic class =oatFactory K static =oat createEString s? K .. your code here i# (s)e*uals(+'ig,-return ne. CruiseS/ip( -0
1+.1/
else i# (s)e*uals(+small,-return ne. Speed1oat( -0 else return null0 22 error L L (sing the same code$ use the Decorator design pattern to
i. Add a =oatDecorator class implementing the =oat inter ace pu'li! !lass 1oatDe!orator implements 1oat 3 1oat '0 1oatDe!orator (1oat '- 3 t/is)' 4 '0 5 int topSpeed( - 3 return ')topSpeed( -0 5 5 ii. )reate two =oatDecorators with=arnacleE ? and withTur!o*ngineE ? that change the result returned !y topSpeedE ? !y 61 and N10$ respecti'ely pu'li! !lass .it/1arna!le( - e"tends 1oatDe!orator 3 int topSpeed( - 3 return ')topSpeed( - - 60 5 5 pu'li! !lass .it/Tur'oEngine( - e"tends 1oatDe!orator 3 int topSpeed( - 3 return ')topSpeed( - 7 600 5 5
#nstall so tware Access network Su!mit coursework solution Pu!lish coursework pro!lem
O O
O O
O O
1-.1/
A mem!er o your team has proposed an initial design which is shown in Figure 1. &ith this design$ the a!stract superclass Operator is intended to !e su!9classed with concrete classes representing particular roles. The Operator class pro'ides a de ault implementation o the isAuthorizedTo() method which simply returns false. The concrete su!classes o'erride this method and depending on the String argument 'alue$ return true or false indicating whether instances o the class ha'e permission to do what is descri!ed !y the String argument. For e%ample$ calling isAuthorisedTo() with the argument install software on an Administrator instance would return trueA calling the method with the same argument on a Student or Lecturer o!"ect would return false.
$igure 6 Initial design The proposed design$ howe'er$ su ers rom a undamental weakness. &ithin the (ni'ersity$ a single indi'idual may play se'eral roles. For e%ample$ one person might play the ;ecturer role and teach undergraduate students. The same person might also !e studying part time or a postgraduate degree. #n this case$ the person will re>uire access rights or !oth pu!lishing coursework and su!mitting coursework. &ith the e%isting design$ a person can only !e represented !y an instance o one o the three concrete su!classes and is there ore constrained to play a single role. 1ou raise this pro!lem with your team. Another mem!er responds and points out that the pro!lem is easily sol'ed !y creating additional su!classes to cater or all the com!inations o roles. Speci ically$ this means de ining 2 additional su!classes0 LecturerAndStudent$ LecturerAndAdministrator$ and StudentAndAdministrator. To cater or an indi'idual playing all three roles$ a urther su!class LecturerAndStudentAndAdministrator would !e re>uired. 1ou think a!out this suggestion or a moment and it doesn@t take you long to see that it@s unattracti'e. First$ it would !e error9prone to maintain since i the access rights change or one role$ you will ha'e to edit the source iles or our classes. For e%ample$ adding a new pri'ilege or students$ such as allowing them access to ile sharing ser'ices Elikely to !e used or sharing music ilesP? would in'ol'e editing the Student$ LecturerAndStudent$
1,.1/
and LecturerAndStudentAndAdministrator classes. #t then occurs to you that the pro!lem would !e e%acer!ated i at a later date you wanted to introduce a new role$ such as Secretary. To cater or all possi!le com!inations now would re>uire many more su!classes. And what i urther new roles needed to !e accommodated a ter thatF )learly the e%ponential growth in the num!er o concrete su!classes is unmanagea!le.
StudentAndAdministrator
1ou air your thoughts to your team mem!ers. They are impressed !y your analysis !ut look to you or a solution. 1ou >uickly consider each o the design patterns you know a!out$ !ut none o them seem to tackle this seemingly generic pro!lem. A !rie search on the #nternet using Joogle with the terms Bsu!class e%plosionC and Bdesign patternC returns a host o links which ha'e in common the Decorator design pattern. The Decorator pattern looks promising Q
T/e tas8
#n'estigate the Decorator design pattern and apply it to de'elop an alternati'e design to the access control pro!lem. 1our design should address the pro!lems inherent in the original design. The e%am >uestion will assess your understanding and application o the pattern and thus re>uires that you do the necessary preparatory work prior to the e%am.
1/.1/