A Beginner’s Guide to Object-Oriented Programming with Apex: 1. Encapsulation

This is part 2 in the series “A Beginner’s Guide to Object-Oriented Programming with Apex” and will cover the aspect of Encapsulation.

A Beginner’s Guide to Object-Oriented Programming with Apex

  1. Introduction
  2. Encapsulation (this post)
  3. Abstraction
  4. Polymorphism

What the hell is Encapsulation?

Encapsulation isn’t a tricky concept in itself but some confusion does arise from it’s close relationship with Abstraction (to be covered in my next post). Broadly it is defined as one of, or both of the following:

  1. An information hiding mechanism.
  2. A bundling of data and methods that operate on that data.

These are pretty abstract statements but in reality are very simple. I will demystify them with examples below but for now let’s use an analogy:

Imagine you have a watch (or if you have one just consider it, don’t worry about the imagining part) that tells you the date and time. You can adjust the date and time using buttons/knobs/switches but you have no idea what happens inside the watch, just that it results in the date and time changing. You have some data (the date and time), you have some methods to operate on that data (buttons/knobs/switches) and there is a whole lot of stuff going on in the background that you don’t know about (and it’s better that way, imagine you had to adjust all those bits and pieces yourself).

That’s encapsulation baby!

What does “An information hiding mechanism” mean?

This statement essentially means that some data is hidden from the consumer of the service provided e.g.

  • You have a VF page that has a button that is used to calculate the cost of an item.
  • Calculating the cost is done in the page controller and requires a number of different values used in a complex calculation.
  • The page doesn’t need to “see” the variables or know how the calculation works, and in fact you want to prevent anyone from messing with the variable values.
  • Thus we make the calculated value available to the page (or any other consumer) and hide everything else.

What does “A bundling of data and methods that operate on that data” mean?

This definition is even easier to understand, it’s simply stating that a piece of code should be grouped together with the data and actions important to that code’s purpose. This will become more clear with the example below.

How do we Encapsulate?

Fulfilling the two requirements of encapsulation with Apex is a cinch. The language mechanisms available are:

I’ve linked to the relevant documentation for each since they’re great and I encourage you to bookmark them as they’re core to OOP in Apex. Time to look at an example.

Below is a class that encapsulates the functionality of making an HTTP callout. I’ve numbered the comments and the corresponding explanations follow the code.

/*
 * 1. HttpService - demonstrate the concept of Encapsulation
 */
public Class HttpService {
 
    // 2. Private variables cannot be accessed by other code outside of this class.
    // Those marked as "final" are reference values
 
    private final String HEADER_PROP_AUTH     = 'Authorisation';
    private final String HEADER_PROP_USERNAME = 'Username';
    private final String HEADER_PROP_PWD      = 'Password';
 
    private String baseUrl = 'http://example.com';
 
    /*
     *  3. Public Methods
     */
 
    // 4. Public method that allows consumers of this service class to build an HttpRequest object
    public HttpRequest buildRequest(String url, String method, Map<String, String> headerProperties) {
         HttpRequest req = new HttpRequest();
 
        req.setMethod(method);
        req.setEndpoint(url);
 
        for(String property: headerProperties.keySet()){
            String value = headerProperties.get(property);
 
            // 5. A special action is required for the auth header value
            if (property == HEADER_PROP_AUTH){
                value = buildAuthHeader(headerProperties);
            } 
 
            req.setHeader(property, value);
        }
 
        return req;
    }
 
    // 8. This is an "overloaded" method with a simple signature for convenience i.e.
    // it defaults the value for the URL.
    public HttpRequest buildRequest(String method, Map<String, String> headerProperties){
        return buildRequest(baseUrl, method, headerProperties);
    }
 
    //  ... more public methods to do with the HTTP service go here. They have been omitted for
    //  brevity ...
 
     /*
      *   6. Private Methods
      */
 
    // 7. Private method used to build the authentication header. This method is only available to
    // other methods of this class.
    private String buildAuthHeader(Map<String, String> headerProperties){
        String username = headerProperties.get(HEADER_PROP_USERNAME);
        String pwd = headerProperties.get(HEADER_PROP_PWD);
 
        Blob headerValue = Blob.valueOf(username + ':' + pwd);
 
        String authorisationHeader = EncodingUtil.base64Encode(headerValue);        
 
        return authorisationHeader;
    }
}

The numbers below correspond with the numbers in the comments in the code above.

  1. The very foundation of encapsulation is the concept of a Class. A mechanism for collecting data and functionality that belongs together given the context of the problem we’re trying to solve.
  2. The access modifier “Private” guarantees that these variables can’t be read from or written to from outside of this class. They are “hidden”.
  3. The public methods provide a mechanism for other classes to access the functionality and data that this class wants to share.
  4. I have omitted the other methods you would need for a full-blown HttpService since this method illustrates the point.
  5. A point of interest in that for the Auth header property a special action is required. However the fact that this needs to occur is not relevant to the consumer of this method i.e. it is hidden.
  6. As with the private variables, methods marked as “private” cannot be seen outside of this class.
  7. Data is transformed into new data within this method, but that secret is only known within this class.
  8. Overloading isn’t a facet of encapsulation but it’s a neat trick. This overloaded method has one less parameter than the other method, a small convenience to spare your finger joints.

Why Should I Use Encapsulation?

  • Provides namespaces/unique names for application data and functionality making code more manageable e.g. in the old days when classes didn’t exist and all your code would be lumped together you could only have one function called calculate(). With classes you can group functionality into classes and not have to think up crazy and creative names for your variables and methods e.g. Tax.calculate() and IQ.calculate().
  • Protecting data that is read-only or irrelevant to the consumer.
  • Control over how variables are managed e.g. validating input before assigning it to a variable.
  • Code is easier to read, maintain and extend.
  • OOP is impossible without it!

If you’re a developer you’ve probably been using Encapsulation without even knowing it. Hopefully this post has formalised your knowledge and filled in a few gaps. Onwards and upwards! Next time I’ll be writing about Abstraction.

6 thoughts on “A Beginner’s Guide to Object-Oriented Programming with Apex: 1. Encapsulation”

Leave a Comment