Sunday, December 30, 2007

The Object Oriented way

At Thoughtworks, anyone who apply for the position of developer, need to submit code for a problem. I don't take part much actively in recruitment, just because yet i am not good enough for it. But still, I sometime get a chance to look at code written by people who have significant years of experience. And surprisingly, I found that
most of the time, the code written by these techie and experienced guys is pathetic. I know I am not a very good OO programmer, but I think, most of the code I saw was not OO at all. It was just a procedural code written in language like Java, C++ that supports OO.

My present project has a legacy code written in C#, which is one of the prominent OO languages. But I can bet that the legacy code in my project can be an ideal example of how to write procedural code in a OO language. It has all the problems that a typical large procedural program will have. Is witting a good (or not so good) OO program difficult ?

Most important thing that is missing is Object oriented way of thinking about problem at hand. OOP needs a way of thinking that is entirely different from procedural way.

In simple words, procedural programming says that program or a software system is a set of instructions and procedures. In procedural programming, when we have a problem to solve, we think about the procedure to solve it and then write that procedure down in form of function/method. Now the data is provided to this function, it operates on it and provides result.
Here, data is put into separate structures and there is no binding between data and functions.

In Object oriented world, a program or system is made up of collection of interacting objects. Every object has its own attributes and certain behaviour and responsibility.In OO way, when we have problem to solve, we think about objects that plays role in problem and the responsibility of each object, rather than thinking about the procedure to solve problem. The objects interacts with each other by sending messages (calling methods) to each other. Then We write classes that has data and behaviour binded together and the objects of classes interacts to solve the problem. So the entire way of thinking in OOP is different than procedural programming.

The concepts of OOP resembles to real world. In our world, everything is object with attributes and certain behaviour. e.g. consider a dog. It has attributes like color, size, height etc. and it has behaviour like walk, eat, bark etc. These attributes and behaviour are not separate, they are the part of a Dog itself. When we perform any action, a set of objects interacts with each other.

The main features of OOP like encapsulation, polymorphism and abstraction can be easily seen in the real world also. Consider a break of car. The break has certain attributes and behaviour. It is encapsulated within the assembly of break. The internal details of how the break operates is not visible to the user. User just preform the action of pressing the breaks and break perform the action of stopping the car. How break achieves this is abstracted from user. The mechanism break applies to stop the car is private to the break and external world, including user need not know about it i.e. the internal implementation is abstracted from user.

Lets get back to the original question, Is OOP difficult ? I guess, its not difficult and certainly different than procedural way and we need a entirely different way of thinking. Just by using a language like C++, Java or C# that supports OOP doesn't makes our code OO. OO way of thinking is must for witting good OO programs !

Saturday, December 29, 2007

Using cflow() and cflowbelow() in pointcuts

Control flow is just the flow of execution of program within specific join point. cflow() and cflowbelow() constructs takes another join point as argument and allow us to define control flow based pointcuts - the pointcuts that captures all the join points in the control flow of specified join point.

cflow() captures all the join points e.g. call, execution, set and get field, error handlers in the control flow of join point specified as argument along with the specified join point itself.
cflowbelow() behaves same as cflow, however it doesnt captues the join point specified as argument, but captures all other join points that comes below that.

For example, Consider a class -

public class Test{
private int value;

private void method(){
value = 10;
}

public static void main(String[] args) {
new Test().method();
System.out.println("Exiting Test.main()");
}
}

And an aspect -

public aspect ControlTestAspect {

pointcut controlPointcut() : cflow(call(void Test.method())) && !within(ControlTestAspect);

before():controlPointcut(){
System.out.println("In Control pointcut : " + thisJoinPoint);
}
}

This aspect contains pointcut that captures all join points that are triggered during the control flow of method method() of class Test. The output of running the Test class is -

In Control pointcut : call(void Test.method())
In Control pointcut : execution(void Test.method())
In Control pointcut : set(int Test.value)
Exiting Test.main()

As we can see, the before advice is called for all the join points that comes in the control flow of method() execution.

If we use cflowbelow in the pointcut instead of cflow, the output will be -

In Control pointcut : execution(void Test.method())
In Control pointcut : set(int Test.value)
Exiting Test.main()

i.e. it captures all the join points that are below the specified join point.


When defining pointcut using cflow or cflowbelow, we need to ensure that the pointcut does not capture the calls that are made from the same aspect, otherwise it will invoke recursive method calls and we will get StackOverflowError. This happens because cflow() will also capture the method calls from the aspect itself and try to apply the advice to it.
This can be avoided by using within() construct. within() takes a type(class or interface) name as argument and captures all join points the are defined in that type.

To capture all the join points in the control flow of method foo of class Test and excluding the calls from the TestAspect, we can define the pointcut as -

pointcut controlPointcut() : cflow(call(void Test.foo())) && !within(TestAspect);

This pointcut will exclude the join points that are triggered directly by TestAspect, however if the join points are invoked indirectly in the control flow of advice then those join points will still be captured. e.g. If the advice in TestAspect calls method shoo() of class Test2 and this method calls method foo of Test, then this join point will NOT be excluded by above pointcut and we will get StackOverflowError because of recursive advice invocation. This can be avoided by using adviceexecution() construct.

pointcut controlPointcut() : cflow(call(void Test.foo())) && !cflow(adviceexecution());

This pointcut will happily exclude all the join points that are triggered directly or indirectly by the aspect.


Lets look at the places where cflow and cflowbelow() can be used effectively.

# One obvious use of cflowbelow is to capture non-recursive call to method.
e.g. consider a class Foo -

public class Foo {

private void count(int value){
if(value==0) return;
System.out.println("Hi!");
count(--value);
}

public static void main(String[] args) {
new Foo().count(2);
new Foo().count(2);
}
}

If we want to capture only the non-recursive calls to the method count(), then we will need an aspect like this -

public aspect FooAspect {

pointcut countMethod() : call(void Foo.count(..));
pointcut nonRecursiveCountMethod() : countMethod() && !cflowbelow(countMethod()) ;

before() : nonRecursiveCountMethod() && !cflow(adviceexecution()) {
System.out.println("In nonRecursiveCountMethod pointcut : " + thisJoinPoint);
}
}

The output of running the Foo class is -

In nonRecursiveCountMethod pointcut : call(void Foo.count(int))
Hi!
Hi!
In nonRecursiveCountMethod pointcut : call(void Foo.count(int))
Hi!
Hi!

As we can see, only calls that are made outside of method count() are captured and recursive calls are ignored.


# cflow and cflowbelow are useful if want to perform operation only in specific part of your application (or if you want to restrict the operation in specific part). e.g. if you want to add security check on method call of some class, say Foo only if the method is called from methods in web tier classes (and their subclasses), then we can write pointcuts like -

pointcut methodCalls() : call(public void Foo.*(..)) ;
pointcut methodCallFromWebTier() : methodCalls() && cflow(call(* com.webtier.*+.*(..)));

Now, we can write advice for methodCallFromWebTier() pointcut to perform specific operation.

The pointcut can be easily modified using unary NOT (!) to do operation when method is called from anywhere other than the control flow of methods in web tier classes.

pointcut methodCallFromWebTier() : methodCalls() && !cflow(call(* com.webtier.*+.*(..)));

Tuesday, December 18, 2007

Static crosscutting with AspectJ

Crosscutting concerns are the features of the system that are applicable across the system. They need to be applied in the system-wide manner in multiple modules. Examples of the typical crosscutting concerns in typical system are authentication, security, error handling, logging etc.
Crosscutting concerns can be addressed in two ways - Dynamic and static. Dynamic crosscutting modifies the runtime behaviour of system and static crosscutting helps to change the static stracture of program. Here, I will only discuss about static crosscutting, and will blog about dynamic crosscutting seperately.

Lets look at way in which static crosscutting can be applied.

## One of the feature of Ruby is that all the classes in Ruby are open. That means you can add new members to the existing class. Its a native feature of Ruby language. However, same feature can be achieved in Java with AspectJ. By using aspects, you can add new members to the existing class or interface. We can add new field, method, constructor into existing class. This is called as static member introduction.

e.g. To add new members in the class Foo, we will write as -

public aspect FooAspect {
public float Foo._newField = 9.0;

public void Foo.newMethod() {
System.out.println("Crosscutting - The static way !");
System.out.println("Value of field : " + _newField);
}
}

These new members will be available to use when we weave(compile) this aspect with Java class Foo.

New methods can be added in interface with implementation, you can not add just methods signature ending in semicolon. This implementation acts as default for all implementing classes. If we want to modified method for some class, we need to define that method either in aspect or directly in our class.

The following aspect adds a new method in FooInterface interface.

public aspect FooInterfaceAspect {

public void FooInterface.blue(){
System.out.println("In new method from Aspect");
}
}


## We can change the class hierarchy with declare parent clause. We can add new parent to the class or add an interface to the class or set of classes.

e.g. To implement FooInterface for Foo class -

public aspect FooInterfaceAspect {
declare parents : Foo implements FooInterface;
}

Following piece of code implements the interface to group of classes and implements the method in individual classes.

public aspect MyAspect {
declare parents : com.webservices.messages.* implements SomeInterface;
public Object ClassOne.method() {
// do something
}
public Object ClassTwo.method() {
// do something else
}
}

Instead of writing separate method for each class, We can also write a single method which will be used by all classes. This can be done by defining the method on interface rather than on class.

public aspect MyAspect {
declare parents : com.webservices.messages.* implements SomeInterface;
public Object SomeInterface.method() {
// do something
}
}


This feature along with member introduction can be used intelligently to achieve modular solutions when using with third party API. An excellant example of this is given in article AOP banishes the tight-coupling blues.

Similar to class, We can also extend an interface.

public aspect FooInterfaceAspect {
declare parents : FooInterface extends ShooInterface;
}


## We can give out compilation errors or warnings by using -

declare error : pointcut : message;
declare warning : pointcut : message;

For Example, following aspect gives compile error when method method() of Foo class is used and gives warning when anotherMethod() is used -

public aspect FooAspect {
declare error : call(void Foo.method()) : "No way man !";
declare warning : call(void Foo.anotherMethod()) : "You shouldn't do this !";
}


We can use this to give out compilation errors or warnings when some deprecated or unsupported methods are called in code. Or we can use this to recomment usage for methods.
This is useful when we have to use third party code or API and we want to regulate the usage pattern.


## We can use AspectJ to soften the checked exceptions.
There are two types of exceptions in Java. For Checked exceptions, the caller of the method which throws exception need to handle it explicitly by using try-catch or by re-throwing it. And other is Unchecked exceptions which need not be handled explicitly. They are subclasses of RuntimeException or Error.

This piece of code softens i.e. converts the checked exception into unchecked exception. So that the caller of the method do not need to handle it.

public aspect FooAspect {
declare soft : java.rmi.RemoteException : call(void Foo.method());
}

Now the caller of method method() do not need to handle the exception explicitly. This is achieved by adding try-catch block around the method call in code during weaving process. In the catch block, actual exception is wrapped in org.aspectj.lang.SoftException and throw again.SoftException is a subclass of RumtimeException.


## We can define the precedence of advice with the declare precedence clause.
e.g.
declare precedence : LoggingAspect, ErrorCheckAspect;

Only concrete aspects are meaningful in the list of aspects. Having abstract aspects in the list has no effect. However, we can use wildcard characters. e.g. If Logging and ErrorCheck are two abstract aspects, you can give precedence to aspects that extend logging over the aspects that extend Security as-
declare precedence : Logging+, ErrorCheck+;

The following declaration gives precedence to all the aspects that have 'Logging' in their name.
declare precedence : *Logging*, *Error*;

Having a same aspect more than once in the list,which makes cyclic precedence, is not allowed and it gives error. e.g.
declare precedence : LoggingAspect, ErrorAspect, LoggingAspect; // Error !

However,

declare precedence : LoggingAspect, ErrorAspect;
declare precedence : ErrorAspect, LoggingAspect;

is allowed as long as the pointcuts in two aspects are not matching or overlapping. If any pointcut in two aspects are same then we get an error saying "conflicting declare precedence orderings for aspects".


Finally, one last point. The pointcuts that are used in static crosscutting has a limitation. All the static crosscutting pointcuts should be such that they can de determined at compile time. So pointcuts can not be determined in terms of cflow, this, if, target, args.

Wednesday, December 5, 2007

What is Metaobject protocol ?

In traditional programming languages like C, C++, Java, programming language designer works at different level of abstraction than programming language users. Language designers writes programmers that decides how the elements of programming languages works and how the features in the languages such as method dispatch, inheritance are implemented. And the programming language users work on writing the primary application classes without having the flexibility of changing the way language itself works.

However, in some languages like Common Lisp Object System (CLOS), Groovy and Ruby, the programming language provide interface to alter and enhance the core features of programming language. This allows changing the way language throws certain exception or implementing multiple inheritance in language that does not allow it by default.

Metaobject protocol is a interface to programming language using which programmer can add and modify the features to programming language. Here, programming language users play with the Meta objects. These objects decides how features like inheritance, method invocation, scope resolution behaves. These objects are called as Meta Objects simply because they holds information about object like methods, fields, super class etc.These objects also controls run time behavior of program and how the primary objects in the actual system works. We can say that Metaobject protocol makes features of compiler/interpreter available to the programmers.

Metaobject protocol is an important feature for meta programming (However, some programming languages like smalltalk allows to do elegant metaprogramming without MOP). It also allows programmers to adjust language according to their needs.
For example, Common Lisp Object System (CLOS) adds object oriented and dynamic language features to LISP using Metaobject protocols. The implementation of language is done by implementing classes as objects of a metaclass and allowing programmer to change behavior of base class and also allow defining new metaclasses.

Groovy, a dynamic scripting language for JVM, implements Metaobject protocol. Metaobject protocol in Groovy decides how the core language functionality like method dispatch, scope resolution for attributes works. It gives more flexible control of language in programmer's hand. And Ruby has many features that allows programmer to do amazing things like changing the behavior of class on run time, defining methods dynamically etc. The AOP implementation for Java called AspectJ is also implemented with Metaobject protocol.

In short, Metaobject protocol gives some amazing power and flexibility to the programmer which can be used with little caution to create amazing programs !

AOP - Need to explore more..

When I came across AspectJ first time, I was unsure how to use it effectively. And when I started exploring it, i was amazed by the enormous capability it has, power to create highly modular and clean design. AspectJ and in turn, Aspect Oriented programming (AOP) has lot of potential to solve our programming hurdles. Still I am exploring the field and checking the places where it can be used effectively.

In my last project, I used AOP mostly for logging and once for authentication (thanks to people who worked on it). But there are lot of much more serious things that can be done.

It depends on us how we can separate our code into aspects and have the "multidimensional" programming code rather than mixing all the aspects into single dimension. Obviously, AOP is not here to replace OOP. Both AOP and OOP need to collaborate to produce the most modular and maintainable code. In fact, AOP allows us to address the problems that are (to some extent) out of scope of OOP.

I think, the excellent OOP design can partially address some of the issues that AOP is solving. So, why to use AOP ? The most obvious answer is AOP is better way of doing it !! Its best suited for addressing the crosscutting concerns. And we always prefer better and cleaner way of doing things. Practically, there is no program that can not be written using machine language or even brainfuck (which is one of those Turing complete esoteric programming languages). But still we use Java and C++ because they are address the problems more effectively and easily !!