Friday, March 28, 2014

GoF Design Patterns - Quick Overview

GoF Creational Patterns
Abstract FactorySets of methods to make various objects.
BuilderMake and return one object various ways.
Factory MethodMethods to make and return components of one object various ways.
PrototypeMake new objects by cloning the objects which you set as prototypes.
SingletonA class distributes the only instance of itself.

GoF Structural Patterns
AdapterA class extends another class, takes in an object, and makes the taken object behave like the extended class.
BridgeAn abstraction and implementation are in different class hierarchies.
CompositeAssemble groups of objects with the same signature.
DecoratorOne class takes in another class, both of which extend the same abstract class, and adds functionality.
FacadeOne class has a method that performs a complex process calling several other classes.
FlyweightThe reusable and variable parts of a class are broken into two classes to save resources.
ProxyOne class controls the creation of and access to objects in another class.
GoF Behavorial Patterns
Chain Of ResponsibilityA method called in one class can move up a hierarchy to find an object that can properly execute the method.
CommandAn object encapsulates everything needed to execute a method in another object.
InterpreterDefine a macro language and syntax, parsing input into objects which perform the correct opertaions.
IteratorOne object can traverse the elements of another object.
MediatorAn object distributes communication between two or more objects.
MementoOne object stores another objects state.
ObserverAn object notifies other object(s) if it changes.
StateAn object appears to change its` class when the class it passes calls through to switches itself for a related class.
StrategyAn object controls which of a family of methods is called. Each method is in its` own class that extends a common base class.
TemplateAn abstract class defines various methods, and has one non-overridden method which calls the various methods.
VisitorOne or more related classes have the same method, which calls a method specific for themselves in another class.

Monday, March 24, 2014

Maven Overview

What is Maven? From the website, the answer to the question:
Maven is an attempt to apply patterns to a project's build infrastructure in order to promote comprehension and productivity by providing a clear path in the use of best practices. Maven is essentially a project management and comprehension tool and as such provides a way to help with managing:
  • Builds
  • Documentation
  • Reporting
  • Dependencies
  • SCMs
  • Releases
  • Distribution
Maven is not just a build tool, and not just a replacement for Ant. Maven is an entirely different creature from Ant. Ant is simply a toolbox whereas Maven is about the application of patterns in order to achieve an infrastructure which displays the characteristics of:
  • Coherence - Maven allows organizations to standardize on a set of best practices. Because Maven projects adhere to a standard model they are less opaque. The definition of this term from the American Heritage dictionary captures the meaning perfectly: "Marked by an orderly, logical, and aesthetically consistent relation of parts."
  • Reusability - Maven is built upon a foundation of reuse. When you adopt Maven you are effectively reusing the best practices of an entire industry.
  • Agility - Maven lowers the barrier to reuse not only of build logic but of components. When using Maven it is easier to create a component and integrate it into a multi-project build. It is easier for developers to jump between different projects without a steep learning curve that accompanies a custom, home-grown build system.
  • Maintainability - Organizations that adopt Maven can stop building the build, and start focusing on the application. Maven projects are more maintainable because they have fewer surprises and follow a common model.
To get an ant project up and running, you usually need to cut and paste a build script and get started laying out your environment. Maven allows you to skip this step and install a new project.
Quick Start
Once maven is installed and on the classpath, all one has to do, from project root execute:
mvn archetype:create -DgroupId=com.mycompany.app -DartifactId=my-app
This results in the directory structure:
my-app
|-- pom.xml
`-- src
    |-- main
    |   `-- java
    |       `-- com
    |           `-- mycompany
    |               `-- app
    |                   `-- App.java
    `-- test
        `-- java
            `-- com
                `-- mycompany
                    `-- app
                        `-- AppTest.java
The starting pom.xml file looks like:
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  <modelversion>4.0.0</modelversion>

  <groupid>com.mycompany.app</groupid>

  <artifactid>my-app</artifactid>

  <packaging>jar</packaging>

  <version>1.0-SNAPSHOT</version>

  <name>Maven Quick Start Archetype</name>

  <url>http://maven.apache.org</url>

  <dependencies>

    <dependency>

      <groupid>junit</groupid>

      <artifactid>junit</artifactid>

      <version>3.8.1</version>

      <scope>test</scope>

    </dependency>

  </dependencies>

</project>
The following are the most common "targets"
  • compile - compile the code
  • test - compile and run the test cases
  • test-compile - compile the test classes
  • package - build the jar
  • install - install the package into a repository

Repository
Maven supports the concept of repositories. These can be local or remote libraries of all the necessary jar files. Each project defines dependencies (see dependencies element in the pom.xml above).

In the default setting, the expected jar file will be located in ~user/.m2/repository. The behavior can be changed in settings.xml of the maven installation. 

A jar file can have its own pom file declared which will create nested dependency chains. So if your project requires soap, and soap requires the activation, and mail jars, these dependencies can be within the soap pom.

Local repo:
\~user/.m2/repository/[groupid]/[artifactid]/[version]/[artificatid]-[version]
In the case of the above example, the location of the jar file:
\~/.m2/repository/junit/junit/3.8.1/junit-3.8.1.jar

Remote repo:
What happens if the jars are not there. By default Maven will go out and attempt to download them. One of the most popular remote repositories is ibiblio.com, which is the apache jar library. Of course, you can specify other repositories. Furthermore, you can prevent maven from using a particular location.

Plugins
Plugins are very similar to dependencies. Its just a project action dependency.  Using plugins allows the user to customize the build for their project. In the following example, I demonstrate the jaxb plugin for generating source files from an xsd.


<plugins>

    <plugin>

        <groupId>com.sun.tools.xjc.maven2</groupId>

    <artifactId>maven-jaxb-plugin</artifactId>

    <executions>

        <!?Which phase the plugin should be executed in -->

        <execution>

            <goals>

            <goal>generate</goal>

        </goals>

        </execution>

    </executions>

    <configuration>

    <!?The package name -->

            <generatePackage>com.riskfocus.markit.generated</generatePackage>

            <!- - Which schema files to include -->

            <includeSchemas>

        <includeSchema>**/*.xsd</includeSchema>

            </includeSchemas>

            <includeBindings>

        <includeBinding>*.xjb</includeBinding>

        </includeBindings>

        <!?Where should the generated files be placed -->

        <generateDirectory>src/main/java</generateDirectory>

        </configuration>

    </plugin>

</plugins>


It takes a little bit of hunting the first time around to understand how to structure the plug in declaration. However, most times, someone out there has already done it.

Ant
A further benefit, there is an ant task supported. So if you cant do it the maven way, you can always plug in an ant task.
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <executions>
        <execution>
            <id>apt-task</id>
            <phase>generate-sources</phase>
            <configuration>
                <tasks verbose="true">
            <property name="gen.src.java" value="target/generated-sources/main/java"/>
            <mkdir dir="${gen.src.java}"/>
                <taskdef name="apt" classname="com.sun.tools.ws.ant.Apt">
                    <classpath refid="maven.compile.classpath"/>
                </taskdef>
                <apt fork="true" debug="false" verbose="false" destdir="target/classes" sourcedestdir="${gen.src.java}"
                                     nocompile="true" sourcepath="src/main/java">
                    <classpath>
                    <path refid="maven.compile.classpath"/>
                    <pathelement location="${java.home}/../lib/tools.jar"/>
                </classpath>
                <option key="r" value="target"/>
                <source dir="src/main/java">
                    <include name="**/websvcs/**/*.java"/>
                </source>
                </apt>
            </tasks>
            <sourceRoot>${gen.src.java}</sourceRoot>
            </configuration>
            <goals>
            <goal>run</goal>
     </goals>
     </execution>
</executions>

This task attempts to generate a wsdl file from an annotated java class.   
Should ant be an absolute requirement, I believe that you can generate an ant build.xml for your pom.
How does maven determine the classpath resources for your project. The first is the dependency tag, which indicates the jar or project dependency. Yes, you can declare multiple projects with their own hierarchies within your project pom.

Resources reside, by default, in src/main/resources. Any resource file added here will automatically be picked up. For test cases, the pattern is to add src/test/resources.

Maven supports project scaffolding, i.e. template generation, for different project types, so calledarchtype. The goal of this scaffolding is to allow a fast start into the Maven world and supports a "standardized" folder structure of software projects.
You can create a project by executing the generate goal on the archetype plugin : $mvn archetype:generate . This starts the generate process in the interactive mode and asks you for several settings. Artifact properties
Name
Description
groupId
defines a unique base name of the organization or group that created the project. This is normally a domain name. For the generation the groupId also defines the package of the main class.
artifactId
defines the unique name of the artifact. In our case it's the same like the groupId, but it could also be a simple name like "SuperCalculator". The generation uses this value as name of the root folder for out project.
packaging
defines the packaging method. This could be e.g. jar, war or ear. This setting has influence on the whole life cycle.
version
This defines the version of the artifacts generated from our project.
url
defines the project site.
The configuration of a Maven project is done via a Project Object Model, which is represented by thepom.xml file.
By default, this is the only configuration file required for the build process. Every build follows a specified life cycle. Maven comes with a default life cycle that includes the most common build phaseslike compiling, testing and packaging. All phases are made up of plugin goalsPlugin goals are tasks which are more specific than phases. So a phase can be defined to run more than one plugin goal.
The result of a build is called artifact. An artifact, for example, can be a executable or an archive of documents.
With this single line, the maven lifecycle will be started. So the configuration from the pom.xml will be loaded and the dependencies will be resolved. After this, Maven tries to load the lastest version of the depended artifacts from the central repository into a local repository, which is placed as.m2/repository in the users home directory. As part of the lifecycle, the build tool compiles the sources and tests, runs the tests and packs the compiled files in, e.g., JAR archives. As last step the resulting artifact will be saved in the local repository, so it can be used by other projects.
Maven creates the build result in the target folder. If you run the mvn install command, Maven compiles the source code, builds the result, e.g., the JAR file.
# default to run Maven
# compiles, build and install the build result
maven install 
By default, Maven checks online if the dependencies have been changed. If you want to use your local repository, you can use the -o to tell Maven to work offline.
# work offline , i.e. use the local maven repository
maven -o clean install 
C:\Java\maven >mvn archetype:generate -DgroupId=mavenexample -DartifactId=mavenexample -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
CD mavenexample
C:\Java\maven\mavenexample >mvn archetype:generate -DgroupId=mavenexample -DartifactId=mavenexample -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
C:\Java\maven\mavenexample>java -cp target/mavenexample-1.0-SNAPSHOT.jar mavenexample.App
To run specific phases:
$ mvn package
$ mvn test
$ mvn compile
$ mvn clean 

Binary Tree in Java



import java.util.ArrayDeque;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;

public class BinaryTree {
private TreeNode root;

/** Inner class tree node */
private class TreeNode {
Object element;
TreeNode left;
TreeNode right;

public TreeNode(Object o) {
element = o;
}

}

/** Create a default binary tree */
public BinaryTree() {
}

/** Create a binary tree from an array of objects */
public BinaryTree(Object[] objects) {
for (int i = 0; i < objects.length; i++) {
insert(objects[i]);
}
}

/** Search element o in this binary tree */
public boolean search(Object o) {
return search(o, root);
}

public boolean search(Object o, TreeNode root) {
if (root == null) {
return false;
}
if (root.element.equals(o)) {
return true;
} else {
return search(o, root.left) || search(o, root.right);
}
}

/** Return the number of nodes in this binary tree */
public int size() {
return size(root);
}

public int size(TreeNode root) {
if (root == null) {
return 0;
} else {
return 1 + size(root.left) + size(root.right);
}
}

/**
* Return the depth of this binary tree. Depth is the number of the nodes in
* the longest path of the tree
*/
public int depth() {
return depth(root);
}

public int depth(TreeNode root) {
if (root == null) {
return 0;
} else {
return 1 + Math.max(depth(root.left), depth(root.right));
}
}

/**
* Insert element o into the binary tree Return true if the element is
* inserted successfully
*/
public boolean insert(Object o) {
if (root == null) {
root = new TreeNode(o); // Create a new root
} else {
// Locate the parent node
TreeNode parent = null;
TreeNode current = root;
while (current != null) {
if (((Comparable) o).compareTo(current.element) < 0) {
parent = current;
current = current.left;
} else if (((Comparable) o).compareTo(current.element) > 0) {
parent = current;
current = current.right;
} else {
return false; // Duplicate node not inserted
}
}

// Create the new node and attach it to the parent node
if (((Comparable) o).compareTo(parent.element) < 0) {
parent.left = new TreeNode(o);
} else {
parent.right = new TreeNode(o);
}
}

return true; // Element inserted
}

public void breadth() {
breadthFirst(root);
}

// Implement this method to produce a breadth first
// search traversal
public void breadthFirst(TreeNode root) {
if (root == null)
return;
Queue queue = new LinkedList();
queue.clear();
queue.add(root);
while (!queue.isEmpty()) {
TreeNode node = queue.remove();

System.out.print(node.element + " ");
if (node.left != null)
queue.add(node.left);
if (node.right != null)
queue.add(node.right);
}
}

public void depthFirst() {
depthFirst(root);
}

/**
* Depth first traversal.
*/
public void depthFirst(TreeNode root) {
if (root == null)
return;
Deque stack = new ArrayDeque();
stack.clear();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode node = stack.pop();

System.out.print(node.element + " ");
if (node.left != null)
stack.push(node.left);
if (node.right != null)
stack.push(node.right);
}
}

/** Inorder traversal */
public void inorder() {
inorder(root);
}

/** Inorder traversal from a subtree */
private void inorder(TreeNode root) {
if (root == null) {
return;
}
inorder(root.left);
System.out.print(root.element + " ");
inorder(root.right);
}

/** Postorder traversal */
public void postorder() {
postorder(root);
}

/** Postorder traversal from a subtree */
private void postorder(TreeNode root) {
if (root == null) {
return;
}
postorder(root.left);
postorder(root.right);
System.out.print(root.element + " ");
}

/** Preorder traversal */
public void preorder() {
preorder(root);
}

/** Preorder traversal from a subtree */
private void preorder(TreeNode root) {
if (root == null) {
return;
}
System.out.print(root.element + " ");
preorder(root.left);
preorder(root.right);

}

}

Test code:

import org.junit.Test;

public class BinaryTreeTest {

@Test
public void test() {
BinaryTree tree = new BinaryTree(new Integer[] {10, 5, 15, 12, 4, 8 });

   System.out.print("\nInorder: ");
   tree.inorder();
   System.out.print("\nPreorder: ");
   tree.preorder();
   System.out.print("\nPostorder: ");
   tree.postorder();

   //call the breadth method to test it

   System.out.print("\nBreadthFirst:");
   tree.breadth();
   System.out.print("\nDepthFirst:");
   tree.depthFirst();
}

}

Book Review: Spring Start Here: Learn what you need and learn it well

  Spring Start Here: Learn what you need and learn it well by Laurentiu Spilca My rating: 5 of 5 stars This is an excellent book on gett...