Tuesday, 11 May 2010

Design Patterns

I am thinking to do the SCEA exam, so first started preparing the design patterns.

In day-to-day design/development many places we need to use the patterns, but most of the times we just write the code without knowing the exact patterns.

Patterns can make the system robust and can re-use it.

I share my experience with the design patterns.

Startegy Pattern

In Strategy Pattern, the algorithms(behavior) can be selected at run time.




The strategy pattern is intended to provide a means to define a family of algorithms, encapsulate each one as an object, and make them interchangeable. The strategy pattern lets the algorithms vary independently from clients that use them.



Example code:

Following program add/subtract/multiply/divide(s) the two numbers and this add/subtract/multiply/divide behavior(strategy) has been extracted out defined as a interface.

This strategy has been referenced in the context class and it can be changed dynamically using the constructor/setter method.





//StrategyPatternSample

class StrategySample {

public static void main(String[] args) {

Context context;

context = new Context(new StrategyAdd());
System.out.println(context.executeStrategy(12,3));

context = new Context(new StrategySubtract());
System.out.println(context.executeStrategy(12,3));

context = new Context(new StrategyMultiply());
System.out.println(context.executeStrategy(12,3));

context = new Context(new StrategyDivide());
System.out.println(context.executeStrategy(12,3));

}

}


// The strategy interface
interface IStrategy {

int run(int a, int b);

}

// Implements the algorithm using the strategy interface
class StrategyAdd implements IStrategy {

public int execute(int a, int b) {
System.out.println("add");
return a + b;
}

}

class StrategySubtract implements IStrategy {

public int execute(int a, int b) {
System.out.println("subtract");
return a - b;
}

}

class StrategyMultiply implements IStrategy {

public int execute(int a, int b) {
System.out.println("multiply");
return a * b;
}

}

class StrategyDivide implements IStrategy {

public int execute(int a, int b) {
System.out.println("divide");
return a / b;
}



// Configured with a ConcreteStrategy object and maintains a reference to a Strategy object
class Context {

private IStrategy strategy;

// Constructor
public Context(IStrategy strategy) {
this.strategy = strategy;
}

public int executeStrategy(int a, int b) {
return strategy.execute(a, b);
}

//setter method for strategy
public void setStrategy(IStrategy strategy) {
this.strategy = strategy;
}


}

Monday, 10 May 2010

Refactoring

What is Refactoring
Refactoring is the process of changing the source code alterning the internal structure without changing the external behavior of the code.

Before refactoring the code, complete set of unit-test cases are required. After refactoring the small piece of code then run the test suite to make sure that the code is not broken.

Advantages:
- Readability
- Maintainability
- Extendability

Refactoring Techniques:
o Encapsulate Field – force code to access the field with getter and setter methods
o Generalize Type – create more general types to allow for more code sharing
o Extract Method, to turn part of a larger method into a new method. By breaking down code in smaller pieces, it is more easily understandable. This is also applicable to functions.
o Extract Class moves part of the code from an existing class into a new class.
o Move Method or Move Field – move to a more appropriate Class or source file
o Rename Method or Rename Field – changing the name into a new one that better reveals its purpose
o Pull Up – in OOP, move to a superclass
o Push Down – in OOP, move to a subclass

Martin Fowler explains the refactoring techniques with the diagrams and is really good.

Refactoring Techniques by Martin Fowler

Friday, 7 May 2010

Composition / Inheritence

inheritance models the is-a relationship




class Fruit {

public String taste() {

System.out.println("It is sweet.");
return "Sweet";
}
}

class Orange extends Fruit {

//...
}




composition models the has-a relationship




class Fruit {

//...
}

class Orange {

private Fruit fruit = new Fruit();

public String taste() {
return fruit.taste();
}

}





* Composition allows you to delay the creation of back-end objects until (and unless) they are needed, as well as changing the back-end objects dynamically throughout the lifetime of the front-end object.

* With inheritance, you get the image of the superclass in your subclass object image as soon as the subclass is created, and it remains part of the subclass object throughout the lifetime of the subclass.

* It is easier to add new subclasses (inheritance) than it is to add new front-end classes (composition), because inheritance comes with polymorphism.

* The explicit method-invocation forwarding (or delegation) approach of composition will often have a performance cost as compared to inheritance's single invocation of an inherited superclass method implementation.