Showing posts with label Design Patterns. Show all posts
Showing posts with label Design Patterns. Show all posts

Saturday, September 13, 2014

Abstraction


By romana klee from usa - sammati tarka prakarana, CC BY-SA 2.0, https://commons.wikimedia.org/w/index.php?curid=59461928

Abstraction is the ability to build models. For example, you are dealing with a problem to be solved. The problem has its own details and nuances. To solve it, a human mind tries to build the model of both problems and then the solution. Both the problem and solution space can be made as specific or as generic. How specific or generic depends on the person doing the mapping. Depending on individual inclinations and capabilities, it might be very specific or very generic.

Abstraction has to be handled carefully in software development or for that matter in any problem-solving exercise of the world. The right level has to be achieved otherwise it will lead you to a rat hole, in the case of both under and over abstraction.

Let's look into the problems with under and over abstraction.

Perils of over abstractions

Sunday, August 17, 2014

Visitor Pattern

Visitor pattern provides a way to implement double dispatch in Java. What double dispatch means? Double dispatch in simple terms means, you start with an object->Pass the reference to another object->Another object will do a callback which will land up in the starting object itself. Simple:). The starting object are usually algorithmic objects and the other objects are usually structural objects.

Let's take an example that in an organization we have people with different designation. Different designations are treated in different way. For example, let's say we need to calculate their salaries based on role in a different way. Also we need to calculate the Stocks to be allotted to them based on the designations. Here we have a set of objects, and a set of algorithms.

Now Salary class (Finance department in real life), has all the logic buried in it to. Also the logic of how much stock to allot is buried in StockAllotment class(HR department). And we do not want each individual to calculate theirs salaries or their stocks. That's where Visitor pattern comes into picture.

public interface Employee {
   public void accept(Calculator calculator);
}

public class Manager implements Employee {
public void accept(Calculator calculator) {
calculator.visit(this);
}
}

public class Developer implements Employee {
public void accept(Calculator calculator) {
calculator.visit(this);
}
}
public interface Calculator {
public void visit(Manager manager);
public void visit(Developer developer);
}

public class SalaryCalculator implements Calculator {

@Override
public void visit(Manager manager) {
System.out.println("Salary = Lines of code written");
}

@Override
public void visit(Developer developer) {
System.out.println("Salary = 1/Number of Bugs introduced");
}
}

public class StockCalculator implements Calculator {

@Override
public void visit(Manager manager) {
System.out.println("Stocks = amount of money spend lat year");
}

@Override
public void visit(Developer developer) {
System.out.println("Stocks = Do we need to give them?");
}
}

Now the main class

public class VisitorMain {

public static void main(String[] args) {

List<Employee> employeeList = new ArrayList<Employee>();
employeeList.add(new Developer());
employeeList.add(new Manager());

SalaryCalculator salaryCalculator = new SalaryCalculator();
StockCalculator stockCalculator = new StockCalculator();

for (Employee employee : employeeList) {
employee.accept(salaryCalculator);
employee.accept(stockCalculator);
}
}

}

Notice that we started with Salary Calculator, passed it to an instance of employee and the final call landed back into SalaryCalculator class.

One big disadvantage of Visitor pattern is that if you introduce one more concrete type, than one more call back has to be written in Calculator interface and has to be implemented all through. You can write one more abstract class in between Employee and other concrete class which has the default implementation, and that would shield from a lot of changes. On the positive side, this disadvantage is a great job creator.

Articles on Software Design and Patterns

Prototype Pattern

At time prototype looks to heavy a word to me for this pattern. A simple and more intuitive name is Clone or Copy pattern. But clone and copy names take a lot of sheen out of the things. :-). Anyway, coming back to prototype pattern, it's just a smart cloning mechanism. The cloning logic is encapsulated neatly inside a method. Whenever you need the clone of a object, call clone method on that object. The decision which is important for Prototype pattern is how deep or shallow you want it to be.

The cloning interface for better management

public interface Cloneable {
public Object clone();
}

Class which has cloning capability

public class Actor implements Cloneable {

private final String name;
private final List<String> movieList;

public Actor(String name, List<String> movieList) {
this.name = name;
this.movieList = movieList;
}

@Override
public Object clone() {
      //In future when the cloning technology will be prevalent, this might be a contentious
 //issue that how the wealth will be shared between originals and clones. A sure conflict
 //of interest exists here. From the pattern perspective, we can have a shallow copy which is
 //done here or we can have a deep copy
Actor clone = new Actor(name, movieList);
return clone;
}

public String getName() {
return name;
}

public List<String> getMovieList() {
return movieList;
}
}

Main class

public class PrototypeMain {

public static void main(String[] args) {
// Let make Arnie
List<String> movieList = new ArrayList<String>();
movieList.add("Commondo");
movieList.add("True Lies");
// We can add more but let's stop here. Let's do pattern and not movies
// :)

Actor arnie = new Actor("Arnold", movieList);
// Sounds like "The 6th day"
Actor clone = (Actor) arnie.clone();

if (clone.getMovieList() == arnie.getMovieList()) {
System.out.println("Hmmm serious issue of ownership");
}
}
}

This pattern is quite useful in one situation, when one has to copy a set of records in database which are connected through a parent child relationship. but while copying we do not want their original primary keys, but the newly generated keys. With proper cascading set at top object, (I am assuming ORM being used here) and clone at all levels, whole tree can be cloned. With persist called on the top object, the tree is created in the database.

Articles on Software Design and Patterns

Observer Pattern

Observer pattern is similar to publish-subscribe model. The subscriber register themselves with the publishers. When publisher publishes a event, it notifies all the subscriber. Think of it as a subscription done online of for SMS. Whenever any relevant things happen, a SMS or mail is received in the Inbox.

Java in fact provides utility class and interface to implement this pattern. The Observable can be extended from java.util.Observable and the observers can be extended from java.util.Observer. Let's look into a basic example

Observable:

public class Publisher extends Observable {

public void publishEvent(String eventName) {
//Calling set changed is important for triggering event
this.setChanged();
//Notify the observers
this.notifyObservers(eventName);
}
}

Observer:

public class Subscriber implements Observer {

@Override
public void update(Observable o, Object arg) {
System.out.println(arg);
}
}

And the main class

public class ObserverMain {

public static void main(String[] args) {
Publisher publisher = new Publisher();

Subscriber subscriber1 = new Subscriber();
Subscriber subscriber2 = new Subscriber();

publisher.addObserver(subscriber1);
publisher.addObserver(subscriber2);

publisher.publishEvent("Observer Pattern Working");

Composite Pattern

Composite is about dealing the whole and the part in a uniform way. It's useful in building tree like structures and then working on them in a uniform way. Let's see how to implement one related to a tree.

The Node interface

public interface Node {
public void process();
}

The whole

public class NonLeafNode implements Node {
private final List<Node> nodeList = new ArrayList<Node>();

public void addNode(Node node) {
nodeList.add(node);

}

@Override
public void process() {
System.out.println("I am not a leaf node");
for (Node node : nodeList) {
node.process();
}
}
}

The part

public class Leaf implements Node {

@Override
public void process() {
System.out.println("I am leaf");
}
}

And the main method

public class Composite {

public static void main(String[] args) {
NonLeafNode root = new NonLeafNode();
NonLeafNode level1 = new NonLeafNode();
root.addNode(level1);

Leaf leaf = new Leaf();
level1.addNode(leaf);

root.process();
}

Chain of responsibility Pattern

Chain of responsibility as the name suggests has two parts to it. One is Chain and the other is Responsibility. The chain part is about setting a sequence of things who can process the things. The responsibility part is basically about doing the things.

In any organization, budget approvals are done at different levels based on the hierarchy. Manager can approve till certain amount, but beyond it, it goes to General Manager and so on.Beyond certain amount, even Board or Shareholders (if it is listed) need to involved for the decision making process.

The other important part is setting up the chain. The chain can be set implicitly by participating objects or explicitly by an independent object. For example, in workflow systems, usually the chain is set explicitly based on the process. The systems like leave management system or budget approval systems has implicit chain setting. The boss is set for every individual and based on the condition, the process automatically goes from boss to his/her boss to his/her boss.

Let's build the chain first

public abstract class Employee {
protected Employee boss;

public void setBoss(Employee employee) {
boss = employee;
}

public void applyLeave(int noOfDays) {
Leave leave = new Leave(this, noOfDays);
boss.processLeaveForApproval(leave);

if (leave.isApproved()) {
System.out.println("Pack the fishing gadgets.");
} else {
System.out.println("Open Laptop and start working.");
}
}

abstract public void processLeaveForApproval(Leave leave);
}

public class Developer extends Employee {

@Override
public void processLeaveForApproval(Leave leave) {
// Developer can not process any leave
throw new RuntimeException("Developer cannot process leaves");
}
}

public class Manager extends Employee {

@Override
public void processLeaveForApproval(Leave leave) {
// Make sure one does not approve its own leave
if (leave.getEmployee() == this || leave.getNoOfDays() > 15) {
this.boss.processLeaveForApproval(leave);
} else {
// Manager in good mood, so will approve all leave
System.out.println("Approve by Manager");
leave.setApproved(true);
}
}
}

public class Director extends Employee {

@Override
public void processLeaveForApproval(Leave leave) {
// Director has got stock option recently so in good mood
// Also let's assume he can approve his own leaves also
System.out.println("Approve by Director");
leave.setApproved(true);
}
}

The Leave class for completion

public class Leave {

int noOfDays;
boolean approved = false;
Employee employee;

public Leave(Employee employeeApplied, int days) {
employee = employeeApplied;
noOfDays = days;
}

public void setApproved(boolean approved) {
this.approved = approved;
}

public boolean isApproved() {
return approved;
}

public Employee getEmployee() {
return employee;
}

public int getNoOfDays() {
return noOfDays;
}

}

And now the usage

public class ChainOfResponsibility {

public static void main(String[] args) {
Director director = new Director();
director.setBoss(director);

Manager manager = new Manager();
manager.setBoss(director);

Developer developer1 = new Developer();
developer1.setBoss(manager);
Developer developer2 = new Developer();
developer2.setBoss(manager);

developer1.applyLeave(10);
developer2.applyLeave(20);
manager.applyLeave(5);
director.applyLeave(1);
}

Builder Pattern

Builder as the name suggests is about building objects. The objects are built in steps. It's one more higher level of abstraction than Abstract factory, where the steps to build the object and the object responsible for actual building are also separated out. For example let's say we want to make a builder for Car. Take real life example of let's say Ford. Ford has many vehicles in its portfolio. For example, let's take Fiesta and Mustang. Now there are two parts of this problem. One is the building of the Mustang or Fiesta and the second is the plant where the cars are actually build. So we have to handle with both steps of building and actual building. If Ford would have only one factory to build all the cars, we could have used Abstract factory. If Ford would have only one factory and one car, we could have used Factory. Also in builder pattern, we can use abstract factory also for building different cars. So a lot of mix and match is possible as per the requirement.

Coming back to our present problem, Let's define the Car

public class Car {

private String chasis;
private String interior;
private String engine;

public void setChasis(String chasis) {
this.chasis = chasis;
}

public void setInterior(String interior) {
this.interior = interior;
}

public void setEngine(String engine) {
this.engine = engine;
}

}

Now let's make the builder

public abstract class CarBuilder {

protected Car car;

public void createCar() {
this.car = new Car();
}

public Car getcar() {
return car;
}

public abstract void buildChasis();

public abstract void buildInterior();

public abstract void buildEngine();
}

And the actual builders

public class FiestaCarBuilder extends CarBuilder {

@Override
public void buildChasis() {
car.setChasis("Small Chasis");
}

@Override
public void buildInterior() {
car.setInterior("Simple but elegant");
}

@Override
public void buildEngine() {
car.setEngine("Small engine");
}

}

and another concrete builder

public class MustangCarBuilder extends CarBuilder {

@Override
public void buildChasis() {
car.setChasis("A big chasis");
}

@Override
public void buildInterior() {
car.setInterior("Luxurious");
}

@Override
public void buildEngine() {
car.setEngine("Powerful");
}

}

Now we need to represent the actual plant for making cars

public class FordManufacturingPlant {

private CarBuilder carBuilder;

public void setCarBuilder(CarBuilder carBuilder) {
this.carBuilder = carBuilder;
}

public void constuctCar() {
carBuilder.createCar();

carBuilder.buildChasis();
carBuilder.buildEngine();
carBuilder.buildInterior();
}

public Car deliverCar() {
return carBuilder.getcar();
}
}

And finally the main app

public class Builder {

public static void main(String[] args) {
FordManufacturingPlant plant = new FordManufacturingPlant();
FiestaCarBuilder fiestaCarbuilder = new FiestaCarBuilder();
MustangCarBuilder mustangCarbuilder = new MustangCarBuilder();

// Let's build 100 fiesta cars
List<Car> fiestCarList = new ArrayList<Car>();
for (int i = 0; i < 100; i++) {
plant.setCarBuilder(fiestaCarbuilder);
plant.constuctCar();
fiestCarList.add(plant.deliverCar());
}

// Let's build 10 mustangs
List<Car> mustangCarList = new ArrayList<Car>();
for (int i = 0; i < 10; i++) {
plant.setCarBuilder(mustangCarbuilder);
plant.constuctCar();
mustangCarList.add(plant.deliverCar());
}
}

Patterns not a Panacea

Patterns are good as they capture best practices but most of the time we try to fit those patterns to solve our problems. Sometimes we even fit our problems over our solutions or so called patterns. We can take the famous example of EJB2.1 entity beans where we have DTO patterns to move the object across the wire. And lot of us take pride in knowing that we know about DTO's and have used it. Don't worry, even I was also one of them. Now take a step back and see that we were solving the basic problem itself the wrong way. The basic problem was that of handling the notion of persistence itself which is fixed in the EJB3.0. The artificial problem went away automatically. Of course we should congratulate hibernate also for showing the right path.


I think we should promote more basic thinking among developers. Rather than trying to figure ourt where we can apply the patterns we should start thinking about the problem that we are trying to solve. We should promote thinking, which happens at basic notions of object oriented programming which are abstraction, encapsulation, inheritance and polymorphism. I believe abstraction is the most powerful of these notions and probably most difficult to master. Abstraction is the basic bridge between software world and the business/real world. The other notions help us in building the structure and detailing of the representative software world that we create.


The important thing is to understand your problem. Knowing the problem that you are solving is half way to the solution. Otherwise we will try to put a square peg on a circular hole. If fact, in any software design problems, start with what we are trying to achieve and then once that is clear think about what are appropriate tools (patterns) to solve them.

Saturday, August 16, 2014

Java Object Oriented Concepts

Object-Oriented Programming concept

Object-oriented Programming is designed to model the real world concept into a computer program.It considers real world things as object.Ex. Bicycle,car,book and so on. This is an approach that provides a way of modularizing program by creating partitioned memory area for both data and function that can be used as templates for creating copies of such modules on demand.

The OOP Principles
  • Abstraction - It deal with the complexity of an object and how that complexity is represented. It's also a mechanism to represent real world concepts of software world. Think of it as a model that is created to represent the problem domain concepts. For example many times we create mental models to understand certain things and that helps in comprehension. In the same way, in the context of software, abstraction is a way of representing problem domain. For example, take School Management System. To make such a system, we need to map many concepts from real world and map it to Software world. The concept of Student and Teacher, which are straightforward to understand and map. Now let's see the concept of pass and fail. How to represent that as there might be many rules. The rules could be

- Minimum marks in individual subjects
- How many subjects one need to have certain marks to pass.
- Different class might have different criteria
- Many more
How to represent all the concepts in software world. That's where abstraction comes in picture. It's about capturing all the details in certain class structure. It's also about focusing on the essential and relevant details and ignore the non-essential details.

  • Encapsulation:  Wrapping up of data and method into a single unit is known as encapsulation. e.g.  capsule,  from the outside its just a cap, and it hides everything that is contained within. But what lies inside may be 2 or 3 or more powders loosely arranged and packed within.An object is something similar. It is created with the immense power of a class. while the composition of the class could be anything (as compared to the capsule), one may not know what is contained when you create the object handles in

A obj = new A();  

you may say obj here is like the capsule to all those who want to consume it in their programs. So, with this object one can use its inherent power. Thus this concept of hiding away its true power is known as Encapsulation.

  • Inheritance:The mechanism of deriving a new class from an old one is called inheritance.The old class is known as base class or super class or parent class and new class is called the subclass or derived class or child class.The concept of inheritance provides the idea of reusability.This means that we can add additional features to an existing class without modifying it.Different Types of Inheritance

Single inheritance(only one super class)
Multiple inheritance(several super classes)
Hierarchical inheritance(one super class, many subclasses)
Multilevel inheritance(Derived from a derived class) note:java does not directly implement multiple inheritance,it is implemented using secondary inheritance path in the form of interface.

Defining a subclass:

class SubClass extends SuperClass
{
varialbe declaration;
method declaration;
}

The keyword extends is used to inherit the properties of base class to derived class.
Ex.


class User
{
   private String name;
   public void setName(String n)
   {
      name = n;
   }
   public String getName()
   {
      return name;
   }
}

class Student extends User
{
   private String stuNum;
   public void setStuNum(String sn)
   {
      stuNum = sn;
   }
   public String getStuNum()
   {
      return stuNum;
   }

Finally we have to create a program that will instantiate a Student object, set the name and student number and then print the values using the get methods.


public class TestInheritance
{
   public static void main(String[] args)
   {
      Student stu = new Student();
      stu.setName("Ishana Bhatt");
      stu.setStuNum("12345");
      System.out.println("Student Name: " + stu.getName());
      System.out.println("Student Number: " + stu.getStuNum());
   }
}

Polymorphism:It means "one interface,multiple methods".The ability to take  more than one form.It means to design a generic interface to a group related activities.It is compiler's job to select the specific action as it applies to each situation.EX. An operation show different behaviour in different instance.consider the operation of addition,for 2 no,the operation will generate sum.If the operands are string ,then the operation would produce a third string by concatenation.

Benefits Of OOP

  • Through inheritance, we can eliminate redundant code and extend the use of existing classes.
  • We can build secure  programs using data hiding concept.
  • It is easy to parition the work in project based on object.
  • Software complexity can be easily managed.
  • More on Java