We have mentioned that abstraction was one of the most important concepts in programming.  Encapsulation is an equally important concept. Encapsulation is a technique by which we divide our code into distinct modules and restrict what variables, constants, and subroutines are visible to other modules. Encapsulation helps tremendously in debugging and development because it allows parts of a large program to be treated as separate entities and developed independently. We have already seen some examples of encapsulation. The local variables of subroutines are encapsulated within the subroutine. Imagine if we could declare only global variables. If we used a global K as a control variable in a subroutine and then included it in a loop elsewhere in the program where we also used the same variable K, the two would interfere with each other and result in a bug that might be quite difficult to spot. Modular design also helps us understand the code. As a general rule, the more divided code is into subroutines the better. This is for a number of reasons. First, subroutines can be named. Which of the following examples of code is easier to understand at first glance, the one on the left or the one on the right?
program NoModularity;
var
  Buf : Integer;
  K,J : Integer;
begin
  for K := 1 to 10 do
  begin
    Buf := 1;
    for J := 1 to 3 do Buf := Buf*K;
    Writeln(Buf);
  end;
  Readln;
end.
program Modularity;

function Power(Base : Integer;
  Pow : Integer) : Integer;
var
  K : Integer;
begin
  Result := Base;
  for K := 1 to Pow-1 do
    Result := Result*Base;
end;

var
  K : Integer;
begin
  for K := 1 to 10 do
    Writeln(Power(K,3));
  Readln;
end.
Both of these programs do the exact same things. The one on the left is shorter, but the one on the right makes it immediately obvious that we are listing the first 10 cubes. So, using subroutines with descriptive names provides a bit of documentation for the program without writing a single comment. This is obviously a very nice feature. There is one caveat to dividing code into many subroutines, however. Each call to a subroutine takes a short amount of time because the processor has to move from one location in the code to some other location to execute the subroutine and then must move back to the original location. This amount of time is generally so insignificant that one never needs to worry about it. However, if we are writing a performance critical section in a program, say a loop that iterates a billion times for example, we should include as few subroutines as possible in such a section. This is because the short amount of time can easily add up if it is repeated billions or trillions of times. Though for 99% of situations this is never the case.

In addition to subroutines, another form of modularity is the division of a program into units. Units are collections of variables, constants, subroutines, etc. that are grouped in a separate source file from the main program. Grouping code into different source files has 2 major advantages. The first is that code can be reused among a number of different programs. The second is that the code of a large program is easier to navigate. If you have several thousand lines of code that do not need to be directly worked on, it is preferable to have them in separate source files so that you can focus on the code that you are currently working on. The division of a program into multiple source files can also be accomplished using the include compiler directive {$I Filename} , but this should be avoided except in rare cases. The reason is that including source with $I actually copies the source into the location of the directive. If you use the same set of procedures 5 times in different parts of a program and include that procedure with $I you are repeating code which simply makes the executable program larger. However, by using a unit, the compiler includes the code only once and passes references to all other locations in the code where parts of the unit are called.

Units are defined in similar ways to programs. They can have global variables and constants like programs and can contain subroutines. The main difference between units and programs is that units in Object Pascal have an interface section and an implementation section. The interface section contains declarations only. It defines the visibility of everything in the unit. Anything not declared in the interface section will not be visible to any other code that uses that unit. The implementation section contains the actual code that defines what subroutines do. The implementation section can also contain declarations, but anything declared in the implementation section is not visible to other code that uses the unit (unless it was declared first in the interface section). The following is an example of a unit:
unit SomeUnit;
interface

function Power(Base : Integer; Pow : Integer) : Integer;

implementation

function Power(Base : Integer; Pow : Integer) : Integer;
var
  K : Integer;
begin
  Result := Base;
  for K := 1 to Pow-1 do
    Result := Result*Base;
end;


end.
Note that the subroutine Power appears to be declared twice. This is because the first declaration in the interface tells the compiler that other parts of the code should be able to call Power and the second declaration in the implementation tells the compiler that this is where the subroutine Power will be defined. The implementation declaration must match the interface declaration.

Units are saved as plain text files with the file extention .pas. They can be included into programs by writing a uses clause at the beginning of the program:
program Modular;
uses SomeUnit;
var
  K : Integer;
begin
  for K := 1 to 10 do
    Writeln(Power(K,3));
  Readln;
end.
Units do not have begin..end blocks because they are not stand-alone programs. In other words, you can compile a unit but you can never run a unit by itself. Units always must be included as part of a program. There are some cases in which one wants to do some initialization or finalization of variables in a unit and Object Pascal provides this functionality:
unit SomeUnit;
interface

VAR
  BaseDirectory : String;

implementation

initialization
  Write('Enter a current working directory: ');
  Readln(BaseDirectory);
end.