- Decorator pattern attach additional functionalities or responsibility to an existing object at the runtime.
- It adds new behaviour to an individual object without affecting other objects of the same class.
- New behaviour or functionalities can be added dynamically at the run time
Consider you are developing
student management application. First you’re creating
basic responsibility to
handle and print information like name, age, gender & grade etc…
After a while you have got a new
requirement to add functionality to maintain lab reports
for science students.
Basically how will do this? May be extend the Student class to create
ScienceStudent
subclass for this responsibility. It’s good enough for this requirement.
You have got another requirement
to add functionality to maintaining game reports for
sports students. Again you
may want to extend the Student class to create a
SportsStudent subclass for
this responsibility.
You have got another requirement
to maintain information of the student who is studying
science and also playing
sports. You will have to maintain lab reports, game reports
along with name,
age, gender and grade. You have already created two subclass's for
science students and sports students, but there is no way you can reuse them in this
scenario. You are left with no option but to create a subclass for
ScienceSportsStudent and
this is a problem. How many subclasses you keep
creating? Decorator pattern solves this
problem.
Sample Demo Diagram:
Final Output:
Click here to download sample program
If you like this post. Kindly share your valuable comments.
UML Diagram:
Drawbacks:
- Decorators can cause issues if the client relies heavily on the components concrete type
- Decorators can complicate the process of instantiating the component because you not only have to instantiate the component but wrap it in a number of decorators
- It can be complicated to have decorators keep track of other decorators because to look back into multiple layers of the decorator chain starts to push the decorator pattern beyond it’s true intent
Sample Demo Program:
The following participant are involved in given program
The following participant are involved in given program
1.
Component
– This is the base interface of actual or concrete object. In this object
additional functionalities will be added dynamically. In implementation, it
could be an abstract class or interface
2.
Concrete Component:
This is the actual object in which additional functionality will be added.
In implementation, it would implement or extend the component
3.
Decorator
– This is the interface of all the dynamic functionalities that would be added
to the component. It maintains reference of the component object and defines
interface for new dynamic functionalities.
4.
Concrete
Decorator – This will add dynamic functionalities to the component.
Entire Code Structure:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | using System; namespace DecoratorPattern { /// <summary> /// Student Component /// </summary> public abstract class Student { public abstract string DisplayStudentInformation(); } /// <summary> /// concrete component for student /// </summary> public class StudentConcrete : Student { public string Name { get; set; } public int Age { get; set; } public string Gender { get; set; } public string Grade { get; set; } public override string DisplayStudentInformation() { string whois = ((Gender == "Male") ? "He" : "She"); return Name + ". " + whois + " is " + Age + " years old. " + "Grade is " + Grade + "."; } } /// <summary> /// base student decorator for all dynamic functionalities /// </summary> public class StudentDecorator: Student { Student baseStudent = null; protected StudentDecorator(Student s) { baseStudent = s; } public override string DisplayStudentInformation() { string baseStudentInformation = baseStudent.DisplayStudentInformation(); return baseStudentInformation; } } /// <summary> /// science student concrete decorator for dynamic functionality /// </summary> public class ScienceStudentDecorator : StudentDecorator { public string Labs { get; set; } public ScienceStudentDecorator(Student baseStudent) : base(baseStudent) { } public override string DisplayStudentInformation() { var result = base.DisplayStudentInformation(); result = result + " Labs are " + Labs + "."; return result; } } /// <summary> /// sports student concrete decorator for dynamic functionality /// </summary> public class SportsStudentDecorator : StudentDecorator { public string Games { get; set; } public SportsStudentDecorator(Student baseStudent) : base(baseStudent) { } public override string DisplayStudentInformation() { var result = base.DisplayStudentInformation(); result = result + " Games are " + Games + "."; return result; } } class Program { static void Main(string[] args) { //normal student StudentConcrete stdKumar = new StudentConcrete { Name = "Kumar", Age = 10, Gender = "Male", Grade = "B" }; var stdKumarInformation = stdKumar.DisplayStudentInformation(); Console.WriteLine("---------------------Normal Student--------------------"); Console.WriteLine(stdKumarInformation); //science student StudentConcrete stdKavitha = new StudentConcrete { Name = "Kavitha", Age = 10, Gender = "FeMale", Grade = "A" }; ScienceStudentDecorator stdScienceKavitha = new ScienceStudentDecorator(stdKavitha) { Labs = "Computer Science, Biology" }; var stdScienceKavithaInformation = stdScienceKavitha.DisplayStudentInformation(); Console.WriteLine("\n---------------------Science Student--------------------"); Console.WriteLine(stdScienceKavithaInformation); //games student StudentConcrete stdArun = new StudentConcrete { Name = "Arun", Age = 10, Gender = "Male", Grade = "C" }; SportsStudentDecorator stdSportArun = new SportsStudentDecorator(stdArun) { Games = "Cricket, Football" }; var stdSportsArunInformation = stdSportArun.DisplayStudentInformation(); Console.WriteLine("\n---------------------Sport Student--------------------"); Console.WriteLine(stdSportsArunInformation); //science & sports student StudentConcrete stdMani = new StudentConcrete { Name = "Mani", Age = 10, Gender = "Male", Grade = "A" }; ScienceStudentDecorator stdScienceMani = new ScienceStudentDecorator(stdMani) { Labs = "Computer Science, Biology" }; SportsStudentDecorator stdSportScienceMani = new SportsStudentDecorator(stdScienceMani) { Games = "Cricket, Football" }; var stdSportScienceManiInformation = stdSportScienceMani.DisplayStudentInformation(); Console.WriteLine("\n---------------------Science & Sport Student--------------------"); Console.WriteLine(stdSportScienceManiInformation); Console.Write("\nPress any key to exist..."); Console.ReadKey(); } } } |
Final Output:
Click here to download sample program
If you like this post. Kindly share your valuable comments.
Awesome
ReplyDelete