Tuesday, September 30, 2008
Getting teams started quickly on projects
1) Use Buildix(http://buildix.thoughtworks.com/) for setting up the infrastructure for the project like version control, continuous integration, agile project management and wiki and bug tracker. Buildix is open sourced under the apache license and automates setting up the basic infrastructure required fro the project.
2) Use Panopticode(http://www.panopticode.org/) to setup tools for gathering code metrics. Panopticode provides customized build scripts to integrate tools like Emma, CheckStyle, JDepend,JavaNCSS, Simian etc.
3) Use a VMWare mirror image to setup a developer box so as to remove any discrepancies across developer environments.
Sunday, September 28, 2008
Windows Shortcuts and useful tools for developers
Firefox Shortcuts
CTRL + number -- can be used to navigate between tabs in firefox. For example CTRL+1 gives the first tab,CTRL+2 gives the second tab etc.
Explorer Shortcuts
Alt+D -- leads to the address bar. The address bar as auto-completion like the tab in shells.
Command Prompt
F7 key--shows the command history
F8 key can be used to navigate across the history. Type the first few characters of the command and use the F8 key for auto-completion
Use pushd and popd. When inside a directory, pushd can be used to navigate to another directory and popd can be used to get back to the other directory. These commands work like a stack(LIFO), so prefer these over the simple cd.
Tools
CLCL -- a multi-clipboard utility
Command Prompt Explorer bar -- A sticky exlplorer-command prompt utility
PowerToys
Tweak UI
TaskSwitch
Virtual Desktop Manager
Thursday, August 28, 2008
Software Architecture Structures
1) Modules
2) Component and Connectors
3) Allocations
1) Modules -- These are the units of implementation. These represent code based views of the system. The intent here is not related to any runtime considerations. Module based structures can be further sub-divided into
1. Decomposition --The units addressed here are that of submodules of a particular module. The intent is to break modules into smaller units such that each unit can be understood. This normally is the starting point of high level design and subsequent low level design. It also incorporates things like implementations, test plans etc. In addition a decomposition can also address questions related to changes made to the system. The intent should be to keep the changes local to a few sub-modules.
2. Uses -- One unit uses another if the correctness of one depends on the existence of the correct version of another. The uses structure can be used to extend the capabilities of a system as well as extract subsets of functionality which can be used for incremental development
3. Layered -- When the Uses structure is carefully modeled, normally layers emerge. These layers are areas of common functionality. Layered structures can be used to assess the dependence of one layer on the other as well as ensuring that the interactions of one layers are only with the layers above or below this layer. In addition, a layer at n should only depend for services on the n-1 layer and none other.
4. Class or Generalization -- The units in this structure are classes. Classes can be used to reason about collection of similar behavior or capabilities. Class structures is used for assessing reuse and incremental addition of functionality.
2) Components and Connectors --Component-and-connector structures help answer questions such as What are the major executing components and how do they interact? What are the major shared data stores? Which parts of the system are replicated? How does data flow through the system? What parts of the system can run in parallel? How can the system's structure change as it executes? These can be further sub-divided into
1. Processes --The process structure shows processes connected to each other through connectors, snychronizers,exclusions etc. This structure is important when looking at a systems performance and availibility.
2. Concurrency -- This structure allows for determining the areas where there can be a resource contention or where parallelism can be employed.
3. Shared data -- This comprises connectors and components that create,store or access shared persistent data. It shows how data is produced and consumed by the runtime components and can be used to ensure performance and data integrity.
4. Client -Server -- This structure shows the components as client server units and the connectors are the underlying protocols which are used for communication.
3) Allocation Structures -- This structure shows the relation between the software elements and the environment in which the software executes. These can be classified as follows
1. Deployment -- The deployment structure shows how software is assigned to hardware-processing and communication elements. The elements are software, hardware entities and communication pathways. Relations are allocated-to, showing on which physical units the software elements reside. This view allows one to reason about performance, data integrity, availability, and security.
2. Implementation --This structure shows how usually modules are mapped to the file structure in the system's development, integration, or configuration environments. This is critical for the management of development activities and build processes
Wednesday, July 23, 2008
Kickstarting your day and honing your development skills
At the start of the day, i take up a puzzle and spend 5-10 minutes in analyzing and solving it. Be aware the intent is not to come to a solution, but just to get the gray cells kicking. After this i normally try some programming problem, albeit a simple one using a new language which i am trying to acquire. I spend another 20-30 minutes in solving the problem. The problem could be as simple as trying to find a repeated integer in a list of otherwise unique sequential numbers. Getting these two activities at the start of the day has two-fold advantages. One it focuses the brain and secondly it helps me acquire a new skill. I have even tried using this after prolonged meetings just to get back into the zone. However a word of caution, the intent is not to get to perfection, but to time-box the effort. You can get back to the problems again the next day if you are stuck on something.
Sunday, June 22, 2008
Regular Expressions Part 2
- Optional Items -- Suppose we wanted to search for the word June, which could be represented as either June or Jun. The ? meta-character means optional. So the search could be accomplished using June?. This can be interpreted as match J, then u then n followed by e if its there. So the ? is placed after the character that is allowed to appear at that point in the regular expression, but the existence isn't required to consider it a successful match. Expanding on the same lets say we have to match June 5th, which can occur as Jun 5, June 5th, or fifth. To match the following we can use (June|Jun).(5|5th|fifth). The first expression can be simplified as (June?) and the second one as fifth|5(th)?. Hence the complete expression can be re-written as June?.(fifth|5(th)?). One point here is that although there are different alternatives, choosing the right one needs some thought and introspection.
- Repetition -- The + and * meta-characters are used for checking for repetition. + implies one or more of the preceding character and * implies any number including none of the item. Thus + fails if there are none of the characters but succeeds for one or many, * on the other hand always succeeds. As an example, to match spaces, one can use . ? which would match a single optional space, . + would match any number of spaces with at least one space and . * would match any number of spaces, if present. Lets take another example, where we have to search for the html tag <hr size="10">. To build the regular expression, we need to have<, then HR followed by one or more spaces(allowed as per the semantics of html), followed by zero or more spaces, followed by = followed by zero or more spaces the number 10 , again zero or more spaces followed by >. Based on our discussion so far, this should be simple,
Now lets try and generalise this to any size, not just 10, so the regular expression would look like For case insensitive search using egrep, we can use the -i option.
is a legal match.
- Back References -- Many tools provide the ability for parentheses to remember text matched by the sub-expression they invoke. So as an example, ([a-z])([0-9])\1\2, \1 refers to the text matched by [a-z] and \2 refers text matched by [0-9]. We will see examples of using back-referencing in following posts.
- Escapting Meta-characters -- In order to escape meta-characters, we can use \ to escape the meta-character. For example if we tried to match att.com, it could end up matching something like watt company. So we need to escape the meta-character . , this can be done using att\.com. This escapes the meta-character and treats the meta-character . like a normal character
Friday, June 20, 2008
Regular Expressions Part 1
A regular expression is composed of a set of meta-characters like *, ^ etc and a set of literal characters like A-Z, a-z, 0-9 etc.
Some Simple Meta-characters
Let us start with a some simple meta-characters and how we can apply these to various scenario's. The
- ^ - The Caret/Anchor is one of the simplest meta-characters and represents the start of the line which is being checked. For example ^cat would match all lines which start with the literal cat like catalog
- $ - The dollar meta-character represents the end of the line which is being checked. So cat$ would match all lines which end with the literal characters cat, for example scat.
Exercise -- What would ^cat$, ^$ and ^ match ?
- Character Class -- The meta-character [...] called the character class lets you list the characters you want to allow at that point of match. For example e matches just e , a matches just a, however [ea] would match both e or a. Thus the implied meaning is that of OR. Suppose you wanted to check whether you have spelt grey or gray. The following regular expression would match the occurance of both gr[ea]y. This matches g follows by r followed by either e or a followed by y. The - operator within a character class matches a range, so [0-9A-Z] matches occurances of numbers and capital letters. For example
] would help you while searching headers in html documents. The - is special inside a character class, otherwise it is used as a normal character and not as a range. - Negated Character classes -- A ^ inside a character class negates the matches. For example [^a-z] would match any character which is not a through z. Remember a negated character class means match a character thats not listed and not don't match whats listed
- Matching Any character with dot -- this is simpler to explain with an example. Suppose you want to find a date 26/02/1977, which can also be represented as 26-02-1977 or even 26.02.1977. Not the . character can be used to match any character. So seemingly, 26.02.1977 should return us the date however it be represented, maybe with a - or a /. However, the above would also match a random number like 12264023197734. This is because the dot character matches any character. The correct way to do so would be to use something like 26[-./]02[-./]1977 (Note, the - is this case would not be a meta-character, since it immediately follows the [, if the same was written as [.-/], then it would become the range meta-character, also the . is not treated as a meta-character since it is inside the character class)
- Matching any one of several sub-expressions -- The | (OR) operator lets you combine expressions into a single expression, that matches any of the individual ones. For example, based on the previous examples, we can rewrite gr[ea]y as gr(e|a)y. (Note-- we cannot use something like gr[e|a]y as inside the character class, | is treated as a normal character). We need the parenthesis because gre|ay would mean gre or ay.
2) What is the difference between ^:List|Of|Books: from ^(List|Of|Books): ?
Note -- Tools like egrep provide switches for case-insensitive searches. For egrep -i performs a case insensitive search.
Example -- egrep -i '^(Subject|Predicate):' myfile.txt
This serves as a good groundwork for someone wanting to start using regular expressions. I will be following up the post with detailed topics. Till then, cheers and keep the faith.
Thursday, June 19, 2008
The Art of analysis and problem solving
Problem Statement
Write a function which removes a set of characters from a given String. The signature of the function should be as follows
public String removeCharsFromString(String source, String remove)
Problem Analysis
The problem involves the following 2 steps
1) For each character in source, determine whether it needs to be deleted
2) Delete the character
Lets start with the actual deletion process first. You have to remove an element from an array. An array is a contiguous block of memory, so you cant remove an element from the middle as can be done with a linked list. So you have to rearrange the elements to maintain it as a contiguous block. For example if you need to remove c from an array containing abcd , you have to rearrange the elements. So you can either shift ab up or shift d down. In addition you need to decrease the size of the string by one.
Now how would the proposed algorithm work if you had to delete all elements from the source string. If the String is n characters long, this would mean shifting the last element by n-1, the second last by n-2 and so on, giving the worst time ass O(n^2).
How can we avoid this. What if you allocated a temporary string buffer and built your modified string there instead of in place? Then you could simply copy the characters you need to keep into the temporary string, skipping the characters you want to delete. When you finish building the modified string, you can copy it from the temporary buffer back into str. This way, you move each character at most twice, giving O(n) deletion. However, you’ve incurred the memory overhead of a temporary buffer the same size as the original string, and the time overhead of copying the modified string back over the original string. Is there any way you could avoid these penalties while retaining your O(n) algorithm?
To implement the O(n) algorithm just described, you need to track a source position for the read location in the original string and a destination position for the write position in the temporary buffer. These positions both start at zero. The source position is incremented every time you read, and the destination position is incremented every time you write. In other words, when you copy a character you increment both positions, but when you delete a character you increment only the source position. This means the source position will always be the same as or ahead of the destination position. Once you read a character from the original string (that is, the source position has advanced past it), you no longer need that character - in fact, you’re just going to copy the modified string over it. Because the destination position in the original string is always a character you don’t need anymore, you can write directly into the original string, eliminating the temporary buffer entirely. This is still an O(n) algorithm, but without the memory and time overhead of the earlier version.
Now to the actual part of deciding whether a character needs to be deleted. The easiest way is to compare all characters in the remove string with all the characters in the source string. If the size of the source string is n and the size of the remove string is m, this entails a running time of O(nm). How can we reduce this to a running time of O(m).If we construct an array or a hashtable which has a constant time lookup, we can reduce the running time to O(m).
Lets construct an array containing all Booleans which is indexed by all the possible values of the characters in the source string. This enables you to determine whether a character is in remove by checking a single element.
Now the function will have 3 parts
- Set all elements in the lookup array to false
- Iterate through each element in remove, setting the corresponding value in the lookup array to true
- Iterate through str with a source and destination index, copying each character only if its corresponding value in the lookup array is false
Now lets take a look at the code
public String removeCharOccurances(String source,String remove){
char[] sourceArr = source.toCharArray();
char[] removeArr = remove.toCharArray();
boolean[] flags = new boolean[128]; // assumes ASCII!
int len = sourceArr.length;
int len1=removeArr.length;
int src, dst;
// Set flags for characters to be removed
for( src = 0; src < len1; ++src ){
flags[removeArr[src]] = true;
}
src = 0;
dst = 0;
// Now loop through all the characters,
// copying only if they aren't flagged
while( src < len ){
if( !flags[ (int)sourceArr[src] ] ){
sourceArr[dst++] = sourceArr[src];
}
++src;
}
return new String( sourceArr, 0, dst );
}
Wednesday, June 18, 2008
REST-ful services using JAX-WS 2.0
- RESTful services are stateless. Each request from a client to a server must contain all the information necessary to understand the request and must not depend on any stored contextual information on the server.
- REST-ful services have a uniform interface. For example for a RESTful HTTP service, the operation supported are GET, POST, PUT and DELETE.
- REST based architectures are built from resources which are identified by unique URI's.
- REST components manipulate resources by exchanging representations of the resources.
The fundamental differences between REST and RPC based services can be outlined as
- RPC services work by invoking a procedure on a server rather than by exchanging representations of a resource.
- In the RPC approach typically many operations are invoked at the same URI, which is fundamentally different from the REST way where every resource has a unique URI.
XML | XML inside a SOAP envelope |
none | WSDL |
HTTP | HTTP,FTP,MIME,JMS,SMTP etc |
In order to consume a RESFful service using JAX-WS 2.0, the majority of the work needs to be done using the javax.xml.ws.Dispatch
The following code displays the basics and is discussed below
QName svcQName = new QName("http://xyz", "svc");
QName portQName = new QName("http://xyz", "port");
Service svc = Service.create(svcQName);
svc.addPort(portQName, HTTPBinding.HTTP_BINDING, args[0]);
Dispatch
- The client uses the Service.addPort() method to create a port within the Service instance that can be used to access the RESTful Web service.
- Next, the Service.createDispatch() method is invoked to create an instance of Dispatch
- The Dispatch.invoke() method then packages the XML request—per the JAX-WS 2.0 HTTP Binding—and sends it to the RESTful service. The invoke() method waits for the response before returning.
- The service processes the HTTP GET and sends an HTTP response that includes the XML.
- The invoke() method returns the response XML message as an instance of Source.
Thursday, June 12, 2008
Pair Programming
Kick-start the day by writing a unit test, just to get the grey cells working
Getting down to serious stuff.
This isnt making a lot of sense, is it.
Getting some tips from the senior partner
Tuesday, June 3, 2008
Light weight java game library
Friday, May 30, 2008
new java puzzlers (As presented in Javapolis --2007)
1) Set of Shorts (hehehe)
public class ShortSet {
public static void main(String[] args) {
Set
for(short i=0;i<100;i++){
shortSet.add(i);
shortSet.remove(i-1);
}
System.out.println("Size of Set =" + shortSet.size()) ;
}
}
The choices are
1)1
2)100
3) Throws an exception
4) None of the above
2)Racy little number
public class Test extends TestCase {
int number;
public void test()throws InterruptedException{
number=0;
Thread t=new Thread(new Runnable(){
public void run(){
assertEquals(2, number);
}
});
number=1;
t.start();
number++;
t.join();
}
}
What is the outcome of this test
1) Passes Sometimes
2)Fails Sometimes
3)Always passes
4) Always hangs
Monday, May 26, 2008
How to derail your experts and ruin their performance
deep end of the development pool—far over their heads. Here we’re trying to race sheep. A misguided sense of political correctness tends to treat all developers the same way, irrespective of the fact that there is a 20:1 to 40:1 in the productivity of the developers.
Living out of the box
The Dreyfus model
Friday, May 23, 2008
The bane of java exceptional handling
Lets take a scenario of the following block of code where we are trying to open a file
InputStream input = null;
try{
input = new FileInputStream("myFile.txt");
//do something with the stream
} catch(IOException e){
throw new WrapperException(e);
} finally {
try{
input.close();
} catch(IOException e){
throw new WrapperException(e);
}
}
Now suppose that the file myFile.txt does not exist, so an FNFE(FileNotFoundException) would be
thrown from the try block. The catch blocked would catch the FNFE , wrap the exception and rethrow it.
Till now all seems well. When the call reaches the finally block, since input is null,
a call to input.close() would result in a NullPointerException(NPE) being thrown.
Now since the finally block never catches a NPE, it would propagate up the call stack.
The WrappedException(WE) from the catch block simply disappears.
The way to avoid this would be to check whether the resource in not null in the finally block.Right, makes
complete sense, but lets take another scenario. Lets say the file myFile.txt is found but there is an
IOException(IOE) thrown due to some other reason. What happens, the try block throws IOE, which is
wrapped and rethrown. Now before the exception propagates up the call stack, the finally block is executed,
if the call to input.close() fails, a new IOE would be thrown, but the original exception would still be lost.
Damn Cute, aint it.
Tuesday, May 20, 2008
Iterating over Map's
Map
Set
for(Integer key:keys){
String val=values.get(key);
}
A better way is
Map
Set
for(Map.Entry
String val=entry.getValue();
}
It is better to get a reference to Map.Entry and then iterate instead of getting all the keys and making the Map object do the work of fetching the value each time
N Queen Problem
The N Queen Problem is a generalized form of the 8 queen problem. In the 8 Queen problem, we have to place 8 queens on a chess board so that none of the queens is in check from any other queen(The queen should not be in the same row, column or diagonal). The N Queen problem would involve generalizing this to a n X n board with n queens.
Monday, May 19, 2008
Identifying Patterns and creating Higher Order Functions
1) Sum of all integers between two integers a and b
def sumInts(a:Int,b:Int):Int ={
if (a>b)
0
else
a+sumInts(a+1,b)
}
2) Sum of square of all integers between two integers a and b
def square(x:Int) :Int=x*x
def sumSqaure(a:Int,b:Int):Int ={
If(a>b)
0
else
square(a) +sumSquare(a+1,b)
}
3) A function to square all the powers 2^n where n betweentwo integers a and b
def powerOfTwo(x:Int):Int={
if(x==0)
1
else
2*powerOfTwo(x-1)
}
def sumPowerOfTwo(a:Int,b:Int):Int ={
if(a>b)
0
else
powerOfTwo(a) + sumPowerOfTwo(a+1,b)
}
These functions are all instances of {Summation from a to b} for different values of f . We can factor out the common pattern by defining a function sum
def sum(f: Int => Int, a: Int, b: Int): Int ={
if (a > b)
0
else
f(a) + sum(f, a + 1, b)
}
Using sum, we can formulate the three summing functions as follows.
def sumInts(a: Int, b: Int): Int ={
sum(id, a, b)
}
def sumSquares(a: Int, b: Int): Int ={
sum(square, a, b)
}
def sumPowerOfTwo(a: Int, b: Int): Int = {
sum(powerOfTwo, a, b)
}
where
def id(x: Int): Int = x
def square(x: Int): Int = x * x
def powerOfTwo(x: Int): Int = {
if (x == 0)
1
else
2 * powerOfTwo(x-1)
}
Tail Recursion
def gcd(a:Int,b:Int):Int ={
if(b==0)
b
else
gcd(b,a%b)
def factorial(n:Int):Int={
if(n==0)
1
else
n *factorial(n-1)
There is an important difference between the two rewrite sequences: The terms in the rewrite sequence of gcd have the same form repeatedly. As evaluation proceeds, their size is bounded by a constant.
By contrast, in the evaluation of factorial we get longer and longer chains of operands which are then multiplied in the last part of the evaluation sequence.
In the implementation of gcd, one notes that the recursive call to gcd is the last action performed in the evaluation of its body. One also says that gcd is tail-recursive.
The final call in a tail-recursive function can be implemented by a jump back to the
beginning of that function. The arguments of that call can overwrite the parameters
of the current instantiation of gcd, so that no new stack space is needed. Hence,
tail recursive functions are iterative processes, which can be executed in constant
space.
By contrast, the recursive call in factorial is followed by a multiplication. Hence,
a new stack frame is allocated for the recursive instance of factorial, and is deallocated
after that instance has finished. The given formulation of the factorial function
is not tail-recursive; it needs space proportional to its input parameter for its
execution.
More generally, if the last action of a function is a call to another (possibly the same)
function, only a single stack frame is needed for both functions. Such calls are called
tail calls. In principle, tail calls can always re-use the stack frame of the calling
function.
Friday, May 2, 2008
Scala vs Java : Implementing quicksort -- not optimized
Below is an implementation of a quicksort the java way
void sort(int[] xs) {
sort(xs, 0, xs.length -1 );
}
void sort(int[] xs, int l, int r) {
int pivot = xs[(l+r)/2];
int a = l; int b = r;
while (a <= b)
while (xs[a] < pivot) { a = a + 1; }
while (xs[b] > pivot) { b = b – 1; }
if (a <= b) {
swap(xs, a, b);
a = a + 1;
b = b – 1;
}
}
if (l < b) sort(xs, l, b);
if (b < r) sort(xs, a, r);
}
void swap(int[] arr, int i, int j) {
int t = arr[i]; arr[i] = arr[j]; arr[j] = t;
}
Quicksort the scala way ... looks neater and is easier to understand
object QuickSort {
def sort(xs:Array[Int]):Array[Int]={
if(xs.length<1)xs
else{
val pivot=xs(xs.length/2)
Array.concat(
sort(xs filter (pivot >)),
xs filter (pivot ==),
sort(xs filter (pivot <)))
}
}
}
Wednesday, April 30, 2008
Zero Turnaround time with javarebel
A normal deployment cycle looks like
1) Make changes to your classes
2) Create the new archive
3) Touch the archive in the deployment environment
4) Restart application server/Redeploy application
5) Check the modifications
With JavaRebel, you can reduce the above steps to
1) Make changes to your classes
2) Background compilation
3) Check for modifications
For standard environments using java 5 and above, we need to add the following to the jvm path
-noverify -javaagent:/path/to/javarebel.jar
For an app-server environment, for JBoss 4.x, we need to add the following in the $JBOSS_HOME/bin/run.sh(%JBOSS_HOME%/bin/run.bat on windows), add the following
JAVA_OPTS="-noverify -javaagent:javarebel.jar $JAVA_OPTS"
or on Windows
set JAVA_OPTS= -noverify -javaagent:javarebel.jar %JAVA_OPTS%
Happy Non-Deployment :-)
Monday, April 28, 2008
New features in EJB 3.1
1) Session bean business interfaces are going to be optional. The intent is to bring the Session beans as close to POJO's. Another advantage is that the it makes using EJB 3.1 beans easier to use in Web Beans (JSR 299).
2) Singleton Beans - These are the middleware equivalent of the GOF singleton pattern. These can be used to store shared application scope data. Although there are alternatives for caching shared data, the issue with these solutions is that they lack services like thread management, security, transaction management etc. Singleton beans being Enterprise beans have these services provided by the container. All singleton methods are assumed to be thread-safe and transactional(@Required). Thread safety can be changed using @ConcurrencyAttribute and transaction demarcation can be done the standard way transaction demarcation and transaction attributes. Concurrency management can also be managed at the bean level using @ConcurrenyManagement(BEAN) and synchronizing on methods you want to be thread-safe
3) Timer service - The main enhancements is the ability to trigger EJB methods using a cron like scheduling using the @Schedule. The bean method can be triggered based on seconds till the level of year.
4) EJB packaging -- As of now, EJB's need to go as a separate jar file. A typical ear contains a separate ejb-jar for an EJB and a war for the web app. However for simple applications, it would be possible to place the EJB's directly in the war's WEB-INF/classes to simplify the packaging process.
5) Asynchronous invocation of session beans- Although MDB's provide the capability of using asynchronous invocations, it is an overkill for using for simple applications. You are forced to use messages and JMS even for very simple scenarios. With EJB 3.1, session beans can be invoked asynchronously.
6) EJB Lite -- a subset of the EJB features based on the Java EE 6 profiles(ref --http://weblogs.java.net/blog/robc/archive/2008/02/profiles_in_the_1.html).
External References
1. JSR 316: Java EE 6, http://jcp.org/en/jsr/detail?id=316.
2. JSR 318: Enterprise JavaBeans 3.1, http://jcp.org/en/jsr/detail?id=318.
3. JSR 299: Web Beans, http://jcp.org/en/jsr/detail?id=299.
4. Spring Pitchfork Project, http://static.interface21.com/projects/pitchfork/files/m4/docs/reference/html_single/.
Saturday, April 26, 2008
Using the ternary operator
Lets assume we have the following hierarchy
Class A {
...
}
Class B extends A {
...
...
}
Class C extends A{
...
...
}
Now someMethod takes A as a parameter and needs to narrow it to a specific type B or C
public void someMethod(A a){
A a1=null;
if(a instanceof B) {
a1=new B();
}
else{
a1=new C();
}
.....
//other stuff here
}
A better approach for brevity sake would be use the ternary operator
A a1= a instanceof B ? new B() : new C() ;
This reduces 4 lines to 1 which is some improvement.
Thursday, April 24, 2008
Exception handling on a per thread basis
Note - prior to Tiger, we would have to create our own ThreadGroup, assign any Thread we create to this ThreadGroup and handle the uncaught exception in the ThreadGroup ( a lot of shit for nothing of substance)
Autoboxing and Unboxing
Integer i1 = 256;
Integer i2 = 256;
if (i1 == i2) System.out.println("Equal!");
else System.out.println("Not equal!");
The output in this case would be "Not equal!" as these are two separate Integer objects,
so "==" returns false.
However, the following
Integer i1 =100;
Integer i2 = 100;
if (i1 == i2) System.out.println("Equal!");
else System.out.println("Not equal!");
will return "Equal!", Remember that int values from -127 to 127 are in that
range of immutable wrapper types, so the VM actually uses the same
object instance (and therefore memory address) for both i1 and i2. As a
result, == returns a true result.
Perfecting OO classes/methods
1) Use only one indention per method, if there is a need to indent again create another method and call that method from the first one.
2) Don't use else. Use the if condition to test the condition and exit the method if the condition is false. So every method tests for just one thing
3) Wrap all primitives and Strings to prevent primitive obsession. If you need to use a primitive, create a class to define its role.
4) Use only one dot per line. This prevents you from reaching deeply into objects to get to methods and fields and prevents breaking encapsulation.
5) Don't abbreviate names. Hence you spend less time thinking about method names. Thus have methods for Order like ship() rather than Order.shipOrder() ;
6) Keep entities small. No more than 50 lines per class and no more than 10 classes per package. This helps to keep classes concise and focused.
7) Don't use classes more than 2 instance variables. Difficult but then a lot of instance variables might warrant extracting a class.
8) Use first-class collections. In other words, any class that contains a collection should contain no other member variables. The idea is an extension of primitive obsession. If you need a class that’s a subsumes the collection, then write it that way.
9) Don’t use setters, getters, or properties. This is a radical approach to enforcing encapsulation. It also requires implementation of dependency injection approaches and adherence to the maxim “tell, don’t ask.”
Blog Archive
-
▼
2008
(26)
-
►
May
(10)
- new java puzzlers (As presented in Javapolis --2007)
- How to derail your experts and ruin their performance
- Living out of the box
- The Dreyfus model
- The bane of java exceptional handling
- Iterating over Map's
- N Queen Problem
- Identifying Patterns and creating Higher Order Fun...
- Tail Recursion
- Scala vs Java : Implementing quicksort -- not opti...
-
►
May
(10)