Showing posts with label Principle of least knowledge. Show all posts
Showing posts with label Principle of least knowledge. Show all posts

Friday, May 20, 2011

Principle of least knowledge or Law of Demeter (LOD)

The principle states: Each unit should only talk to its friends; Don’t talk to strangers. A method of an object should invoke only the methods of the following kinds of objects:
    1. itself 2. its parameters 3. any objects it creates/instantiates 4. its direct component objects

Violation of above principle

Below is an example of some code breaking this principle:
Interface : IOrderManager

public interface IOrderManager
{
void AddItemToOrder(IItem item);
void RemoveItemFromOrder(IItem item);
void ChangeItemName(IItem item, string name);
}


Interface: IItem


public interface IItem
{
int Id { get; set; }
string Name { get; set; }
}

Class: Item : IItem

public class Item : IItem
{
private int _Id;
private string _Name;

public int Id
{
get { return _Id; }
set { _Id = value; }
}
public string Name
{
get { return _Name; }
set { _Name = value; }
}
}
Class :OrderManager : IOrderManager

public class OrderManager implements IOrderManager
{
private IOrder _Order;

public OrderManager()
{
_Order = new Order();
_Order.Items = new List<IItem>();
}

public void AddItemToOrder(IItem item)
{
if (_Order.Items != null)
{
if ( ! _Order.Items.Contains(item))
{
_Order.Items.Add(item);
}
}
}
public void RemoveItemFromOrder(IItem item)
{
if (_Order.Items != null)
{
if (_Order.Items.Contains(item))
{
_Order.Items.Remove(item);
}
}
}
public void ChangeItemName(IItem item, string name)
{
if (_Order.Items != null)
{
if (_Order.Items.Contains(item))
{
_Order.Items[_Order.Items.IndexOf(item)].Name = name;
}
}
}

In the above example the OrderManager has the responsibility of adding and removing Items to and from the List collection in the Order class, and even worse it has the responsibility of changing the name of a particular Item inside that collection. This tightly couples the OrderManager to the Order and Item class, if we would change how the Order class is maintaining her Items than we automatically have to change the OrderManager class. The Order should be responsible for its Items, not the OrderManager. Below is the Law Of Demeter implementation of this example:
Interface: IOrder



public interface IOrder
{
void AddItem(IItem item);
void RemoveItem(IItem item);
void ChangeItemName(IItem item, string name);
}


Class: Order : IOrder


public class Order implements IOrder
{
private List<IItem> _Items;

public Order()
{
_Items = new List<IItem>();
}

public void AddItem(IItem item)
{
if (_Items != null)
{
if (!_Items.Contains(item))
{
_Items.Add(item);
}
}
}
public void RemoveItem(IItem item)
{
if (_Items != null)
{
if (_Items.Contains(item))
{
_Items.Remove(item);
}
}
}
public void ChangeItemName(IItem item, string name)
{
if (_Items != null)
{
if (_Items.Contains(item))
{
_Items[_Items.IndexOf(item)].Name = name;
}
}
}
}

Class: OrderManager : IOrderManager


public class OrderManager implements IOrderManager
{
private IOrder _Order;

public OrderManager()
{
_Order = new Order();
}

public void AddItemToOrder(IItem item)
{
_Order.AddItem(item);
}
public void RemoveItemFromOrder(IItem item)
{
_Order.RemoveItem(item);
}
public void ChangeItemName(IItem item, string name)
{
_Order.ChangeItemName(item, name);
}
}

Now we can change how the Order class is keeping its Items without having to change the OrderManager. One nice rule of thumb is: One dot should be enough.

Wednesday, March 2, 2011

Facade Pattern

Facade provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher level interface that makes the subsystem easy to use.

Facade pattern works on principle of least knowledge.

A Facade not only simplifies an interface, it also decouples a client from subsytem of components. Using Facade Pattern you can take a complex subsystem and make it easier to use by implementing a Facade class that provides resonable interface.

Need for Facade


For Example,Let us think we have subsytem containing Gate, GarageDoors, CarLock, Lights etc.. Now when we leave home we have to following:

door.open();
lights.off();
door.close();
garageDoor.open();
carLock.unlock();
gate.open();
garageDoor.close();
gate.close();


This is a small subsystem, but consider you have bungalow, things get more complicated. Not only this, when the person comes back , he has to do following things:


gate.open();
garageDoor.open();
carLock.lock();
door.open();
lights.on();
gate.close();
garageDoor.close();
door.close();

Again a hell lot of work. Wouldn't be it good, if we have some smart system, which does all this itself, rather than we go and click all these to work. This is where facade pattern comes into picture.

Instead of doing all that stuff and making lots of object in our main class, we supply all these components to our facade class, which deals with these components and solve these problems. Now we will be having a single iterface which will do simplify the subsystem for us:


public class HomeFacade{
Gate gate;
GarageDoor garageDoor;
CarLock carLock;
Lights lights;
MainDoor door;

public HomeFacade(Gate gate,GarageDoor garageDoor,CarLock carLock,Lights lights,MainDoor door){
this.gate = gate;
this.garageDoor = garageDoor;
this.carLock = carLock;
this.lights = lights;
this.door = door;
}

public void reachHome(){
gate.open();
garageDoor.open();
carLock.lock();
door.open();
lights.on();
gate.close();
garageDoor.close();
door.close();
}

public void leaveHome(){
door.open();
lights.off();
door.close();
garageDoor.open();
carLock.unlock();
gate.open();
garageDoor.close();
gate.close();

}
}


The Facade still leaves the subsystem accessible to be used directly. If you need the advanced functionality of the subsystem classes, they are avilable for your use. (As Facade doesn't encapsulate the subsystem classes, but it provides a simplified interface)
Facade is free to add its own specialization in addition to making use of subsystem.
For a subsystem, we can have number of Facades.


Design Principle behind Facade pattern :



Priciple of least knowledge : When you are designing a system, for any object be careful of the number of classes it interacts with and also how it interacts with those classes. Also known as law of Demeter.
This principle prevents us from creating designs that have a large number of classes coupled together so that changes in one part of the system cascade to other parts. when you build a lot of dependencies between many classes, you are building a fragile system that is costly to maintain and complex for others to understand.
But how to implement this design priciple?
Take any object. Now from any method in that object, we should only invoke methods that belong to
1. The Object itself
2. Objects passed in as a parameter to the methods
3. Any object that method creates and instantiates.
4. Any components of objects. (Has-A relationship)
(Dont call methods on objects that were returned from calling other methods)
Example :



Without principle :


public float applyForJob(){
Agency agency = company.getAgency();
return agency.searchJob();
}


Here we are dependent on Agency Class also



With principle:


public float applyForJob(){
return company.searchJob();
}



This reduces the number of classes we are dependent on.
Primary benifit is that the calling method doesn't need to understand structural makeup of the object it's invoking methods upon.
The obvious disadvantage of using this principle is that we must create many methods that only forward method calls to the containing classes internal components. This can contribute to a large and cumbersome public interface.
An alternative to this principle or variation on its implementation, is to obtain a reference to an object via a method call, with the restriction that any time this is done, the type of reference obtained is always an interface datatype. As we are binding ourselves with directly to the concrete implementation of a complex object, but instead we are depending on abstractions of which the complex object is composed.


A very nice example of the above approach is java.sql.ResultSet interface.
After an SQL statement has been executed, Java stores results in a ResultSet Object. One of our options at this point is to query this resultset object and obtain metainformation pertaining to this set of data. The class that contains this metadata is ResultSetMetaData class and it's contained with resultset class. We cant directly obtain reference of this class, but instead would call methods on the ResultSet which subsequently forward these requests to ResultSetMetaData Class. This would results in explosion of methods on ResultSet class. Therefore getResultSetMetaData() method on ResultSet would does return a reference to ResultSetMetaData. However as ResultSetMetaData is an interface we are not bound to any concrete implementation contained within resultset.


Difference between Adapter pattern and facade Pattern:
Adapter Pattern changes the interface of one or more classes into one interface that a client is expecting while a Facade may provide a simplified interface to a single class with a very complex interface.
Facade and Adapter may wrap multiple classes but facade's intent is to simplify and adapter's intent is to convert the interface to something different.
Hope it will be useful.

Chitika