Thursday, January 03, 2013

Doing this MVC thing! Part 1

Let's get back to our web application shall we?

First let's remove everything in our project and start fresh. Here is what I have for the Contact Keeper project.

My current layout for the project.

So basically all that we are keeping is the "com.blogger.contacts.beans" package and the JSTL libraries.  Now let's begin where any sensible project would begin.  On the information that we are trying to store.  In other words, I like to look at the problem as "what to store, before presentation."  Some developers like to work on presentation first and then data.  I always get confused when I work this way, hence the reason I like to focus on data first.  However, to each their own.

Now our "database" isn't going to be a real database, we are just going to use a memory structure to store the information.  If our server gets turned off, then we loose all of our information.  That's okay, because we are going to make the interface to our database generic so that if we decide to ditch the memory storage and replace it with a real DB like PostgreSQL later on, then it will require very little code change.

So the first thing we need to do is create the actual object that we plan to store.  That means we need to model our contact in Java code.  If we were using a real database then we'd add another layer on top of our contact model to implement JPA.  JPA is just a fancy system that you use to translate Java objects into SQL code automatically (I am really simplifying the heck out of JPA here, but the premise holds.)

So we are just going to have a basic naked model here.  Our contacts should have the following:
  • First name - string
  • Last name - string
  • Phone number - string (we are not going to deal with validation here, at least not now)
  • Age - integer (real contact keepers would ask for Birthdate and calculate age from that, be we aren't doing that here, at least not now)
That's it.  Pretty simple.  I want to keep it pretty simple for the time being.

So let's create your Java code for this model.  We are going to store this Java class in a new package called, "com.blogger.contacts.entity"  Entity is the technical term for an object that models to something one would store in a database (or relates to something in the real world if you want a much fuller idea of the term), honestly if you really want a better technical definition, feel free to hit up Wikipedia.  At any rate, we are going to create anything that maps to the real problem in the entity package.

So here is the code:


package com.blogger.contacts.entity;

import java.io.Serializable;

public class Contact implements Serializable {

 /**
  * Serial version of our contact class, so that version stay compatible. 
  */
 private static final long serialVersionUID = 1L;
 
 private String firstName;
 private String lastName;
 private String phoneNumber;
 private Integer age;
 
 public Contact() {
  this.firstName = null;
  this.lastName = null;
  this.phoneNumber = null;
  this.age = null;
 }
 
 public Contact(String firstName, String lastName, String phoneNumber,
   Integer age) {
  super();
  this.firstName = firstName;
  this.lastName = lastName;
  this.phoneNumber = phoneNumber;
  this.age = age;
 }

 public String getFirstName() {
  return firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 public String getPhoneNumber() {
  return phoneNumber;
 }

 public void setPhoneNumber(String phoneNumber) {
  this.phoneNumber = phoneNumber;
 }

 public Integer getAge() {
  return age;
 }

 public void setAge(Integer age) {
  this.age = age;
 }

 @Override
 public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result + ((age == null) ? 0 : age.hashCode());
  result = prime * result
    + ((firstName == null) ? 0 : firstName.hashCode());
  result = prime * result
    + ((lastName == null) ? 0 : lastName.hashCode());
  result = prime * result
    + ((phoneNumber == null) ? 0 : phoneNumber.hashCode());
  return result;
 }

 @Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (getClass() != obj.getClass())
   return false;
  Contact other = (Contact) obj;
  if (age == null) {
   if (other.age != null)
    return false;
  } else if (!age.equals(other.age))
   return false;
  if (firstName == null) {
   if (other.firstName != null)
    return false;
  } else if (!firstName.equals(other.firstName))
   return false;
  if (lastName == null) {
   if (other.lastName != null)
    return false;
  } else if (!lastName.equals(other.lastName))
   return false;
  if (phoneNumber == null) {
   if (other.phoneNumber != null)
    return false;
  } else if (!phoneNumber.equals(other.phoneNumber))
   return false;
  return true;
 }

 @Override
 public String toString() {
  return "Contact [firstName=" + firstName + ", lastName=" + lastName
    + ", phoneNumber=" + phoneNumber + ", age=" + age + "]";
 }

}


So you may be asking yourself, why isn't this a bean?  Well it is, to an extent, back in the day you'd be absolutely correct about this being a bean, as this used to be called an Entity Bean.  However, as Java EE matured it became clear that Entities were stuff that mapped to real world things, and Beans were used to access stuff.  So in a basic case like ours here, our Entity could very well function as the bean as well, since the logic needed to access our entity is pretty simple stuff.  However, in more complex cases we might want Access beans that handle the needed logic to access our entities.

For now what we are going to do is let our entity stand by itself and we will create a DAO (Data Access Object) bean that will provide the basic CRUD (Create, Read, Update, and Delete) that we need to have a functioning application.

So there is our entity.  I've provided a hash code function, an equals function, and a to string function.  I usually do this for my benefit rather than any application need.  Your taste to do so may vary.

There you go, we've created the entity.  Now we need to create somewhere to actually store these things!  This needs to be a memory based storage, remember what I said earlier, and it needs to be simple and not overly complex.  What I am going to do, and this isn't something you'd normally do on production code, is just create a regular old collection and set it to the application scope, so that any sessions can access it.  Now you don't do this in normal production code because it is not thread safe at all.  People could come in and create the same contact at the same time and there would be nothing to stop them, or they could delete a contact that was deleted by someone else while the first person was deleting it.  In other words, it could lead to all kinds of badness.

We are going to use a basic Array List collection because it is fast on insert (adding contacts), fast on update (changing information or updating a contact), normal speed on listing (viewing all contacts), and slow on delete and random access (getting rid of contacts and finding a contact).  The only down side is the last part, random access, a contact list's number one feature is "finding" contacts.  We could use a hash map, but then our program would a bit more memory hungry but finding contacts would be very fast, and since we are not actually going to be using this code in any production system, I doubt that our contact list will ever grow to the size where a hash map makes more sense than an array list.  (I would need at least the assumption that the contact list would be at least 100 contacts or more before I would consider the hash map a good fit.)

break time...

Just noticed it is getting late, better call it a night for the time being.  We will implement our Array List next and we are going to create an interface DAO and DAO for that implementation that implements our interface.  So in case you missed that, part two will do the following.


  • Implement our Array List to store our Contact entities.
  • Create an interface for our DAO so that we keep a standard interface regardless of if we are using memory or actually DB back ends.
  • Create a concrete object for our DAO interface that has all the logic to connect our interface and Array List implementation.
Post a Comment