Click here to Skip to main content

Jon Person - Professional Profile

32,769
Author
298
Authority
263
Debator
19
Organiser
1,158
Participant
0
Editor
0
Enquirer
31 Dec 2004: CodeProject MVP 2005
Hi there! From 2004 to 2009 I ran a company called "GeoFrameworks," publishing two components called GPS.NET and GIS.NET which helped developers quickly write location-based services. Now, I've released the source code for GPS.NET to CodePlex for you to use as you see fit.
 
GPS.NET 2.0 on CodePlex
GPS.NET 3.0 on CodePlex
 
... I've also released the source code of a library called the "GeoFramework," a collection of commonly used classes such as Latitude, Longitude, Distance, Speed, and Position:
 
GeoFramework 1.0 on CodePlex
GeoFramework 2.0 on CodePlex
 
I'm now taking a break from programming, but I really appreciate the positive feedback from readers!
Member since Sunday, August 29, 2004 (7 years, 9 months)

Below is the list of groups in which the member is participating


GeoFrameworks



Unknown

Administrator, Manager, Author, Member



Organisation
members

GeoFrameworks is a privately-held software design and development firm in Denver, Colorado, specializing in the creation of software components for Microsoft's .NET platform. Our products help developers vastly reduce their development time, save money, and quickly become experts with GPS and GIS technologies.

 

For more information on Reputation please see the FAQ.
 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   


Advertise | Privacy | Mobile
Web02 | 2.5.120528.1 | Last Updated 29 May 2012
Copyright © CodeProject, 1999-2012
All Rights Reserved. Terms of Use
Layout: fixed | fluid

You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
  Refresh
GeneralBetter Living Through Immutable Objects Pin
Monday, February 14, 2005 1:22 PM
Hi, my name is Jon Person, and I'm addicted to writable properties.
 
After several years of programming, I had gotten into the habit of making properties writable. It made great sense on the surface -- if the value can be changed then make the property writable and call it easy-to-use. Recently, however, I needed to make use of multithreading more than ever before and I quickly ran into synchronization problems. After several days of re-engineering to solve these problems, however, I'm now convinced that developers should try to make their objects immutable whenever possible to avoid complicated threading issues.
 
Immutable objects are objects whose properties cannot be modified once the object is created. All property values are instead set via the object's constructors. This approach forbids any "Set" accessors on properties, yet it makes an object completely thread-safe because there are no values to synchronize between threads. Another advantage to immutable objects is that they become simpler than their mutable counterparts. Many times, a mutable object must recalculate other properties within itself to stay in check. The "Angle" class of GPS.NET was a great example of this -- when the "DecimalDegrees" property changed, a lot of code went into recalculating the "Hours," "Minutes," and "Seconds" properties. Immutable objects can shed a lot of this overhead.
 
I'm now of the opinion that classes should be immutable by design unless a few conditions exist:
 
  1. If the class contains several properties, making it immutable may not be a good idea since it would require constructors with a lot of parameters.
  2. If the class requires significant initialization or finalization, it would not be a good immutable object because these processes would occur frequently whenever a property had to change.
  3. If the class uses a significant amount of memory, like a huge array, making it immutable might add too much overhead.
  4. If the class must source events or provide virtual "OnChanged"-type delegates, it cannot be immutable.
  5. An object should be immutable only if it's properties' types are also immutable. If you can drill-down from your object and eventually a property somehow, the class will not be fully thread-safe! This is why it's best to make your base types immutable first, and build from there.
 
This looks like a lot to sacrifice, but in my opinion the end result was still worth the effort to gain verifiably thread-safe code for downstream developers. The events were the only painful thing to remove because I had been relying on some of these events to tell a collection that its contents had changed. This, too, however, turned out to be alright to deal with, though it required some extra "IndexOf" code to find the index of an object before replacing it. Additionally, the new immutable classes got rid of some issues with "GetHashCode." This method is supposed to return the same value throughout the lifetime of the class -- even if the class is mutable. The newly-immutable classes now behaved with this rule.
 
The re-engineering process for each class broke down into several steps:
  • Having NUnit tests to test property behavior.
  • The return types for each property were verified to be immutable.
  • "Set" accessors for the class were removed.
  • Code from "Set" accessors were moved into constructors.
  • Methods which modified the class had their return value changed to return a new instance of the class instead.
  • All events and "OnChanged"-like virtual methods were commented out Frown | :-(
  • NUnit tests were re-run
 
After a few days of re-engineering, the GPS.NET 2.0 library is now mostly thread-safe by design and easier to maintain, thanks to immutable objects.

 
GeneralSolving bad form validation with your own Parse method Pin
Monday, February 14, 2005 1:20 PM
Filling out forms on the web is one thing that makes me crave having a microchip in my forehead. I've been on three web sites this morning which have each required that I fill out a form. Thanks to the Google Toolbar "AutoFill" feature, this is really easy to do. However, in each of these forms, there were validation errors. One in particular made my blood boil for a few seconds:
 
ERROR: Please enter an area code without parenthesis.
 
Call me crazy, but wouldn't it have been easier to add code to remove the parenthesis than it would have been to raise the error?
 
AreaCode = AreaCodeTextBox.Text.Replace("(", "").Replace(")", "");
 
if(AreaCode.Text.Length != 3)
MessageBox.Show("ERROR: Please enter an area code without parenthesis.");
 
It seems that there are web developers out there (myself not immune) who are demanding that users type in absolutely perfect form data before they are allowed to proceed. This is bad practice and leads to a poor user experience because of human error. Phone numbers, social security numbers, names... all of these fields can be typed in different formats yet have the same meaning. Many times, a little bit of string parsing goes a long way. So, for myself and others, here's a friendly reminder:
 
Make a reasonable effort to anticipate varying data formats. This frequently involves the use of the Replace() and Trim() functions to reduce data to its simplest format. An error should be displayed to the user only if this reasonable effort fails.
 
... this rule is especially important in online order forms, where "closing the sale" as they say can make or break your company. I was once buying some software, and the order form gave me this astounding error:
 
ERROR: Credit card numbers may not contain spaces.
 
What on Earth? A sale brought to its knees by spaces? Once again, the code to fix the problem would have been less code than raising the error!
 
CreditCardNumber.Replace(" ", "") // ahem
 
I went back and completed the order, but I swear if it would have given me one more dumb error like that, I would have given up, and they would have missed out on the revenue. It's really just good sense to anticipate human errors in your user interfaces.
 
If you really want to get serious about this in terms of component, you might consider following the .NET framework technique of adding a static (Shared in Visual Basic) "Parse" method to your classes if they resemble simple value types. Your Parse method will be especially useful if it can handle whatever "ToString" can spit out. I've received a lot of great feedback from GPS.NET customers because the library uses this exact design -- Parse and ToString are designed to handle each other's output. This makes forms and other forms of I/O elegant:
 
// Make an instance of an object (in this case, an Azimuth)
Azimuth MyAzimuth = Azimuth.Empty;
// Use ToString to show the azimuth in a human-readable form
MyTextBox.Text = MyAzimuth.ToString();
// The user makes modifications, which must be interpreted
MyAzimuth = Azimuth.Parse(MyTextBox.Text);
 
public static Azimuth Parse(string value) {} // etc.
 
... if a user types an azimuth of "45.0" or " 45 " or "NE" or " NoRtHeAsT " in a TextBox, it all translates to the simplest meaning in the Parse method (a double of 45.0), and there's no form error. So, remember to anticipate human errors, reduce information to its most basic form when you're collecting it from forms, and consider incorporating "Parse" into your simple value types. This may net you some well-earned revenue as well as thanks from your users by sparing them from string parsing. My apologies for saying "string parsing" -- I will go wash my hands now.

GeneralRe: Solving bad form validation with your own Parse method Pinmemberjblewis8:57 2 May '05  
I completely agree with you here! Particularly on the "closing the sale" bit. My street address has a "/" (slash) in it. The post office agrees that it should have a slash in it, and yet there commerce sites out there that are convinced that "/" is not a valid character in a street address. It gets pretty aggrevating sometimes.
 
BTW, great GPS related articles!
 
GeneralWhy the Equals Method Has Different Meanings in Value Types Versus Reference Types Pin
Monday, February 14, 2005 1:19 PM
Overloading the Equals method in reference types is one of the most confusing guidelines to me because there is no concrete "when to do it" rule for reference types, and there are contradictions that come up when I try to do it. For example:
 
* When overriding Equals in a reference type to compare values, you should make the equality operator (==) do the same thing.
* Most reference types, even those that implement the Equals method, should not override ==.
 
So, once you finish implementing Equals, also implement ==, then comment out the code for == because it's really not allowed :P. I think that the two rules above should be rephrased into the following:
 
"Equals and the equality operator must be synonymous in value types, but have separate meanings in reference types. Override Equals in reference types to compare values only if sufficiently documented and the equality operator is left alone."
 
I've wrestled with this a lot with the "Angle" class in GPS.NET (http://www.gpsdotnet.com/Support/Documentation/StormSource.Gps.Angle.html) because it is by all accounts a value type. It stores a single value, a double, between 0 and 360 degrees, and is immutable, making it a great candidate as a value type. The only reason it's *not* is that it must be inherited from, and value types cannot be inherited from.
 
Turning a value type into a base type is a disappointing process because of the sacrifices that must be made. First, since (==) can no longer be overloaded to compare values, all math operators (+, -, +, /) must also be abandoned, which, according to FxCop, requires that the (==) operator be overloaded to test for value. See what I mean? Ouch. Goodbye elegance. Still, I can't help being tempted to break this rule and implement math operators. For example, this looks perfectly fine to me:
 
Angle Angle1 = new Angle(45);
Angle Angle2 = new Angle(180);
Angle Sum = Angle1 + Angle2; // 180 + 45
 
... yet it is not allowed!
 
After a lot of waffling, the Angle class now has what may be the best FxCop-compliant compromise. Mathematical operators are not overloaded (which makes FxCop happy), but mathematical methods "Add," "Subtract," which typically accompany overloaded math operators, are present, allowing for still-readable code:
 
Angle Angle1 = new Angle(45);
Angle Angle2 = new Angle(180);
Angle Result = Angle1.Add(Angle2); // 180 + 45
 
... which I guess is reasonable. It's just that Rule Number One of successful component development, in my opinion, is to "Facilitate Efficiency With the Simplest Possible Solution for The Developer, Not the Author." This rule would demand that "+" is better than "Add" because it saves developers the most time, but it's just not allowed, even when a base class is 99.9% similar to a value type.
 
If I was working on a private project, I would probably ignore FxCop and go ahead with overloading mathematical operators on a reference type, twisting my mustache as I go, but a reusable component is a much larger audience to appeal to. Has anyone ever overloaded mathematical operators in a reusable reference type with favorable feedback? I'm guessing "No."

 
GeneralWelcome! Pin
Monday, February 14, 2005 1:19 PM
I've been wanting to get involved in blogging for a while because GIS and GPS is so fascinating, and there's a ton to learn and discuss about it. As a component developer, I'm also finding that there are a bunch of nuances that come up during .NET development and it's always valuable to get feedback from others before putting something into production. It'll take me a little while to get the hang of this but I'm hoping it becomes a good learning source for GIS, GPS and .NET.
 
Just a little background about me: I am the author of a GPS product named "GPS.NET" (www.gpsdotnet.com) which has become quite successful as a tool for GPS developers. I am practically addicted to authoring components and have much more fun writing them than end-user applications. The thought of empowering others is more attractive that filling a niche, perhaps. I enjoy writing articles and helping other developers, and have been named a "Most Helpful Member of 2004" on CodeProject (http://www.codeproject.com/script/rumor/article.asp?id=316) for my series on GPS applications.
 
When I'm not coding, I enjoy spending time with my girlfriend, Bonnie, near our home in the foothills of Colorado. I really like storm chasing as well (hence the blog name), and have been on national TV a few times (a la Real TV, Extreme Driving Quiz, Worst Case Scenario) from my experiences close to storms. Lately, however, programming has become more exciting than storm chasing, believe it or not, because chasing storms requires a ton of driving and there's no guarantee of seeing an exiting storm.
 
I hope you find this blog useful, and welcome discussions on any of these topics...
QuestionRe: GIS article. PinmemberMonomachus0:55 2 Nov '08  
AnswerRe: GIS article. PinmemberJon Person9:42 6 Nov '08  
GeneralRe: GIS article. PinmemberMonomachus6:17 4 Dec '08  
GeneralRe: GIS article. PinmemberShooker569:15 10 Jun '10