Showing posts with label Opinion. Show all posts
Showing posts with label Opinion. Show all posts

Tuesday, May 15, 2012

Achieving Decoupling: Dependency Injection v/s Event driven design

(Update: A more exhaustive sequel post is in progress on this topic so don't be disappointed by lack of details and stay tuned)

Coupling is considered to be a bad sign in a software design, having seen enough of it in practice I agree with this belief. The need for decoupling has resulted in a cottage industry of IoC containers in Java ecosystem, where it still remains popular, so this is not a philosophical topic.

When I was learning object oriented software design as a student, the gist I received was encapsulation and message passing between objects with state. In theory this sounded great, objects with behavior and encapsulated state seemed unbeatable (given that I only knew BASIC and C).  In real life, however, I have found that it is hard to keep objects simple while keeping their dependency fulcrum in control. This may not correlate in real OO programming languages like Smalltalk but I can't speak for that.

Given that I've only worked on a relatively medium to larger enterprise applications (ranging from 10KLOC to 1MLOC+)  this might sound a bit biased: most enterprise applications are not object oriented. This is counter intuitive given that OO approach is considered to excel at modelling large systems by breaking it down in to more manageable pieces, but I digress.

Coming back to the main issue, how can we control coupling?

Dependency Injection
The most popular option so far is to exploit dependency injection to invert the dependencies. The touted benefits of it are: testability, flexibility and abstracted, and hence, switchable implementations.
For example:
interface IHttp{  InputStream open(URL url); }
class FireFox implements IHttp{ 
 InputStream open(HtttpURL url){  doOpen(url).andLeakSomeMemoryAsDesigned(); } 
}

class Chrome implements IHttp{
 InputStream open(HttpURL url){ feedUserInfoTo(googleAI).thenOpenUrl(url).makeItFast(); }
}

class InternetExplorer implements IHttp{
 //Since no one uses it apart from downloading other browser,
 // being efficient, user friendly or useful is just a misplaced goal.
 InputStream open(HttpUrl url){ 
  waitIndefinitelyOrForeverFor(url).attemptToLoadWhenever(url).possiblyReadOrJustGiveUp(); 
 }
}

class MavenHttpClient implements IHttp{
 InputStream open(HttpUrl url) {
   downloadKnownInternetFiveThousandTimesEveryHour().completelyIgnoringWtfHttp()
   .then()
   .inflictDarkSufferingOnUserAndBeReluctantlyOpinianatedAboutHowYouScrewUpBuilds().asAlways(); 
 }
}

class MyHappyEnterpriseApp{
 IHttp http;
 setBrowser(IHttp browser){this.http = http} //Injected dependency
 void myBusinessLogic(){ http.open("http://blog.nirav.name").doSomething() }
}
So by coding to interface and relying on a dependency injection "container" we get all the prescribed  benefits. This is the de-facto standard to achieve decoupling in current enterprise application architecture in Java ecosystem.

Event Driver Design
The second obvious alternative (may be not so obvious to many) is to fall back to good old message passing which can be synchronous or async. Isn't OO approach all about message passing and keeping state encapsulated while reacting to meaningful messages? Turns out, it doesn't jive well enough with statically typed languages such as Java.

Instead of lethally injecting objects with dependencies (abstract or concrete) why not just send a message which will be observed by objects who are really interested in responding? The benefits here are inclusive of the ones offered by dependency injection but are more evolutionary.

For example, The similar implementation of the above design can be represented as events:
interface IEvent{}
interface HTTPEvents{
 interface OpenUrl extends IEvent{
   InputStream open(HtttpURL url);
 }
}
class FireFox implements HTTPEvents.OpenUrl{
 InputStream open(HtttpURL url){  doOpen(url).andLeakSomeMemoryAsDesigned(); } 
}

class Eventing{
  Dictionary events; //initialize implementations
  T  sync( evt){
    return events.lookupImpl(evt.getType()).send(evt);
  }
}
class MyHappyEnterpriseApp{
 void myBusinessLogic(){ doSomething(Eventing.sync(HTTPEvents.OpenUrl, "http://blog.nirav.name")); }
}

While simplistic, this implementation should provide general idea that dependency injection is not the only true way to achieve decoupling.

Even the most complex systems are designed around the idea of message passing (Linux kernel, Win API and so on) where it successfully achieves decoupling from user land API (POSIX) from physical implementations (e.g. CPU interrupt faults and traps). This elucidates a strong merit that message passing can be applied to a general purpose applications (which are comparatively less complex). It is not a novel approach to system design but it appears that reinventing the wheel is in the fashion as far as enterprise application development goes. JMS has been a solid spec geared more or less towards similar principles but it is viewed only as a queueing mechanism to offload the async task.

I guess not every one sees coupling from the same angle and starts to build yet another money making framework to achieve the same goal. I hope that agent driven libraries like Akka and Erlang style message passing gets some more attention from enterprise app community to see how benefits beyond coupling (performance, fault tolerance and scalability) are achieved with message passing.

Monday, March 05, 2012

On Static v/s Dynamic typing

I've been pondering about trivialities again, I am observing how most programmers have strong vested interest in defending static v/s dynamic typing as if they are mutually exclusive.

There're those who think static typing is the ultimate engineering solution to build reliable software and dynamic typing is some kind of a sick joke to put their lazyness to test. Then there are those who think types are for primitive minds and variable declaration is an insulting feature.

At this point in time, I can relate to both groups as I've had strong opinion on this subject. Having opinion on typing is OK, I think. (having no opinion on this topic basically means google didn't work for you and you should head back).

Most programmers go through, what I call, a typing evolution cycle. I started with dynamically typed language (name removed because of possible copyright violation). It was really great to stuff everything in to a variant (actually I never even bothered to declare variables!) and not worrying about compilation or runtime errors, it mostly ran. Then I was introduced to C (and later C++) and I remember how I hated it because I was now forced to declare variables and had to think about what I wanted computer to do upfront. It was alien to me that compiler will point out my mistakes instead of doing my bidding. During that time I was a supporter of dynamic typing because I was naive.

As the time went by I got more used to static typing with interesting IDE features such as IntelliSense of Visual Studio. Writing correct program was much easier now and it always worked (mostly correctly). Then came the Java programming, everything was object (except primitives). Large projects and Eclipse JDT made me appreciate value of static typing. When I start writing test I don't think about type errors because they are taken care of, I could easily refactor code without nightmares that something could be broken. Scala's type inference and simpler type system actually boosted my faith in static typing even further. At this point in time I supported static typing because I was naive.

This was my experience, may be it is reverse for others (starting from static typing and going back and forth).
My views have changed on typing over the time. Depending on what I'm working on, I don't mind hand-waving type system (coupled with esoteric tests) for a quick isolated stab that brings a lot of benefits v/s a bloat of API to do the same in few years. While still having the confidence in my software being immune to my bad keyboard-fu and assurance that stupid mistakes will not make it all the way to production. Probably, I'm still naive.

Monday, October 24, 2011

On using "PermGen" as application level cache

I was reading an interesting article 'Assualt by GC' by stack exchange guy and it felt like a Déjà vu with my past couple of years of development on the JVM. It struck to me that we can definitely do better, so here it goes..

Automatic GC is really a great step forward in software development, except when it is not. If you have deployed application on a JVM with large heap (4g+) you probably know what a long GC pause really feels like [insert familiar knock-knock joke about java]. Jokes aside, JVM's GC advancement is unprecedented. The amount of tuning you can do with different garbage collectors can define a niche profession.

For most applications where GC latency isn't an issue; default garbage collector works just fine. For applications which need to scale GC can (and does) become a 'bottleneck'. If you disagree, try running a JVM under memory pressure and see app response times. It should be surprising because in most data driven applications bottleneck is usually IO or other IO bound resources (e.g. a DB). This situation generally happens when GC is completely thrashing the process because there are too many "tenured" objects which don't fit in the allocated heap or heap is fragmented and GC wastes a lot of time compacting the heap. Unlike .NET, Java folks are not very lucky with platform specific optimizations such as locking pages to prevent swapping. So it is not uncommon that a full GC causes excessive paging, making GC IO bound.

Turns out that GCing large "tenured" object space is expensive compared to short lived young objects (sweep). A large population of "tenured" objects is generally a genuine requirement for long running server processes relying on large amounts of data and this requirement shouldn't really punish application with long GC pauses. While not impossible, it is not really practical to set size of tenured generation very large because it may adversely affect young generation collections. JVM GC optimization is a skill not in abundance but the problem is all too common. So what can we do about it?

One way to eliminate GC on predictable "tenured" application data is to just not store it on JVM heap (i.e. use direct byte buffer etc. ). I've been watching solutions like Terracotta's BigMemory which uses similar approach to address GC issues. However all such solutions seem a mix of  manual memory management with hacks to circumvent GC which end up being half-baked reinvention of JVM's copy-on-write "permgen".

Most of the java developers I know consider "permgen" to be some kind of evil which causes all kinds of problems including "eclipse crashing", crying JSP/[insert other template library] compiler, unpredictable class unloading and really large interned strings which stick around. "permgen" is going to go away from the hotspot vm, which is kind of sad because I think it could be a great way to achieve GC free heap storage for application level data (more specifically cache). This is not really possible unless "permgen" is used for one specific purpose, and if that specific purpose allows application to store its data, we can have standard supported GC free application data without the need of third party solutions which achieve the goal poorly. Even better would be java.cache using "permgen" for cache storage.

One of the commenter at HN talked about Smalltalk VM's way of using permgen (just send a message to  object to move itself to "permgen"). I like this approach because applications can control which objects are long lived which is sensible because they have the best knowledge about long lived objects. The only similarity in JVM we have is String.intern, which unfortunately caches strings forever and it is not really as useful as having some kind of eviction control.

So, what do you think about this approach?

Tuesday, September 06, 2011

Thoughts on Event sourcing

I read about event sourcing a while back and I couldn't stop thinking about it so it had to explode here as a blog post.

A typical data driven application involves CRUD operations on domain entities which are important to business. Such application typically capture data from user or other system in a centralized database for reporting or for further distribution. Architecture of such application is generally simple and there's a vast ecosystem of platforms, frameworks, tools and libraries to support it.

If we wanted to represent traditional design of such application in terms of a state machine, then we can say that such application capture, distribute and allow reporting of domain in a certain state. The primary objective of such application is to facilitate data manipulation (CRUD) which changes state of the domain. For most applications it is generally a sound design ignoring familiar caveats.

Thinking in terms of state machines, there's an interesting alternative: we can store all the state transitions that led initial domain model to its current state. This second perspective to application design has many interesting repercussions. In this approach, current state of domain is no longer as important as the earlier approach because it can be recreated just by repeating all the transitions. This second approach is named "Event sourcing" where event is just a little familiar name for state transition.

Not every application care about the easy recreatibility aspect of domain, most business applications care only about current state of domain. However many applications, especially the ones with mandated audit trails or domain with significant historical data, can benefit from event sourcing. A common example of such application is a version control system, version control systems capture state transitions (diffs) of domain entities (source files) so you can switch to any state (version) and rebuild it to desired state by successive applications of  state transitions (diffs).

As far as business domains goes, Insurance domain by far seems to be a great area of application for event sourcing given that audit trail is a legal compliance requirement and insurance domain models tend to be really complex. Think of an insurance policy as a state and all the changes to it (endorsements) as transitions. By just tracking the transitions, one can rebuild a policy to its current state and reason about it for underwriting analysis and audit. Compare it, instead, with our initial approach of capturing multiple states (identical records in relational database) with complex logic to diff them and comparing them. This approach has profound positive implication on usability of application as well as testability, with this approach it is easy to visualize and rebuild data of interest to any point in time.

One more interesting application of event sourcing, I think, is in data mining. If data is stored as events it is fairly easy to sample, plot and build historical and predictive models. My limited experience in mining data has always involved custom (expensive) efforts to store historical data, such custom efforts usually involve complex development efforts just to extract marginally meaningful information.

It shouldn't be surprising that event sourcing can have significant influence on application architecture which may not be an easy sell especially in a larger setting. There are many related concepts to event sourcing, specifically CQRS which lead to wild architectures (which I'm not quite fond of yet).

I'm learning this is not new or revolutionary and has been done in past but never caught up for whatever reasons, nonetheless I find it interesting. As far as my technical curiosities go I'm very much inclined to try it out with a pet project to see how far these benefits are viable.

Saturday, May 01, 2010

Future of a Java programmer

As a long time Java only programmer professionally, I have been pondering about how things are changing around me as a Java programmer. Ever since I remember I had no choice but to use subset of C++ dialect (Java lang) with an extremely rich class library and ecosystem (Java platform).

In last few years there has been a drastic shift in number of languages targeting JVM. For example: dynamic (javascript, jruby, jython, groovy), functional + OO (scala) and a lisp dialect (clojure) and so many others. While I am excited about all the options I have today I don't think a single language will dominate on JVM anymore like Java did so far.

In a way this is a good thing, one tool rarely fits all needs (I couldn't curse Java enough for GUI programming). Like C, Java was never designed to be used for developing dynamic web apps, but we still tried and miserably failed with JSP/JSF and plethora of frameworks against PHP/Rails/Python in terms of productivity. One really good thing Java did was to raise a level of abstractions from platform specific details and memory management. These new languages on top of JVM raise the abstraction level even further for its area of strength.

It is not a remote future when we will see concurrent processes being programmed in clojure and presented with jruby/rails with intermediate code written in Java. Each layer of application is going to be implemented in different programming languages while interfaces being transparent for developers working in each layer. This is a big thing, it has never been envisioned before for Java Platform, the lowest coupling we have seen so far is through remoting (web services et. al.) where clients and servers are on different runtimes and languages.

What this means for a Java developer is if you are

  • A web developer: you are going to learn things which are extremely different from struts/jsf/jsps, no more artificial model1/model2 MVCs.
  • A non web-developer : you are going to write code which is far more readable and very specific to your business domain via DSL created in any of the languages mentioned above without worrying about accidental complexity Java and its frameworks imposed on you.

While I can keep classifying developers on Java platform all day long, these two are major ones whose life (and resumes) are going to change soon, they will be expected to know more than one programming languages rather than frameworks now. Contrary to the cool kids on interwebz, I don't think Java the language is going to die anytime soon not because many of the existing libraries are written in it, but because of the number of programmers on earth who know Java, tooling around it and the native JVM support for it. Java is like C in a way, you can do whatever is supported by underlying implementation.

Many of you who are like me are going to see change around them soon, I am thrilled to see how my career is going to transform as polyglot programmer are you?

Thursday, April 16, 2009

Your Language is not SLOW!

Do you really give a thought when you say "Ruby is slow or Python is slow"? Just because Twitter moved their back end messaging to JVM doesn't necessarily make Ruby any slower than it already was. If a language runtime can't handle concurrent load or long running processes it is not a limitation of the language!

This is dejavu for me as Java was considered "a slow language" back in 1.1 days when HotSpot JVM was in its poorer life and ISO/IEC C++ was hot girl in town. Now that you realized your pony implementations can't catch up with real life performance expectation you start blaming languages, are you serious?

Whether it's global interpreter lock or lack of native threads it's the runtime (re-read the runtime) and not the language that is slow. For the love of technology, Stop blaming languages for poor performance of your suboptimal reinventions!

Every language implementor should at least consider the host platform support before coming up with their "Not Invented Here" approach, sadly that's what is happening with most modern languages.

Thursday, April 09, 2009

Scala: First impression

If you are curious enough about programming languages then you probably have heard about Scala - the 'statically typed' functional and object oriented language. Scala is the new sun rising to balance 'the burn factor' between functional and object oriented schools of thoughts.

Unlike what this paper suggests[pdf], The reason why I think Scala exists is because functional v/s object oriented groups are moving in opposite directions, which is not only inefficient but they can't leverage achievements of one another. If you read about functional v/s object oriented programming comparison, every argument boils down to productivity, tooling and maintainability of code. While functional languages (Lisp, Haskell, Python etc.) offer excellent productivity compared to OO languages (Java, C++ etc.), Object oriented languages offer excellent tooling and are relatively maintainable. The reason why I think OO languages have been so popular is due to its easier to understand concept which is easy to map in real life, so for most people who have never took computer science course OO is still easier to grasp compared to Functional programming methods like list comprehension, closures or the higher order functions which are rooted from the formal systems of mathematics.

Scala tries to satisfy both of the groups by providing grammar and a type system which seamlessly integrates with mainstream platforms (Java, .NET) and offers powerful functional abstractions only available in dynamic languages. What this means is, Java developers can write their code in same fashion they write in Java using existing libraries and frameworks but with an added advantage of functional programming techniques wherever they feel it might be productive. Functional programming language enthusiast get access to rich class libraries and powerful tooling (eventually).

If you take a look at the Scala language grammar[pdf] you will notice that what you can create with Scala is limited by your creativity. Based on what I have learned so far, I find Scala much more refreshing than Java, Scala feels a lot more like a programming language of the 21st century! Scala compiler itself is pluggable so you can do heck of a stuff you can only dream with javac, ecj. What is missing is tooling, the existing tooling is scrap but that will improve hopefully with an active community.

Bill Venners of Artima has presented Scala wonderfully, take a look at the presentation[requires flash] on 'The feel of Scala'.

Wednesday, August 06, 2008

Synchronizing client requests using Ajax

Before few months I was dealing with a problem where I needed to synchronize the server call sequence on browser. The problem was something like this: Client code will open new window navigating to a different page, but that should happen only after post on current page. The link that new window was opening needed to be server synchronized because of database updates etc. on server.

Being ignorant java-script developer I went ahead and put 'window.open' in onsubmit event of submit button, hoping it will be executed before form is submitted; Apparently, it failed. The event handling/dispatching/capturing in java-script is in sad state - it's specific to browser and I must make it work for IE so the pain is obvious. To reveal some more ignorance, I thought of putting 'window.open' in onmousedown event assuming form will not be submitted till the code in onmousedown is executed
fully, that too failed. Then, it was clear that 'window.open' was essentially a thread fork and will execute in parallel so this event capturing is not going to work here.

Since there was no obvious fix to my problem, I thought of using XMLHTTP for asynchronous wait to synchronize the request. I created new page which will open in a new window with javascript that handles form post in parent window, looks like following:
<html>

<body onload="postParentWindow()">
<%
out.print("Loading Print Preview, Please wait...");
%>
</body>
</html>


getFormValues is a function which concatenates all the input's selected values and makes a request string. More interesting things are done in makePOSTRequest method:
var http_request = false;
function makePOSTRequest(url, parameters) {
http_request = false;
try {
http_request = newActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
http_request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
http_request.onreadystatechange = navigateToOtherPage;
http_request.open('POST', url, true);
http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http_request.setRequestHeader("Content-length", parameters.length);
http_request.setRequestHeader("Connection", "close");
http_request.send(parameters);
}

function navigateToOtherPage() {
if (http_request.readyState == 4) {
if (http_request.status == 200) {
window.navigate('newpage.jsf');
} else {
alert('There was a problem with the request.');

}
}

(Note: This code completely disregards browser compatibility and good error handling etc.) The important thing here is, we can assign a function to XMLHTTP object that will be executed after server response is received so that serves my purpose of synchronizing the request. I find this use of AJAX pretty useful in building stateful web-applications. The code might look very crude but powerful abstractions can be built over it to make a nice utility framework for such use-cases.

Thursday, March 13, 2008

Unusual tip to find refactoring hot-spot

Disclaimer: This post contains generalization based on my experience, it may or may not be applicable in every state of code-base resembling this situation.

Most of you have probably been through this list of smells to refactoring. In Recent refactoring sessions I discovered a new (at least unusually new) way to identify "hot-spot" needing refactoring.

This might be in turn related to some other smells (like most of them), but here it is:

- A (set of) source file with significantly more revisions compared to it's dependencies demands refactoring.

The obvious question here is why?
- Number of revisions for a source file indicate that it is being modified more frequently than it should. There can be many reasons why a source file is being modified among:
  • Imperative requirements change or
  • A source file that tries to do so much than it should
Now, requirements change is something very common in everyday life. But generally speaking ( opps! ), Not all requirements ask for a significant change in control flow but data. Depending on the domain, you can externalize the portions which keep changing to helper classes or configurations.

A source file trying to do more than it could is always a problem and is generally perceived as 'God module', it's time to slice it down.

So next time you feel like hunting for bad code, look at the revisions and you will have hint where to start. Good hunting.

PS: Note that I've deliberately generalized this to 'source files' and not the configurations.

Monday, February 25, 2008

Six reasons why you should know internals of your IDE

May be this is overwhelmingly obvious to geeks, but I am going to describe it nonetheless. This might not significantly impress non-developers or the people and programmers (yes, they are different) who can't describe the word 'tooling'. A developer's productivity is highly dependent on the tools they use, whether it's a fancy big fat IDE platform or an editor as abstemious as VI.

Apparently, the business we work for doesn't really care for the tools we use most of the time - unless of course they are suppose to pay for it. But as simple as it is, If you know how the IDE you use works and how you can make it work the way you want, can make all the difference in your productivity. Here are some unimpressive hows:

1. Many mundane and stupefyingly boring tasks can be automated if your IDE supports macros or extensions. Learn it, it will relieve your back/wrist pain.

2. You may have some fun exploring a totally different software architecture than you may be writing day-to-day, this may turn out to be way too interesting than your day job. Learn it you will know how to design.

3. Sometimes your IDE is just used for a single purpose - coding, but If you know how to extend it you might be motivated to add some cool stuff to it like chat view next to problems view in Eclipse or may be rolling reddit RSS entries in status bar. Learn it, possibilities are never ending.

4. Integrate your IDE to reproduce bugs in your application. This is similar to 1 but different in the way it solves your problem, this may not always possible but worth a thought. I managed to write several plug ins for quickly reproducing bugs related to my application components. Learn it and you can quickly fix them.

5. You can devise custom metrics from your code like how many lines you delete everyday compared to how many you write. Learn it and you will get to know your weird programming habits.

6. You never know when you get in to alternative job market if you know your tools well. Tool developers are far less than application developers. So learn how your IDE works and you might end up earning more money than your own job pays.


All of these, among others I can't really word without beer, are from my own experience. Since Level 1 Human Programmer in 'M$-Land' I've been curious about the tools I use, right from Visual Studio Add-in to Eclipse plug-ins, it has been wonderfully interesting journey so far. Given a chance to speak and I would totally be interested in how Eclipse is architected and how Gel used to support extensions and how painful it used to be to debug Add-ins in Visual Studio 6.0. Boy, it is interesting!

Monday, February 11, 2008

Climbing the Python hill

Finally I have started working on new year's resolution. As a part of it, I'm learning a dynamic language called Python.

There are several reasons why I'm a new Python convert. One of them is not because blogosphere keeps intimidating Java programmers that they are writing crap. And I've honest sympathy for those who hold the assumption that Java is dead and other strangling naive opinions like that.

I am rather going ahead with some mature opinion like programming in a language with different philosophy gives you another way of solving the same problem, And sometimes the other way is better or at least, it will bring out interesting techniques which can be useful in general. Since I have very limited experience writing sizable software using them, I am expecting a lot from dynamically typed languages, Python in particular.

Python has been particularly interesting to me because I am curious about it since academics. I've played with it in past but that was just a stab that didn't bleed my nerve. I have no hard feelings for Ruby (or "hoopla oriented" Rails), because I'm not a huge fan of Web applications - web applications are boring.

Python is actually fun to program, programming in Python is like kidding, no it's not as frightening as it's name implies. For example, Methods in Java you know? they can't be moved around with out puzzlers and pain. But in Python, methods are also treated as types, called function types, which you move around like variables - no wait believe me it's as simple as passing around variables. Look at the closure example below and tell me how difficult it is to understand?
x = lambda: a,b: a**b

x(10,12)

Like you do in a regular mathematical equation, assign an expression to a variable or symbol and bind that symbol with value as shorthand like this.
a = x(10,2) * x(6, 8) / x(10, 2)
Also, any method which is not using 'lambda; keyword is also treated in same way, no partiality. Other obvious thing to like about Python is - it forces correct indentation in source code, that makes Python program much more readable in a consistent style. No need for one thousand formatters and coding standards.

I'm not comparing Java with Python, that's not my Job. I'm just trying to realize that how apt it is to solve the same problem aptly in a different way.

Python community, like Python itself, looks great. It isn't impossible to realize that - hangout on Python google group sometime and you will know. I am glad that they are very accepting and responsive to the n00bs like me.

I have started with SQLAlchemy ORM and db api in general to learn python because I'm curious on how they play with tuples and all. Later on I'll write a bit of parser as I've heard Python has some neat and funky stuff for parsing.

And oh, I'm having little trouble getting out of Java shoes lately - hmm, there is nothing like private fields or methods. But I guess that's better than writing getter and setter for that private variable which does nothing but to add overhead for dynamic compiler of hotspot VM to inline it after 3000 iterations, gosh!! But hey, Python is missing the package convention or let me say it prefers configuration over convention here, __init__.py is not as intuitive, is it?

Friday, December 14, 2007

Of length of experience and developer's worth

I'm of the opinion that there's no incredibly sensible reasoning which confirms that a higher number of years of experience (always) makes one developer more competent (for most jobs) than other. Before someone starts on me, I perfectly understand the value of having experience and its importance in general, but I'm not biased towards the quantitative usage of it (numbers that people like to attach with themselves). But what I don't understand is why experience becomes the only factor in rating a developer in every compensation decision?

One of the reason of this frustration is the way 'experience' is handled by Human Resources department of a average company. I, for one, extremely hate to negotiate my pay rates with pitifully non-technical HR executives, especially when a non-technical person in front says, your rate is way higher than your number of years of experience. See? they don't care about the proficiency (or productivity) required for job but the number of years of experience, they take casual interviews; get reverse-interviewed and start negotiations relating to length of experience (because they don't know how to negotiate other way). How am I supposed to make that person understand what I can do and what level of productivity I can offer? there's no measurement in competency but a person more experienced would easily win, all because length of experience has become and is increasingly becoming de-facto bargain.

Why many people don't understand that the field of Software development is way too different than most of the fields out there (like manufacturing)? Why they tend to apply their (illogical) rules of thumb to software development realm when they don't even understand software development?

In my career, I've seen many experienced people, people with considerable experience and but not many can even prove their expertise. I also know many many bright people who keep inspiring me, they also have vast experience but I consider they have valuable experience because many have learned from their and other's experiences. I've interviewed many fresh as well as less experienced guys whom I found far better and who can, any day, out-perform those so called experienced professionals. I have always favored the competent than simply experienced, because I know experience isn't the only thing that matters in my field.

It is miserably disappointing how our industry is lead by such nonsense measures of identifying developer's worth. Experience isn't the only thing that makes a developer productive, People!!

Tuesday, November 13, 2007

Hibernate won't delete child objects from database

Given a commonly known parent/child relationship in a domain model, the hibernate code below would not delete child object from database.
Parent p = (Parent)session.load(Parent.class, id);
Child c = p.getChildren(0);
p.getChildren().remove(c);
c.setParent(null);
Unless you have specified 'all-delete-orphan' as the cascade value in the relation as shown below, or use 'Session' object to delete the object from db.
<set name="children" inverse="true" cascade="all,delete-orphan">
<key column="parent_id">
<one-to-many class="Child">
</set>
This detail is from hibernate manual (Section 21.3), and I have read it many times in last three years, but somehow I didn't find it intuitive thing to do and hence drawing a blank.

It's a breeze to have 'Session' object available everywhere in the code, but imagine a pile of layers hiding everything related to persistence, all you can do is play around with associative object references in the object graph.

There are many such minute intricacies in Hibernate which give surprises (and pain if that code is not covered by test cases), Endless debugging with hibernate is just as painful as dear old CMP (Container managed persistence in Entity Beans). Ironically though, Hibernate can win the "paingiving" if you use it with cglib whereby, while debugging, you see weird things in lazily loaded proxy (or object zombie if you like to call it so) where you wanted to see only a string value.

And oh I hate that AbstractEntityPersister.java with it's 4000 lines of code...

Monday, October 22, 2007

On IClass (anti-)pattern

I'd been re-reading this post by Sidu and the comments on it. I had to do exactly similar to IClass anti-pattern for one of the development effort. And I think having IWhatever completely makes sense for the current state of affairs in my development environment.

While it's unfortunate, most of the time, to have an Interface for just about every class in the code-base, It does have certain uses in some situations (apart from the (IoC) frameworks which mandate you to have them) like:
  • Support parallel development.
I will define parallel development as a situation where there are many components involved in developing a software and your component (or module or whatever..) and it's arbitrary version has to support other components (and their integration tests depending on your environment). For example, for something as important as (so called) service layer in an Enterprise application you need the Interface with single implementation at one time, it might just be a 'placeholder implementation' for a dependent component while the new version being developed parallely. It just makes sure that there is something to hold the place which can be tested easily. This is one more learning from distributed development, you're not alone developing it man!
  • When using Generative development methods
If you use code generators heavily, say, most of your code-base is generated out of models (UML, BPMN, BlahL ...) then depending on the generation pattern you'll find interface for just about every implementation (or other way around for EMF generator - one implementation for each interface). This is necessary as you might want to customize forward engineering by overriding parts of generated artifacts.

Most of the Eclipse code does have this pattern, for every class there's IClass. For Eclipse, In my opinion, it is justifiable (to some extent) to have them considering it is a development platform rather than just an application. However, I would be more than interested to know conceivable reasons to have those IInterfaces which I might be missing.