Encapsulation

What is it?


Encapsulation is about objects keeping secrets on each other and only telling through proper channels when another object asks nicely. Encapsulation is about keeping all your eggs in one basket and not letting anyone touch them.... it's about data integrity... cleaner code and reducing bugs! It's also about not cutting up your drivers license just because someone told you to!

Believe it or not encapsulation is the first step in Thread Safety. An object maintains members or fields that are needed to perform a function... track internal data during processing or whatever the need is. Members should be protected from other carless objects in order to maintain integrity because when they are compromised... they're useless.

By instilling some very basic principals integrity can be kept to a high standard...

CREATED 2013-02-15 18:30:09.0

00-19-DF

UPDATED 2013-02-15 18:49:13.0

Scope...


Keep your privates... well private! Don't let anyone touch... not even if you really, really know them. A class has a parent not a Mom and Dad. So there is no reason to show your privates!

Set the scope of all object members to private. This prevents not only the outside world from tampering with them but also you and your decendants. If members are set to protected or worse public then anyone can access them... not good... keep your privates close to the vest.

If members are private, not even decendants can access them. Thats what accessors and mutators are for. Create accessors to get a copy or a pointer. It prevents unauthorized modification.

Data validation should be a concern for everyone. A member can't be validated if it is set directly. Unvalidated data can cause problems... big problems!

CREATED 2013-02-15 18:48:40.0

00-19-E0

UPDATED 2013-02-15 18:49:10.0

Mutation...


Set and access the private members with the appropriate methods. Never set them directly, not even from within the object. This provides the ability to validate the parameter being set to the member before it gets set. e.g. not allowing null or blank values. Ignoring this one causes bugs to creep into your code!

You can create a method to set each member but a better way to accomplish this task is to create a member to modify each member type. One for strings, ints, etc... within reason of course... then pass a seperate parameter to indicate the member to be set once the validation is complete.

CREATED 2013-02-15 18:49:27.0

00-19-E1

UPDATED 2013-02-15 18:49:36.0

Accessing...


Once the data is validated and stored it may need to be modified for different types of access. Use accessors (getters) to do this. Even if it is from another method with visibility to the member... and especially if it's from a decendant. Anyone could extend a normal class... but they might not understand the purpose of a given field.

If a member or field can be accessed directly... it can be set directly

Lets say you stored a phone number in three seperate fields. Area code, prefix and number. It was stored this way so it could be searched or some other purpose that prevented the whole formatted number from being stored.

Now you need to get that number. Or better yet you need to allow others to retrieve this phone number. It isn't much good without being formatted right? 3031231234 is not that easy to read. But rather than "(" + getAreaCode() + ")" + getPrefix() + "-" + getNumber() everytime you need to output the number for human consumption... it would be much easier to create a getPhoneNumber() method that does this formatting for you. Besides... (303)123-1234 is easier on th eye.

CREATED 2013-02-15 21:19:19.0

00-19-E5

UPDATED 2013-02-15 21:19:25.0

An Example...


Let's look at a simple class... a person. For simplicity, this class has three members... lastname, firstname and middlename.

 public class Person{   /** Members */  private String lastname;  private String firstname;  private String middlename;   /** Zero arg constructor */  public Person(){}  public Person(String last, String first, String middle){  this.lastname = last;  this.firstname = first;  this.middlename = middle;  } } 																

There is one very glaring problem in this class. The name parts are set directly in the constructor. Doesn't sound like a big deal right? OK... lets look at this object in action...

 Person p = new Person(Smi3th, John, A); 

See the problem... somebody snuck a three in the last name. This is a potentially serious problem... what's worse... it could make the developer look really bad... even worse the bad data could have come off a feed like an InputStream... which can be very hard to track. But it could have all been avoided.

CREATED 2013-02-15 19:46:20.0

00-19-E2

UPDATED 2013-02-15 20:12:00.0


Let's add a method to this class...

  /** private method to set the name and validate it */  private final boolean setName(String name, String part) throws InvalidNameException{  // check for null...  try{  name.charAt(0);  // the object is not null , check for length...  if(name.length() > 0){  // Now we know the name has length  String newName = "";  for(int i=0;i<name.length();i++){  Character c = name.charAt(i);  // add each character only if it is a letter  if(Character.isLetter(c)){  newName += c.toString();  }else{  // do nothing, not adding invalid characters or throw an exception.  }  // Now that we know the name is all characters and not null or blank...  if(part.equalsIgnoreCase("last"){  this.lastname = newName;  }else if(part.equalsIgnoreCase("first"){  this.firstname = newName;  }else if(part.equalsIgnoreCase("middle"){  this.middlename = newName;  // the name has no length  }else{  // throw an exception or commit the name with no length  }  }catch(NullPointerException e){  throw new InvalidNameException("Null value for last name is not allowed.");  }  } 																

First this method is declared final so it can be called from the constructor. If it wasn't it could be overriden in a decendant... using an overridable method in a constructor can make a mess... Second we need to modify the constructor to use it...

  public Person(String last, String first, String middle) throws InvalidNameException{  setName(last, "last");  setName(first, "first");  setName(middle, "middle");  } 

Notice the new constructor throws an InvalidNameException... a little more work but the results pay off. Now Smi3th would become Smith! The exact validation may vary i.e. a null last name may be allowed, or a middle initial with a period after it... but this makes the point. If this came off an InputStream, the 3 would have been eliminated OR an exception would have been thrown and the problem could be addressed.

A more robust example may have used a java enum for type or maybe a seperate private string validation method but that is beside the point.

CREATED 2013-02-15 19:51:05.0

00-19-E3

UPDATED 2013-02-15 19:51:05.0

Conclusion...


Real programmers use ! Not paying attention to a few simple rules can make a real mess and rewriting botched code can be a nightmare. Practice these rules... keep your classes safe and keep your privates, private! Encapsulation

CREATED 2013-02-15 20:31:05.0

00-19-E4

UPDATED 2013-02-15 20:31:10.0

Knowledge

L
I
N
K
S

DBID: db.wam

Page Server: Ithica

©2012 Leistware Data Systems

      Hello anonymous