You are on page 1of 14

What is Encapsulation in Java and OOPS with Example

Encapsulation in Java or object oriented programming language is a concept which enforce protecting variables,
functions from outside of class, in order to better manage that piece of code and having least impact or no impact on
other parts of program duec to change in protected code. Encapsulation in Java is visible at different places and Java
languageitself provide many construct to encapsulate members. You can completely encapsulate a member be it a
variable or method in Java by using private keyword and you can even achieve a lesser degree of encapsulation in
Java by using other access modifier like protected or public. true value of encapsulation is realized in an
environment which is prone to change a lot and we know that in software requirements changes every day at that
time if you have your code well encapsulated you can better manage risk with change in requirement. Along
with abstaction in java and polymorphism in Java, Encapsulation is a must know concept. In this java tutorial we will
see How to use encapsulation in Java, advantage and disadvantage of Encapsulation and various design
patterns and real life problems which makes use of Encapsulation object oriented concept. If you are looking for a
quick guide on both OOPS and SOLID design principle in Java than you may find 10 Object Oriented Design
principles Java programmer should know interesting.

Encapsulation is nothing but protecting anything which is prone to change. rational behind encapsulation is that if
any functionality which is well encapsulated in code i.e maintained in just one place and not scattered around code is
easy to change. this can be better explained with a simple example of encapsulation in Java. we all know that
constructor is used to create object in Java and constructor can accept argument. Suppose we have a
class Loan has a constructor and than in various classes you have created instance of loan by using this constructor.
now requirements change and you need to include age of borrower as well while taking loan. Since this code is not
well encapsulated i.e. not confined in one place you need to change everywhere you are calling this constructor i.e.
for one change you need to modify several file instead of just one file which is more error prone and tedious, though it
can be done with refactoring feature of advanced IDE wouldn't it be better if you only need to make change at one
place ? Yes that is possible if we encapsulate Loan creation logic in one method say createLoan() and client code
call this method and this method internally crate Loan object. in this case you only need to modify this method
instead of all client code.

Example of Encapsulation in Java

class Loan{
private int duration; //private variables examples of encapsulation
private String loan;
private String borrower;
private String salary;

//public constructor can break encapsulation instead use factory method
private Loan(int duration, String loan, String borrower, String salary){
this.duration = duration;
this.loan = loan;
this.borrower = borrower;
this.salary = salary;
}

//no argument consustructor omitted here

// create loan can encapsulate loan creation logic
public Loan createLoan(String loanType){

//processing based on loan type and than returning loan object
return loan;
}

}

In this same example of Encapsulation in Java you see all member variables are made private so they are well
encapsulated you can only change or access this variable directly inside this class. if you want to allow outside world
to access these variables is better creating a getter and setter e.g. getLoan() that allows you to do any kind of
validation, security check before return loan so it gives you complete control of whatever you want to do and single
channel of access for client which is controlled and managed.

Advantage of Encapsulation in Java and OOPS
Here are few advantages of using Encapsulation while writing code in Java or any Object oriented
programming language:

1. Encapsulated Code is more flexible and easy to change with new requirements.
2. Encapsulation in Java makes unit testing easy.
3. Encapsulation in Java allows you to control who can access what.
4. Encapsulation also helps to write immutable class in Java which are a good choice in multi-threading
environment.
5. Encapsulation reduce coupling of modules and increase cohesion inside a module because all piece of one thing
are encapsulated in one place.
6. Encapsulation allows you to change one part of code without affecting other part of code.

What should you encapsulate in code
Anything which can be change and more likely to change in near future is candidate of Encapsulation. This also helps
to write more specific and cohesive code. Example of this is object creation code, code which can be improved in
future like sorting and searching logic.

Design Pattern based on Encapsulation in Java
Many design pattern in Java uses encapsulation concept, one of them is Factory pattern which is used to create
objects. Factory pattern is better choice than new operator for creating object of those classes whose creation logic
can vary and also for creating different implementation of same interface. BorderFactory class of JDK is a good
example of encapsulation in Java which creates different types of Border and encapsulate creation logic
of Border. Singleton pattern in Java also encapsulate how you create instance by
providing getInstance() method. since object
is created inside one class and not from any other place in code you can easily change how you create object without
affect other part of code.

Important points aboue encapsulation in Java.
1. "Whatever changes encapsulate it" is a famous design principle.
2. Encapsulation helps in loose coupling and high cohesion of code.
3. Encapsulation in Java is achieved using access modifier private, protected and public.
4. Factory pattern , Singleton pattern in Java makes good use of Encapsulation.


Factory design pattern in Java one of the core design pattern which is used heavily not only in JDK but also in
various Open Source framework such as Spring, Struts and Apache along with decorator design pattern in Java.
Factory Design pattern is based on Encapsulation object oriented concept. Factory method is used to create
different object from factory often refereed as Item and it encapsulate the creation code. So instead of having object
creation code on client side we encapsulate inside Factory method in Java. One of the best examples of factory
pattern in Java is BorderFactory Class of Swing API. In this Design pattern tutorial we will see What is
Factory method design pattern in Java, What are main advantages of factory pattern in Java , Code example of
Factory design pattern and What problem Factory pattern solves in Java or when to use Factory design
pattern. This article is in continuation of my design pattern article as 10 OOPS and SOLID design principles java
programmer should know and How to use Observer pattern in Java

What is static factory method or factory design pattern


Factory design pattern is used to create objects or Class in Java and it provides loose coupling and high cohesion.
Factory pattern encapsulate object creation logic which makes it easy to change it later when you change how object
gets created or you can even introduce new object with just change in one class. In GOF pattern list Factory pattern
is listed as Creation design pattern. Factory should be an interface and clients first either creates factory or get
factory which later used to create objects.
Example of static factory method in JDK
Best Example of Factory method design pattern is valueOf() method which is there in String and wrapper classes
like Integer and Boolean and used for type conversion i.e. from converting String to Integer or String to double in
java..

Some more examples of factory method design pattern from JDK is :

valueOf() method which returns object created by factory equivalent to value of parameter passed.

getInstance() method which creates instance of Singleton class.

newInstance() method which is used to create and return new instance from factory method every time called.

getType() and newType() equivalent of getInstance() and newInstance() factory method but used when
factory method resides in separate class.

Problem which is solved by Factory method Pattern in Java
Whenever we talk about object oriented language it will based upon some concept
like abstraction, polymorphism etc and on that encapsulation and delegation are important concept any design will be
called good if task are delegated to different object and some kind of encapsulation is there.

Some time our application or framework will not know that what kind of object it has to create at run-time it knows
only the interface or abstract class and as we know we can not create object of interface or abstract class so main
problem is frame work knows when it has to create but dont know what kind of object.

Whenever we create object using new() we violate principle of programming for interface rather than
implementation which eventually result in inflexible code and difficult to change in maintenance. By using Factory
design pattern in Java we get rid of this problem.

Another problem we can face is class needs to contain objects of other classes or class hierarchies within it; this can
be very easily achieved by just using the new keyword and the class constructor. The problem with this approach is
that it is a very hard coded approach to create objects as this creates dependency between the two classes.

So factory pattern solve this problem very easily by model an interface for creating an object which at creation time
can let its subclasses decide which class to instantiate, Factory Pattern promotes loose coupling by eliminating the
need to bind application-specific classes into the code. The factory methods are typically implemented as virtual
methods, so this pattern is also referred to as the Virtual Constructor. These methods create the objects of the
products or target classes.

When to use Factory design pattern in Java
Static Factory methods are common in frameworks where library code needs to create objects of types
which may be sub classed by applications using the framework.
Some or all concrete products can be created in multiple ways, or we want to leave open the option that in
the future there may be new ways to create the concrete product.
Factory method is used when Products don't need to know how they are created.
We can use factory pattern where we have to create an object of any one of sub-classes depending on the
data provided
Code Example of Factory Design Pattern in Java:
Lets see an example of how factory pattern is implemented in Code.We have requirement to create multiple currency
e.g. INR, SGD, USD and code should be extensible to accommodate new Currency as well. Here we have made
Currency as interface and all currency would be concrete implementation of Currency interface. Factory Class will
create Currency based upon country and return concrete implementation which will be stored in interface type. This
makes code dynamic and extensible.

Here is complete code example of Factory pattern in Java:

interface Currency {
String getSymbol();
}
// Concrete Rupee Class code
class Rupee implements Currency {
@Override
public String getSymbol() {
return "Rs";
}
}

// Concrete SGD class Code
class SGDDollar implements Currency {
@Override
public String getSymbol() {
return "SGD";
}
}

// Concrete US Dollar code
class USDollar implements Currency {
@Override
public String getSymbol() {
return "USD";
}
}

// Factroy Class code
class CurrencyFactory {

public static Currency createCurrency (String country) {
if (country. equalsIgnoreCase ("India")){
return new Rupee();
}else if(country. equalsIgnoreCase ("Singapore")){
return new SGDDollar();
}else if(country. equalsIgnoreCase ("US")){
return new USDollar();
}
throw new IllegalArgumentException("No such currency");
}
}

// Factory client code
public class Factory {
public static void main(String args[]) {
String country = args[0];
Currency rupee = CurrencyFactory.createCurrency(country);
System.out.println(rupee.getSymbol());
}
}


Advantage of Factory method Pattern in Java:
Factory pattern in Java is heavily used everywhere including JDK, open source library and other frameworks.In
following are main advantages of using Factory pattern in Java:

1) Factory method design pattern decouples the calling class from the target class, which result in less coupled and
highly cohesive code?
E.g.: JDBC is a good example for this pattern; application code doesn't need to know what database it will be used
with, so it doesn't know what database-specific driver classes it should use. Instead, it uses factory methods to get
Connections, Statements, and other objects to work with. Which gives you flexibility to change your back-end
database without changing your DAO layer in case you are using ANSI SQL features and not coded on DBMS
specific feature?

2) Factory pattern in Java enables the subclasses to provide extended version of an object, because creating an
object inside factory is more flexible than creating an object directly in the client. Since client is working on interface
level any time you can enhance the implementation and return from Factory.

3) Another benefit of using Factory design pattern in Java is that it encourages consistency in Code since every time
object is created using Factory rather than using different constructor at different client side.

4) Code written using Factory design pattern in Java is also easy to debug and troubleshoot because you have a
centralized method for object creation and every client is getting object from same place.

Some more advantages of factory method design pattern is:
1. Static factory method used in factory design pattern enforces use of Interface than implementation which itself a
good practice. for example:

Map synchronizedMap = Collections.synchronizedMap(new HashMap());

2. Since static factory method have return type as Interface, it allows you to replace implementation with better
performance version in newer release.
3. Another advantage of static factory method pattern is that they can cache frequently used object and eliminate
duplicate object creation. Boolean.valueOf() method is good example which caches true and false boolean
value.
4. Factory method pattern is also recommended by Joshua Bloch in Effective Java.
5 Factory method pattern offers alternative way of creating object.
6. Factory pattern can also be used to hide information related to creation of object.

Thats all on Factory design patten in Java for now. This is one of the most used patterns in Java library and
different Java frameworks. Summary is try to use Factory pattern whenever you see an opportunity to encapsulate
object creation code and see chance of creating different object in near future.


Step 1
Create an interface.
Shape.java
public interface Shape {
void draw();
}
Step 2
Create concrete classes implementing the same interface.
Rectangle.java
public class Rectangle implements Shape {

@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
Square.java
public class Square implements Shape {

@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
Circle.java
public class Circle implements Shape {

@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
Step 3
Create a Factory to generate object of concrete class based on given information.
ShapeFactory.java
public class ShapeFactory {

//use getShape method to get object of type shape
public Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
}
Step 4
Use the Factory to get object of concrete class by passing an information such as type.
FactoryPatternDemo.java
public class FactoryPatternDemo {

public static void main(String[] args) {
ShapeFactory shapeFactory = new ShapeFactory();

//get an object of Circle and call its draw method.
Shape shape1 = shapeFactory.getShape("CIRCLE");

//call draw method of Circle
shape1.draw();

//get an object of Rectangle and call its draw method.
Shape shape2 = shapeFactory.getShape("RECTANGLE");

//call draw method of Rectangle
shape2.draw();

//get an object of Square and call its draw method.
Shape shape3 = shapeFactory.getShape("SQUARE");

//call draw method of circle
shape3.draw();
}
}
Step 5
Verify the output.
Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.

Implementation with Interface


Sample Java Source Code for Factory Method Design
Pattern
Following is the interface, that will be returned as the final end product from
the factories.
package com.javapapers.sample.designpattern.abstractfactory;

public interface Animal {
public void breathe();
}
Following is the interface for which the factory implementation should be
done. Inturn all abstract factory will return this type.
package com.javapapers.sample.designpattern.abstractfactory;

public interface AnimalFactory {
public Animal createAnimal();
}
One of the factory from a predefined set which will instantiate the above
interface.
package com.javapapers.sample.designpattern.abstractfactory;

public class SeaFactory implements AnimalFactory {

public Animal createAnimal() {
return new Shark();
}

}
Second factory from a predefined set which will instantiate the Animal
interface.
package com.javapapers.sample.designpattern.abstractfactory;

public class LandFactory implements AnimalFactory {
public Animal createAnimal() {
return new Elephant();
}
}

Implementation of an Animal. This class is grouped with the first abstract
factory.
package com.javapapers.sample.designpattern.abstractfactory;

public class Shark implements Animal {
public void breathe() {
System.out.println("I breathe in water! He he!");
}
}
Implementation of an Animal. This class is grouped with the second abstract
factory.
package com.javapapers.sample.designpattern.abstractfactory;

public class Elephant implements Animal {
public void breathe() {
System.out.println("I breathe with my lungs. Its easy!");
}
}
Following class consumes the abstract factory.
package com.javapapers.sample.designpattern.abstractfactory;

public class Wonderland {
public Wonderland(AnimalFactory factory) {
Animal animal = factory.createAnimal();
animal.breathe();
}
}
Testing the abstract factory design pattern.
package com.javapapers.sample.designpattern.abstractfactory;

public class SampleAbstractFactory {

public static void main(String args[]){
new Wonderland(createAnimalFactory("water"));
}

public static AnimalFactory createAnimalFactory(String type){
if("water".equals(type))
return new SeaFactory();
else
return new LandFactory();
}
}
Output of the above sample program for abstract factory pattern
I breathe in water! He he!


Implementation with Abstract
So far we have seen the classes need to be designed for making a CarFactory. Lets hit the keyboard now and
start composing our classes.
CarType.java will hold the types of car and will provide car types to all other classes
1
2
3
4
5
package designPatterns.creational.factory;

public enum CarType {
SMALL, SEDAN, LUXURY
}
Car.java is parent class of all car instances and it will also contain the common logic applicable in car making of
all types.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package designPatterns.creational.factory;

public abstract class Car {

public Car(CarType model) {
this.model = model;
arrangeParts();
}

private void arrangeParts() {
// Do one time processing here
}

// Do subclass level processing in this method
protected abstract void construct();

private CarType model = null;

public CarType getModel() {
return model;
}

public void setModel(CarType model) {
this.model = model;
22
23
24
25
26
}
}
LuxuryCar.java is concrete implementation of car type LUXURY
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package designPatterns.creational.factory;

public class LuxuryCar extends Car {

LuxuryCar() {
super(CarType.LUXURY);
construct();
}

@Override
protected void construct() {
System.out.println("Building luxury car");
// add accessories
}
}
SmallCar.java is concrete implementation of car type SMALL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package designPatterns.creational.factory;

public class SmallCar extends Car {

SmallCar() {
super(CarType.SMALL);
construct();
}

@Override
protected void construct() {
System.out.println("Building small car");
// add accessories
}
}
SedanCar.java is concrete implementation of car type SEDAN
1
2
3
4
5
6
7
8
9
package designPatterns.creational.factory;

public class SedanCar extends Car {

SedanCar() {
super(CarType.SEDAN);
construct();
}

@Override
protected void construct() {
10
11
12
13
14
15
System.out.println("Building sedan car");
// add accessories
}
}
CarFactory.java is our main class implemented using factory pattern. It instantiates a car instance only after
determining its type.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package designPatterns.creational.factory;

public class CarFactory {
public static Car buildCar(CarType model) {
Car car = null;
switch (model) {
case SMALL:
car = new SmallCar();
break;

case SEDAN:
car = new SedanCar();
break;

case LUXURY:
car = new LuxuryCar();
break;

default:
// throw some exception
break;
}
return car;
}
}
In TestFactoryPattern.java, we will test our factory code. Lets run this class.
1
2
3
4
5
6
7
8
9
10
11
12
13
package designPatterns.creational.factory;

public class TestFactoryPattern {
public static void main(String[] args) {
System.out.println(CarFactory.buildCar(CarType.SMALL));
System.out.println(CarFactory.buildCar(CarType.SEDAN));
System.out.println(CarFactory.buildCar(CarType.LUXURY));
}
}

Output:

Building small car
designPatterns.creational.factory.SmallCar@7c230be4
Building sedan car
14
15
16
17
18
designPatterns.creational.factory.SedanCar@60e1e567
Building luxury car
designPatterns.creational.factory.LuxuryCar@e9bfee2
As you can see, factory is able to return any type of car instance it is requested for. It will help us in making any
kind of changes in car making process without even touching the composing classes i.e. classes using
CarFactory.
Advantages of factory pattern
By now, you should be able to count the main advantages of using factory pattern. Lets note down:
The creation of an object precludes its reuse without significant duplication of code.
The creation of an object requires access to information or resources that should not be contained within the
composing class.
The lifetime management of the generated objects must be centralized to ensure a consistent behavior within the
application.
Final notes
Final notes
Factory pattern is most suitable where there is some complex object creation steps are involved. To ensure
that these steps are centralized and not exposed to composing classes, factory pattern should be used. We
can see many examples of factory pattern in JDK itself e.g.
java.sql.DriverManager#getConnection()
java.net.URL#openConnection()
java.lang.Class#newInstance()
java.lang.Class#forName()

You might also like