Archive for July, 2007

Aaaahh…Agile.

Tuesday, July 31st, 2007

I don’t know if I’ve ever told you, but I am a big fan of unit testing. Especially with Nunit and a little util called TestDriven.Net

In my opinion if you’re using Object Orientated Programming, then unit testing is a must. Unit testing using an automated unit testing framework is one of the cornerstones of Extreme Programming(XP).
I recommend reading more about Extreme programming, it is a really neat way to develop applications without the need for gigantic specs and is a breath of fresh air from the Waterfall model. Now, I’m not saying the one is better than the other, but what I do not like about the Waterfall approach is the fact there is not a steady flow of feedback from the users, thus you might be working for months before you receive feedback from a user about a feature, only to hear that it was not exactly what they expected.

I’m currently using a mixture of XP and Feature Driven Development,where I agree a certain number of features with the client and we use the approach of first finishing one feature, ensuring it works and then only moving onto the next feature. This is particularly useful when you, like me currently, have to rewrite an old legacy system, where the users already have a clear picture of what features they require. Being on-site at the client is proving to be very valuable, this allows me to talk directly to all the users involved and get a clear understanding of their unique requirements.

Another fantastic advantage of being on-site is the immediate feedback you receive from users, enabling you to adapt and change the application on the go, rather than working on the project for a month and then changing it.

I know a lot of development companies cannot have a developer on-site at their clients for projects, but another alternative is to have the developer work more closely with the business analyst in gathering the requirement from the users. This will eliminate a lot of 2nd hand communication, where a lot of information is due to get lost, and will empower the developer to better understand the users’ needs and also put a human face to the application i.e. "I’m writing this application for John, that’ll really appreciate it if this app can enable him to invoice the client automatically"

Agile development is a "relatively" new approach software development, but something I highly recommend reading up on and giving it a go on a project. Try it once on a smaller project, and see how much less painful it’ll be.

The cost of bad design

Monday, July 30th, 2007

I’ve used Jasc Paint Shop Pro a few years ago and really liked it because of it’s ease of use, and recently wanted to buy the latest version for myself. Well, first thing I noticed was that Jasc does no longer exist apparently.Jasc has joined Corel. At first I was a bit affronted, oh no! Will I still be able to get Paint Shop Pro? Sooo, I wandered over to the Corel site.

Great! They still had Paint Shop Pro, the latest version is 11, and it is very nicely priced, so I decided to spend the $69.99, and get the latest version. Right, so after creating an account, filling in all my details, I finally added Paint Shop Pro PHOTO XI Full to my shopping cart.

What a deal! You get the Create Edition 2 collection,valued at $19.95 free!. I clicked the Secure Checkout button, and filled in my details like so:

I then excitedly clicked the save button, only to be presented with the save form…confused I checked if any details were wrong or missing and could find none. So, I clicked Save again.
Again, I was presented with exactly the same form…a bit frustrated but still wanting Paint Shop Pro XI enough to try and figure this checkout maze out. I unticked the "My shipping address is the same as my billing address."option and filled in my Shipping Address details, which by the way is exactly the same as my Billing Address.
With batted breath and enthusiasm I anxiously clicked the Save button again…..nothing man. The exact same form, exact same problem.

Now at this stage I kind of started to get just a tiny bit agitated with this checkout hell. But the problem solver in me jumped in just in time, and I figured, "OK, maybe this is a browser issue". I’ve been using Firefox, and maybe something on this page did not like Firefox, so I opened Internet Explorer.

With a final desperate attempt I signed into my account, added Paint Shop Pro PHOTO XI to my shopping cart, was still impressed with getting the Creative Editions 2 collection absolutely free, and clicked on the Secure Checkout button. I very thoroughly filled in my Billing and Shipping Address, taking care not to make any mistakes, crossed my fingers and clicked the Save button….

I was presented with the following form:

YES!!! The exact same form! Aaaaarggghhh!! After that I closed my browser and happily resorted to using MS Paint for all my graphical editing needs.

Ok, ok , so what’s my point? My point is, that Corel just lost $69.99 due to bad design. The customer was trapped in a order checkout maze, from which he could not escape and took the easiest way out…close his browser and cancelling the sale.
Now I know $69.99 might not be a lot, but still. Am I safe to assume that all customers wanting to buy anything from Corel’s online store experience the same frustration? How much is that costing them.

Anyways, that’s my two cents…now back to trying to get MS Paint to get something transparent.

VB.Net adventures in NHibernate

Thursday, July 19th, 2007

I’ve listened to the DotNetRocks! episode and watched the DnrTV episode with Oren Eini on NHibernate and I must say NHibernate is both pretty intimidating and mind blowing!


I thought what the heck, I’ll give it a go, best way to learn something new is getting your hands dirty. I was also very interested about how
CSLA.Net can fit into NHibernate(But that’s for another time, or my brain will explode)

First, what is NHibernate, well, according to sourceforge Nhibernate is, and I quote:

A .NET port of the excellent Java Hibernate (http://www.hibernate.org) relational persistence tool.


I recommend listening and watching the 2 shows I’ve mentioned previously, they do help shed some light on Nhibernate.


Go on, I’ll wait for you


Ok, so you’ve listened and watched the necessary shows, so let’s get started. First you need to download the following(both available from Sourceforge):


* NHibernate

* NHibernateContrib

Note: A neat trick I read about here, gives you IntelliSense and validation in the VS.NET XML editor when editing NHibernate mapping and configuration files. I’ve tried integrating the help with VS as described in the same article but could not get it to work with VS2005.

I’ve downloaded the APIDocumentation as well, for good measure. Ok…so let’s get a test scenario. I’ve got an existing database from my client Adventureworks(you can download the sample db from microsoft),which contains all their Customer and Sales data. They want a new interface to this data and they do not want to change the layout of their data. Allrighty.


First we’ll start a new Windows Application VB.net project, named NHibernate_AdventureWorks. Then we’ll add a class for our Customer table, the class will look like this:


Public Class Customer

#Region " Members "

Private _CustomerID As Integer = 0

Private _NameStyle As Boolean = False

Private _Title As String = ""

Private _FirstName As String = ""

Private _MiddleName As String = ""

Private _LastName As String = ""

Private _Suffix As String = ""

Private _CompanyName As String = ""

Private _SalesPerson As String = ""

Private _EmailAddress As String = ""

Private _Phone As String = ""

Private _PasswordHash As String = ""

Private _PasswordSalt As String = ""

Private _rowguid As Guid = Nothing

Private _ModifiedDate As Date = Date.Now

#End Region

#Region " Properties "

Public Overridable Property CustomerID() As Integer

Get

Return _CustomerID

End Get

Set(ByVal Value As Integer)

_CustomerID = Value

End Set

End Property


Public Overridable Property NameStyle() As Boolean

Get

Return _NameStyle

End Get

Set(ByVal Value As Boolean)

_NameStyle = Value

End Set

End Property


Public Overridable Property Title() As String

Get

Return _Title

End Get

Set(ByVal Value As String)

_Title = Value

End Set

End Property


Public Overridable Property FirstName() As String

Get

Return _FirstName

End Get

Set(ByVal Value As String)

_FirstName = Value

End Set

End Property


Public Overridable Property MiddleName() As String

Get

Return _MiddleName

End Get

Set(ByVal Value As String)

_MiddleName = Value

End Set

End Property


Public Overridable Property LastName() As String

Get

Return _LastName

End Get

Set(ByVal Value As String)

_LastName = Value

End Set

End Property


Public Overridable Property Suffix() As String

Get

Return _Suffix

End Get

Set(ByVal Value As String)

_Suffix = Value

End Set

End Property


Public Overridable Property CompanyName() As String

Get

Return _CompanyName

End Get

Set(ByVal Value As String)

_CompanyName = Value

End Set

End Property

Public Overridable Property SalesPerson() As String

Get

Return _SalesPerson

End Get

Set(ByVal Value As String)

_SalesPerson = Value

End Set

End Property

Public Overridable Property EmailAddress() As String

Get

Return _EmailAddress

End Get

Set(ByVal Value As String)

_EmailAddress = Value

End Set

End Property

Public Overridable Property Phone() As String

Get

Return _Phone

End Get

Set(ByVal Value As String)

_Phone = Value

End Set

End Property

Public Overridable Property PasswordHash() As String

Get

Return _PasswordHash

End Get

Set(ByVal Value As String)

_PasswordHash = Value

End Set

End Property

Public Overridable Property PasswordSalt() As String

Get

Return _PasswordSalt

End Get

Set(ByVal Value As String)

_PasswordSalt = Value

End Set

End Property

Public Overridable Property RowGuid() As Guid

Get

Return _rowguid

End Get

Set(ByVal Value As Guid)

_rowguid = Value

End Set

End Property

Public Overridable Property ModifiedDate() As Date

Get

Return _ModifiedDate

End Get

Set(ByVal Value As Date)

_ModifiedDate = Value

End Set

End Property

#End Region

End Class


You’ll notice I’ve declared all the properties as
Overridable, you’ll thank me later. I then add the following to my app.config file:

<configSections>

<section

name="nhibernate"

type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"

/>

</< span>configSections>

<nhibernate>

<add

key="hibernate.connection.provider"

value="NHibernate.Connection.DriverConnectionProvider"

/>

<add

key="hibernate.dialect"

value="NHibernate.Dialect.MsSql2000Dialect"

/>

<add

key="hibernate.connection.driver_class"

value="NHibernate.Driver.SqlClientDriver"

/>

<add

key="hibernate.connection.connection_string"

value="Server=(local);initial catalog=AdventureWorks;Integrated Security=SSPI"

/>

</< span>nhibernate>

With that done, we can set out creating a mapping file for each of our classes. Now you don’t have to create a mapping file for every class, you can combine them, but it’s much cleaner to just create a single mapping file for each class.

I’ve named my mapping file Customer.hbm.xml and it looks like this :

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">

<class name="NHibernate_AdventureWorks.Customer, NHibernate_AdventureWorks" table="SalesLT.Customer">

<id name="CustomerID" column="CustomerID" type="integer">

<generator class="identity" />

</< span>id>

<property name="NameStyle" column="NameStyle" type="boolean" />

<property name="Title" column="Title" type="string" length="8" />

<property name="FirstName" column="FirstName" type="string" length="50" />

<property name="MiddleName" column="MiddleName" type="string" length="50" />

<property name="LastName" column="LastName" type="string" length="50" />

<property name="Suffix" column="Suffix" type="string" length="10" />

<property name="CompanyName" column="CompanyName" type="string" length="128" />

<property name="SalesPerson" column="SalesPerson" type="string" length="256" />

<property name="EmailAddress" column="EmailAddress" type="string" length="50" />

<property name="Phone" column="Phone" type="string" length="25" />

<property name="PasswordHash" column="PasswordHash" type="string" length="128" />

<property name="PasswordSalt" column="PasswordSalt" type="string" length="10" />

<property name="RowGuid" column="rowguid" type="guid" />

<property name="ModifiedDate" column="ModifiedDate" type="datetime" />

</< span>class>

</< span>hibernate-mapping>

The name="NHibernate_AdventureWorks.Customer, NHibernate_AdventureWorks" bit is the fully
,

The <generator class="Identity" /> part tells NHibernate that the CustomerID column is an identity column.
As I was typing up the mapping file, one thought immediately sprang to mind: Code Generation!! MyGeneration does have templates for NHibernate, althought I did not check it out yet.

Ok…make sure to change the build action of the mapping file to Embedded Resource. Now before I go on, I had a lot of trouble getting the app.config stuff to work nicely so I deleted the app.config file and created a hibernate.cfg.xml file that looked like this:

?xml version=1.0 encoding=utf-8?>

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">

  • You are currently browsing the Mythical Man Moth blog archives for July, 2007.

  • Archives

  • Categories


  • Google Analytics integration offered by Wordpress Google Analytics Plugin