1
00:00:01,590 --> 00:00:03,360
Hello, my name is David Berry, and welcome

2
00:00:03,360 --> 00:00:05,290
to this course on the decorator pattern in

3
00:00:05,290 --> 00:00:09,170
C#. The decorator pattern is a Gang of

4
00:00:09,170 --> 00:00:11,530
Four structural design pattern that allows

5
00:00:11,530 --> 00:00:13,820
you to dynamically add behavior to a class

6
00:00:13,820 --> 00:00:16,640
without making changes to that class.

7
00:00:16,640 --> 00:00:18,150
Adding this behavior by using the

8
00:00:18,150 --> 00:00:20,290
decorator pattern allows you to maintain a

9
00:00:20,290 --> 00:00:22,420
strong separation of concerns in your code

10
00:00:22,420 --> 00:00:24,690
base, but also gives you the flexibility

11
00:00:24,690 --> 00:00:27,510
to add, remove or resequence behaviors as

12
00:00:27,510 --> 00:00:30,800
needed. The way that the decorator pattern

13
00:00:30,800 --> 00:00:32,430
works is that you first need to have a

14
00:00:32,430 --> 00:00:34,530
class that you want to add some behavior

15
00:00:34,530 --> 00:00:36,950
to. In this diagram we'll call that class

16
00:00:36,950 --> 00:00:39,150
Component, and this represents the class

17
00:00:39,150 --> 00:00:42,000
that we want to decorate. This class needs

18
00:00:42,000 --> 00:00:43,850
to implement an interface or extend a

19
00:00:43,850 --> 00:00:45,750
common base class that our decorator

20
00:00:45,750 --> 00:00:48,750
classes can also implement or extend. In

21
00:00:48,750 --> 00:00:50,540
practice, it is more common that an

22
00:00:50,540 --> 00:00:52,590
interface is used, so that is what is

23
00:00:52,590 --> 00:00:55,880
shown in the diagram here. Then, your

24
00:00:55,880 --> 00:00:58,760
decorator class will implement this same

25
00:00:58,760 --> 00:01:00,000
interface, and within the method

26
00:01:00,000 --> 00:01:02,540
implementations in your decorator class is

27
00:01:02,540 --> 00:01:04,640
where you can inject any new behavior that

28
00:01:04,640 --> 00:01:07,310
you're looking to add. You also will

29
00:01:07,310 --> 00:01:09,260
define a constructor on your decorator

30
00:01:09,260 --> 00:01:11,380
class that takes an object implementing

31
00:01:11,380 --> 00:01:13,950
the same interface. This allows you to

32
00:01:13,950 --> 00:01:16,590
pass the object being decorated into the

33
00:01:16,590 --> 00:01:19,470
decorator object and ultimately allows the

34
00:01:19,470 --> 00:01:21,980
decorator object to act as a wrapper

35
00:01:21,980 --> 00:01:25,480
around this original object. If you could

36
00:01:25,480 --> 00:01:27,360
visualize what is happening here, it would

37
00:01:27,360 --> 00:01:30,240
look something like this. Your decorator

38
00:01:30,240 --> 00:01:32,220
object will keep a reference to the object

39
00:01:32,220 --> 00:01:34,730
that is being decorated. In this case, the

40
00:01:34,730 --> 00:01:36,940
Component object, and then it can pass

41
00:01:36,940 --> 00:01:39,210
method calls to and from the object as

42
00:01:39,210 --> 00:01:42,000
needed. At the same time, because the

43
00:01:42,000 --> 00:01:43,960
decorator class implements the same

44
00:01:43,960 --> 00:01:45,910
interface as the original Component

45
00:01:45,910 --> 00:01:48,470
object, it now has a chance to intercept

46
00:01:48,470 --> 00:01:50,950
any method calls on the interface and

47
00:01:50,950 --> 00:01:53,040
inject some additional behavior into those

48
00:01:53,040 --> 00:01:56,240
calls. Finally, because the decorator

49
00:01:56,240 --> 00:01:58,270
class has the same interface as the

50
00:01:58,270 --> 00:02:00,900
original Component object does, there's no

51
00:02:00,900 --> 00:02:04,140
need to modify any calling code. So when

52
00:02:04,140 --> 00:02:06,110
you hear the word decorator, it is useful

53
00:02:06,110 --> 00:02:08,650
to think about a diagram like this and

54
00:02:08,650 --> 00:02:10,420
understand that what you're really doing

55
00:02:10,420 --> 00:02:12,440
is designing a series of objects that can

56
00:02:12,440 --> 00:02:15,310
wrap around each other and inject behavior

57
00:02:15,310 --> 00:02:18,690
as needed. I say a series of decorator

58
00:02:18,690 --> 00:02:21,150
objects because you're not limited to just

59
00:02:21,150 --> 00:02:24,100
one decorator object at a time. You can,

60
00:02:24,100 --> 00:02:26,610
in fact, define and use multiple decorator

61
00:02:26,610 --> 00:02:29,010
objects together so you can have a layered

62
00:02:29,010 --> 00:02:30,980
structure around your original object,

63
00:02:30,980 --> 00:02:34,280
much like an onion. Each decorator class

64
00:02:34,280 --> 00:02:36,590
can define different behaviors, so you

65
00:02:36,590 --> 00:02:39,340
maintain that strong separation of

66
00:02:39,340 --> 00:02:41,110
concerns, but again, since all of your

67
00:02:41,110 --> 00:02:42,940
decorator classes implement the same

68
00:02:42,940 --> 00:02:45,560
interface as your original object, you

69
00:02:45,560 --> 00:02:47,230
don't have to change any of your client

70
00:02:47,230 --> 00:02:49,300
code to add in these various new

71
00:02:49,300 --> 00:02:51,510
behaviors. So this is really a very

72
00:02:51,510 --> 00:02:54,900
powerful technique to use. So now that

73
00:02:54,900 --> 00:02:55,980
we've covered some of these initial

74
00:02:55,980 --> 00:02:58,030
principles, let's get familiar with the

75
00:02:58,030 --> 00:02:59,870
example that we're going to use in this

76
00:02:59,870 --> 00:03:02,880
course. In the sample project that we'll

77
00:03:02,880 --> 00:03:04,650
see in a moment, I have a class called

78
00:03:04,650 --> 00:03:06,660
WeatherService that I want to add some

79
00:03:06,660 --> 00:03:09,400
behavior to. This class implements the

80
00:03:09,400 --> 00:03:12,020
IWeatherService interface, and as you can

81
00:03:12,020 --> 00:03:14,490
see, it defines two methods, one for

82
00:03:14,490 --> 00:03:16,210
getting the current weather conditions and

83
00:03:16,210 --> 00:03:17,850
the other for getting the forecast of

84
00:03:17,850 --> 00:03:20,140
future weather conditions. This

85
00:03:20,140 --> 00:03:22,750
WeatherService class is a real service

86
00:03:22,750 --> 00:03:24,600
class. As you'll see in just a moment when

87
00:03:24,600 --> 00:03:27,720
we open up the code, it calls out to the

88
00:03:27,720 --> 00:03:29,400
OpenWeatherMap API to actually get the

89
00:03:29,400 --> 00:03:31,630
appropriate weather data based on a city

90
00:03:31,630 --> 00:03:34,370
name that you provide. What we're going to

91
00:03:34,370 --> 00:03:37,080
do is implement two decorator classes, a

92
00:03:37,080 --> 00:03:38,590
LoggingDecorator class and a

93
00:03:38,590 --> 00:03:41,210
CachingDecorator class, and each of these

94
00:03:41,210 --> 00:03:43,070
represents a typical behavior that you

95
00:03:43,070 --> 00:03:45,260
might want to add to a service class such

96
00:03:45,260 --> 00:03:48,550
as this. Once we have defined our

97
00:03:48,550 --> 00:03:49,800
decorators, we'll need to wire them up in

98
00:03:49,800 --> 00:03:52,840
our code to use them. Initially, we'll see

99
00:03:52,840 --> 00:03:54,960
that the sample application is just newing

100
00:03:54,960 --> 00:03:56,650
up a weather service like the code that

101
00:03:56,650 --> 00:03:58,820
you see at the top of your screen, and

102
00:03:58,820 --> 00:04:00,620
then it just uses that service to get the

103
00:04:00,620 --> 00:04:03,410
data that is needed. What we will

104
00:04:03,410 --> 00:04:05,580
transition to is something like you see at

105
00:04:05,580 --> 00:04:07,900
the bottom of your screen. And here you

106
00:04:07,900 --> 00:04:10,240
can see how these decorator objects wrap

107
00:04:10,240 --> 00:04:12,370
around each other and ultimately around

108
00:04:12,370 --> 00:04:14,600
the WeatherService object to form that

109
00:04:14,600 --> 00:04:17,720
onion‑type structure. This sample code

110
00:04:17,720 --> 00:04:19,620
makes very clear why each of our decorator

111
00:04:19,620 --> 00:04:22,520
classes needs to define a constructor that

112
00:04:22,520 --> 00:04:23,870
takes an object of the type

113
00:04:23,870 --> 00:04:26,110
IWeatherService, and that is so we can

114
00:04:26,110 --> 00:04:28,260
build up this structure as we create these

115
00:04:28,260 --> 00:04:31,000
objects. In addition, you can see the

116
00:04:31,000 --> 00:04:33,180
importance of all of the decorator classes

117
00:04:33,180 --> 00:04:34,810
implementing the IWeatherService

118
00:04:34,810 --> 00:04:37,120
interface, because that allows us to

119
00:04:37,120 --> 00:04:39,200
substitute in this entire structure of

120
00:04:39,200 --> 00:04:41,210
objects, whereas before we just had a

121
00:04:41,210 --> 00:04:43,470
simple WeatherService object because

122
00:04:43,470 --> 00:04:46,340
everything implements that same interface.

123
00:04:46,340 --> 00:04:48,180
So with that, let's go ahead and take a

124
00:04:48,180 --> 00:04:50,430
quick tour of the sample project so we can

125
00:04:50,430 --> 00:04:54,000
start implementing our own decorator classes.

