1
00:00:01,140 --> 00:00:02,890
The decorator pattern is not just using

2
00:00:02,890 --> 00:00:05,030
the code we write as developers, but is

3
00:00:05,030 --> 00:00:07,350
used within .NET itself. And a prime

4
00:00:07,350 --> 00:00:09,650
example of this is the Stream class and

5
00:00:09,650 --> 00:00:11,300
other associated classes related to

6
00:00:11,300 --> 00:00:13,890
working with streams in .NET. Let's take a

7
00:00:13,890 --> 00:00:16,290
look at these. At the top of the

8
00:00:16,290 --> 00:00:18,440
hierarchy, we have the Stream class. This

9
00:00:18,440 --> 00:00:20,290
is an abstract class and requires you to

10
00:00:20,290 --> 00:00:21,910
provide implementations for several

11
00:00:21,910 --> 00:00:24,070
methods. But the most important of these

12
00:00:24,070 --> 00:00:26,850
are the Read and Write methods. Even

13
00:00:26,850 --> 00:00:28,650
though this is an abstract class, this

14
00:00:28,650 --> 00:00:30,420
would be equivalent to the interface we

15
00:00:30,420 --> 00:00:33,010
used in our previous examples. The Stream

16
00:00:33,010 --> 00:00:35,150
class defines the abstraction that each

17
00:00:35,150 --> 00:00:38,160
implementation has to fulfill. Then you

18
00:00:38,160 --> 00:00:40,130
have several concrete implementations of

19
00:00:40,130 --> 00:00:42,230
the Stream class, including FileStream,

20
00:00:42,230 --> 00:00:44,900
MemoryStream, and NetworkStream. These are

21
00:00:44,900 --> 00:00:46,750
the classes that do the actual work of

22
00:00:46,750 --> 00:00:48,700
reading and writing bytes to and from

23
00:00:48,700 --> 00:00:51,200
these different sources. Each of these

24
00:00:51,200 --> 00:00:52,940
classes would be equivalent to the Service

25
00:00:52,940 --> 00:00:55,900
class that we saw in the last example.

26
00:00:55,900 --> 00:00:58,040
Finally, we have a number of classes that

27
00:00:58,040 --> 00:01:00,410
act is decorators. These include the

28
00:01:00,410 --> 00:01:02,750
BufferedStream, GZipStream, and

29
00:01:02,750 --> 00:01:05,890
CryptoStream classes. These classes all

30
00:01:05,890 --> 00:01:08,210
derive from the Stream class, all take a

31
00:01:08,210 --> 00:01:10,620
Stream class in their constructor, and all

32
00:01:10,620 --> 00:01:13,860
modify the stream in some way. For

33
00:01:13,860 --> 00:01:15,780
example, the BufferedStream will buffer

34
00:01:15,780 --> 00:01:18,000
data as you read or write from a stream,

35
00:01:18,000 --> 00:01:19,630
rather than reading or writing just a

36
00:01:19,630 --> 00:01:22,640
single byte at a time. The GZipStream will

37
00:01:22,640 --> 00:01:24,440
decompress or compress data as it's

38
00:01:24,440 --> 00:01:26,130
processed. And the CryptoStream will

39
00:01:26,130 --> 00:01:28,890
encrypt or decrypt data. You can use all

40
00:01:28,890 --> 00:01:30,480
of these classes individually or in

41
00:01:30,480 --> 00:01:32,580
conjunction with one another, but you will

42
00:01:32,580 --> 00:01:35,250
always use these classes with a concrete

43
00:01:35,250 --> 00:01:39,060
stream. This simple program takes a string

44
00:01:39,060 --> 00:01:41,820
and writes it to a file. But in doing so,

45
00:01:41,820 --> 00:01:43,740
it is using the CryptoStream class to

46
00:01:43,740 --> 00:01:45,940
encrypt the data in that file, and the

47
00:01:45,940 --> 00:01:47,570
BufferedStream class to improve

48
00:01:47,570 --> 00:01:49,430
performance by buffering the data before

49
00:01:49,430 --> 00:01:52,120
it's written. You can see here the same

50
00:01:52,120 --> 00:01:54,550
wrapping behavior that we saw before where

51
00:01:54,550 --> 00:01:56,380
CryptoStream and BufferedStream are

52
00:01:56,380 --> 00:01:59,030
wrapping around our FileStream object and

53
00:01:59,030 --> 00:02:00,520
adding their respective pieces of

54
00:02:00,520 --> 00:02:03,170
functionality. While the classes

55
00:02:03,170 --> 00:02:05,050
CryptoStream, GZipStream, and

56
00:02:05,050 --> 00:02:06,440
BufferedStream don't have the word

57
00:02:06,440 --> 00:02:08,670
decorator in their names, that is what

58
00:02:08,670 --> 00:02:11,090
they are, decorator classes because they

59
00:02:11,090 --> 00:02:14,000
extend the same common base class, Stream,

60
00:02:14,000 --> 00:02:15,960
they take an instance of a Stream object

61
00:02:15,960 --> 00:02:17,980
as part of their constructor, and they add

62
00:02:17,980 --> 00:02:20,000
new behaviors to the stream that they're

63
00:02:20,000 --> 00:02:23,720
wrapping. Plus, CryptoStream, GZipStream,

64
00:02:23,720 --> 00:02:25,850
and BufferedStream work with any concrete

65
00:02:25,850 --> 00:02:28,170
stream you have, whether it's a file,

66
00:02:28,170 --> 00:02:30,700
working with a MemoryStream, or data over

67
00:02:30,700 --> 00:02:33,470
a network. So the takeaway of all of this

68
00:02:33,470 --> 00:02:35,730
is that the decorator pattern is a pattern

69
00:02:35,730 --> 00:02:37,480
that you'll not just see in using your

70
00:02:37,480 --> 00:02:39,680
code, but you'll also see it used in

71
00:02:39,680 --> 00:02:44,000
frameworks and libraries across the .NET ecosystem.

