WEBVTT

00:00.150 --> 00:00.720
Hello again!

00:01.110 --> 00:08.550
In this video, we are going to look at the Handle-Body pattern. When we are writing object-oriented programs,

00:08.910 --> 00:14.580
one of the things we should do is to have a clear separation between the interface to a class and its

00:14.580 --> 00:15.930
implementation details.

00:19.630 --> 00:21.400
So ideally we have something like this.

00:21.400 --> 00:28.300
We have our class with its interface and implementation, and we have some code which interacts with

00:28.300 --> 00:29.500
an object of this class.

00:30.610 --> 00:33.880
The code should only interact with the interface to the class.

00:34.270 --> 00:40.690
So, by calling the public member functions. And the actual inner details of the class - the way that

00:40.810 --> 00:47.380
the functions are implemented, the data members of the class, and so on - should be completely hidden from

00:47.380 --> 00:47.890
the client.

00:49.330 --> 00:54.960
So the interface acts as a kind of firewall, if you like, between the class implementation and code

00:54.970 --> 00:56.020
that uses the class.

00:58.690 --> 01:04.060
The advantage of this is that if we change something in here, the inner details of the class, then

01:04.060 --> 01:05.880
this does not affect the clients.

01:06.400 --> 01:09.090
So we do not need to modify the code in the client.

01:09.610 --> 01:13.000
The only time we need to modify the client is if the interface changes.

01:17.490 --> 01:18.330
In C++,

01:18.330 --> 01:24.990
we do this by putting the class definition in a header and the implementation of the member functions

01:24.990 --> 01:25.920
in a source file.

01:26.700 --> 01:32.850
We use the access specifiers - public, private or protected - to control access to the implementation.

01:33.540 --> 01:35.580
But this is not 100% proof.

01:38.630 --> 01:42.590
There are still some implementation details which are visible to the client.

01:43.190 --> 01:46.340
The client code can see the names of private data members.

01:46.940 --> 01:50.810
It can see prototypes of member functions which are private or protected.

01:51.620 --> 01:56.510
And if we have any member functions which are inline - template member functions, for example - it

01:56.510 --> 01:58.280
can see those definitions as well.

02:00.720 --> 02:03.900
Because of the way that C++ programs are compiled and built,

02:04.350 --> 02:07.830
all client code which uses this class, must include the header.

02:08.910 --> 02:13.620
And, if there are any changes to this header, even if they are completely irrelevant to the client,

02:14.280 --> 02:16.080
then the client code has to be recompiled.

02:17.520 --> 02:20.490
And for large projects, this can be a big problem.

02:21.240 --> 02:26.190
For example, windows.exe, I believe, takes many hours, or even days, to compile.

02:26.790 --> 02:31.470
If you are making some changes to Windows and you want to compile your changes and try them out,

02:31.890 --> 02:36.120
then you really do not want to compile any more code than is absolutely necessary.

02:40.760 --> 02:43.850
The Handle-Body pattern was introduced to address this.

02:44.300 --> 02:47.870
What we do is, in effect, we split the class into two parts.

02:48.410 --> 02:53.360
So we have two new classes, one for the interface and one for the implementation.

02:56.810 --> 02:58.010
So we have something like this.

02:58.010 --> 03:00.410
We have a Handle class which has the interface.

03:00.920 --> 03:03.740
So that is just the public member functions from the class.

03:04.610 --> 03:07.460
And then we have the Body, which has the actual implementation.

03:07.850 --> 03:09.890
So that will be the original class definition.

03:12.130 --> 03:19.030
When we have a client that wants to interact with this class, it will create a Handle object, and

03:19.030 --> 03:24.640
the Handle constructor will create a Body object, and then the object will manage that Body.

03:25.540 --> 03:31.180
When the client calls a public member function in the Handle, the Handle will forward that call

03:31.510 --> 03:33.790
to the same public member function in the Body.

03:35.590 --> 03:40.000
If you know about the Adaptor design pattern, then this is something similar.

03:40.630 --> 03:45.550
The Handle is making the Body appear to be something else to the client.

03:45.970 --> 03:49.000
In this case, the Handle is making the Body appear as though it is not there.

03:49.480 --> 03:52.900
So as far as the client is concerned, the Body is really a ghost.

03:58.530 --> 04:03.120
If you are writing this class, you would have a header for the Handle, which just defines the Handle

04:03.120 --> 04:10.230
class, with the public member functions only. The Body header defines the Body class, so that would have

04:10.230 --> 04:11.910
the full class definition.

04:13.860 --> 04:18.420
Then when you write the client code, this will include the Handle header, which gives them the public

04:18.430 --> 04:20.490
media functions, but not the Body.

04:21.540 --> 04:26.550
If there are any changes to the implementation details, these will only affect Body.h.

04:27.420 --> 04:29.400
Clients do not include Body.h.

04:29.790 --> 04:32.880
So that means that the clients do not need to be recompiled.

04:36.340 --> 04:38.670
The build process will look something like this.

04:38.710 --> 04:42.400
So we have our Body code, which is in its own little world.

04:43.210 --> 04:45.790
We have the client, which includes the Handle, but not the Body.

04:46.390 --> 04:51.460
So we can do what we like with the Body code, and the client will not need to be compiled.

04:53.210 --> 05:00.230
When we compile and link the program, that will introduce the binary code for the Body into the program binary.

05:00.800 --> 05:05.090
So the client code will be able to call the functions from the binary object.

05:07.070 --> 05:12.710
This is so-called "static" linking, in which all the binary code is combined into a single binary

05:12.710 --> 05:13.400
executable.

05:13.970 --> 05:20.210
There is actually something called "dynamic" linking, which allows us to take this one step further. In

05:20.210 --> 05:21.350
dynamic linking.

05:21.680 --> 05:25.430
We compile the Body code into its own shared library.

05:25.820 --> 05:30.800
So that's a shared object in UNIX terms, a DLL in Windows terms.

05:31.730 --> 05:37.280
And then, when the program runs, the program binary will load up the code from this library.

05:37.850 --> 05:42.230
So that makes the code from the Body available to the client, at run time.

05:43.250 --> 05:48.410
If you are a company which is selling products and you have an update, but you have only changed the code

05:48.410 --> 05:54.050
in the Body - the implementation of this class - then you can just send your customers a new version

05:54.050 --> 05:54.800
of the DLL.

05:55.340 --> 06:00.350
You do not need to have to deliver a new version of the binary, and get your customers to reinstall it.

06:02.060 --> 06:03.460
Okay, so that is it for this video.

06:03.820 --> 06:08.030
We will have some examples in the next video, but until then, keep coding!
