A quick review of Encapsulation using Duff's Beer as an example

What is encapsulation?

One thing it isn’t, but is similar to: Using dogs swimming in beer for flavoring. In this case this would be the hiding of the fact that dogs are used to flavor Red-Tick beer, unlike Duff’s beer (the beer Homer Simpson loves) which uses the usual natural and manmade processes of beer making. See hiding the fact that dog’s are used to add the flavor is a type of encapsulation. Ok, it’s a stretch. 

So a strict definition of:

Encapsulation is a feature that allows classes to hide implementation details. And at Duff’s Beer, it is a really good idea to hide implementation, they don’t have coffee breaks they have beer breaks! Generally, you should hide the internal state of your object from direct access from outside code. If you use the ‘public’ keyword, then the object can be accessed or used by any class. This is good and this is bad.

When it is good, you determine that is good during the requirements and design phase.

When it is bad, again you determine this during the requirements and design phase, and sometimes during the testing phase, or when it is worse during the deployment phase.

Hiding the internal state of your object from direct access from outside code is a good design practice. You do this by the implementation of other members: properties and methods. These properties wrap the state that you are generating with your code.

This wrapping of state allows the internal implementation of the state to change at will, while the members wrapping the state can still return a representation of the state that doesn't change.

Outcomes of the wrapping is that the outside or external code:

  • Will access your object via members that wrap state
  • Is guaranteed that the type of information extracted is consistent
  • Does not have access to the internal state of your object
    • This means that the outside code can not alter that state in an inconsistent manner that could break the way your object works

To put the Duff’s Beer CO2 sensor a into word problem format:

The ComputeCO2 method hides the logic used to calculate CO2 levels using a specific brand of sensors for a beer processing system. If the sensors are modified and require software changes, only the class that defines the ComputeCO2 method needs to change. Other classes that call the ComputeCO2 method do not need to be modified.

Let’s say you are working at the Duff’s Beer company and they are installing a CO2 sensor system. 

Why? Duff’s is going to get hit with a CO2 tax, after all Beer manufacturing creates a lot of CO2. The owner of Duff’s doesn’t want to get locked into a specific set of sensors as they need to be replaced every three years and the owner’s want to be able to get bids for the replacement. In this case your sensor software will need to be flexible, but you don’t know how the other sensors output will look like. 

The output of your ComputeCO2 class should remain the same no matter which sensor is being used. But what is wrong with this code? Does it do the implementation correctly? After all the class ComputeCO2 uses nothing but public accessors, so how do we fix it? See tomorrow’s blog.

Code Snippet

  1. using System;
  2. //**********************************
  3. //Your namespace may not be the same
  4. //If you want to change it, make sur
  5. //to right click and use the refactor
  6. //tool
  7. //**********************************
  8. namespace Encapsulation
  9. {
  10.     //**************************************************
  11.     // There are two Class definition.
  12.     // This one could be used to ComputeCO2 from a sensor
  13.     // An engineering factor may be required, which is
  14.     // referred to as a CalbrationFactor
  15.     // In reality you might use XML Serialization
  16.     // the second Class includes the entry point for this
  17.     // Application
  18.     //***************************************************
  19.         public class ComputeCO2
  20.         {
  21.             // Class members:
  22.             // Property.
  23.             public int CO2level { get; set; }
  24.  
  25.             // Method.
  26.             public int CalibrationFactor(int Calibration)
  27.             {
  28.                 return Calibration * CO2level;
  29.             }
  30.  
  31.             // Instance Constructor.
  32.             public ComputeCO2()
  33.             {
  34.                 CO2level = 0;
  35.             }
  36.         }
  37.         //*********************************************
  38.         //This class is the entry point for the program
  39.         //*********************************************
  40.         class Program
  41.         {
  42.             static void Main(string[] args)
  43.             {
  44.                 // ***************************************
  45.                 // Create an object of type ComputeCO2.
  46.                 // ***************************************
  47.                 ComputeCO2 Sensor = new ComputeCO2();
  48.  
  49.                 // ***************************************
  50.                 // Set the value of a public property.
  51.                 // ***************************************
  52.                 Sensor.CO2level = 27;
  53.                 // ***************************************
  54.                 // Call a public method.
  55.                 // ***************************************
  56.                 int CumulativeSensorValue = Sensor.CalibrationFactor(4);
  57.                 // ********************************************
  58.                 // Console.WriteLine to output the sensor value
  59.                 // ********************************************
  60.                 Console.WriteLine("\n\nCalibrated Sensor output: " + CumulativeSensorValue);
  61.                 // *************************************************
  62.                 // A public service message, but seriously
  63.                 // Don't drink and drive, if you are going to drink
  64.                 // get a taxi or walk back from the party
  65.                 //***************************************************
  66.                 Console.WriteLine("\n\n\t\tDon't Drink and Drive");
  67.             }
  68.         }
  69. }

Now the bottom line:

Don’t drink and drive, it’s July 4th, if you need a ride call a taxi, ask a friend, take the bus (but don’t sit next to me) or walk. Don’t drive!