Tuesday, 28 February 2017

Why wait(), notify() and notifyAll() are in Object class and not in Thread class in java?


1. These method not only used for synchronization, but also they can be used for communication between two threads and Object class is correct place to make them available for every object if this mechanism is not available via any java keyword like synchronized.

Point to remember: Synchronized is used to provide mutual exclusion and ensuring thread safety of Java class like race condition. However wait, notify and notifyAll can be used for communication mechanism among threads.

2. Every Object has a monitor, acquiring that monitors allow thread to hold lock on object (=Locks are made available on per Object basis), which is another reason wait and notify is declared in Object class rather than Thread class.

3. wait(), notify() and notifyAll() are called on objects only When wait() method is called on object by thread it waits for another thread on that object to release object monitor by calling notify() or notifyAll() method on that object.
When notify() method is called on object by thread it notifies all the threads which are waiting for that object monitor that object monitor is available now.
So, this shows that wait(), notify() and notifyAll() are called on objects only.

4. As multiple threads may request to access the same object at a time. However only threadcan hold object monitor at a time. As a result thread can notify other threads of same object that lock is available now. But, put these method into thread does not make any sense because multiple threads exists on object it's no other way around (i.e. multiple objects exists on thread).


Hypothetical scenario:
Suppose, Thread class contains wait(), notify() and notifyAll() methods?
Having wait(), notify() and notifyAll() methods means Thread class must have their monitor i.e. every thread having their monitor will create few problems:

Thread communication problem

Synchronization on object won’t be possible- Because object has monitor, one object can have multiple threads and thread hold lock on object by holding object monitor. But if each thread will have monitor, we won’t have any way of achieving synchronization.

Inconsistency in state of object (=synchronization won't be possible).


Friday, 17 February 2017

Interface-segregation principle


What is the point in selling a horse saddle for one who does not own a horse?

The interface segregation principle (ISP) states that no client should be forced to depend on methods it does not use. ISP splits interfaces that are very large into smaller and more specific ones so that clients will only have to know about the methods that are of interest to them.

Clients should not be forced to depend upon methods that they don't use.



ISP is intended to keep a system decoupled and thus easier to refactor, change, and redeploy.

When we design an application we should take care how we are going to make abstract a module which contains several submodules. Considering the module implemented by a class, we can have an abstraction of the system done in an interface. But if we want to extend our application adding another module that contains only some of the sub-modules of the original system, we are forced to implement the full interface and to write some dummy methods. Such an interface is named fat interface or polluted interface. Having interface pollution is not a good solution and might induce inappropriate behavior in the system.



//interface segregation principle - bad example
interface IWorker {
    
     public void work();
     public void eat();
}

class Worker implements IWorker {
     public void work() {
           // ....working
     }
     public void eat() {
           // ...... eating in lunch break
     }
}

class Robot implements IWorker {
     public void work() {
           //.... working much more
     }

     /** Dummy implementation while robot will not eat lunch.*/
     public void eat() {
           //.... eating in lunch break
     }
}

class Manager {
     IWorker worker;

     public void setWorker(IWorker w) {
           worker=w;
     }

     public void manage() {
           worker.work();
     }
}

If the design is already done fat interfaces can be segregated using the Adapter pattern.



// interface segregation principle - good example
interface IWorker extends IFeedable, IWorkable {
}

interface IWorkable {
     public void work();
}

interface IFeedable{
     public void eat();
}

class Worker implements IWorkable, IFeedable {
     public void work() {
           // ....working
     }

     public void eat() {
           //.... eating in lunch break
     }
}

class Robot implements IWorkable {
     public void work() {
           // ....working
     }
}

class Manager {
     IWorker worker;

     public void setWorker(IWorker w) {
           worker=w;
     }

     public void manage() {
           worker.work();
     }
}

Thursday, 16 February 2017

Liskov’s Substitution Principle - A SOLID principle


Derived types must be completely substitutable for their base types.

Explanation:
To utilize the principles like inheritance, we create some class hierarchies (=extends some classes creating some derived classes).

LSP states that if a program module is using a Base class, then the reference to the Base class can be replaced with a Derived class without affecting the functionality of the program module i.e. we must make sure that the new derived classes just extend without replacing the functionality of old classes.

Otherwise the new classes can produce undesired effects when they are used in existing program modules.

package core.solid;
/**
 * Violation of Liskov's Substitution Principle
 */
classRectangle {
     protected int width;
     protected int height;

     public voidsetWidth(int width){
           this.width = width;
     }

     public voidsetHeight(int height){
           this.height = height;
     }

     public intgetWidth(){
           return width;
     }

     public intgetHeight(){
           return height;
     }

     public intgetArea(){
           return width * height;
     }   
}

classSquare extends Rectangle {

     public voidsetWidth(int width){
           this.width = width;
           this.height = width;
     }

     public voidsetHeight(int height){
           this.width = height;
           this.height = height;
     }
}

public classLSPTest {

     private staticRectangle getNewRectangle() {
           /**
            * It can be an object returned by some factory.
            */
           return new Square();
     }

     public static voidmain (String args[]) {
          
           Rectangle rObj = LSPTest.getNewRectangle();

           /**
            * User knows that rObj it's a rectangle.
            * It assumes that he's able to set the width
            * and height as for the base class
            *
            * But the height and width are setter has
            * been changed as per the SQUARE property.
            **
            */
           rObj.setWidth(5);
           rObj.setHeight(10);

          
           /**
            * Unexpected result as the area of SQUARE calculated but
            * he was expecting the area of rectangle.
            **/
           System.out.println(rObj.getArea());
     }
}

Rectangle and Square two classes are used in the Application. We extend the application and add the Square class. The square class is returned using a factory pattern, based on some conditions and we don't know the exact what type of object will be returned. But we know it's a Rectangle.

We get the rectangle object, set the width to 5 and height to 10 and get the area. For a rectangle with width 5 and height 10 the area should be 50. Instead the result will be 100(=because rectangle class is Substituted by the Square class).

Related Posts Plugin for WordPress, Blogger...