Posted on
March 19, 2008 15:17
by
JP
tdd
Categories:
Actions:
E-mail |
Permalink |
Comments (0) |
Trackback
Have you ever had someone from QA come up to you and say something like "Screen X isn't saving data anymore"? And then you say something like "What the hell???" because you are sure that nothing has been touched in that part of the app for weeks? Not only that, it was working perfectly the last time you were there. P-E-R-F-E-C-T-LY. I swear! I mean, just look in the database. There is data in there. And it came from that screen.
I know some of you know what I am talking about. I have experienced this many times. For some inexplicable reason code that was fine now seems to have actually physically decayed on my hard drive somehow...like a corpse in July...in Houston no less!
Those of you who have no idea what I am talking about or maybe relate to what I am saying in some sort of distant, primordial, genetic memory kind of way, have probably been doing TDD. Or at least writing lots of unit tests around your code.
I have finally reached the point where I can say with absolute certainty that I am almost doing TDD. I am writing unit tests a lot and sometimes those unit tests affect my design. Sometimes I write the test first, like I am supposed to do. And sometimes I don't, but my code is testable nonetheless. In the end, I do have unit tests all over the place. I'm talking solid coverage, too. State-based tests. Interaction-based tests. Stubs. Mocks. Fakes. You name it, I got it.
So, today, we had to jump into some code that is WEEKS old. In the past, the code would just break (of course) if only for the mere fact that we looked at it. Like when you go to the doctor and everything is fine, but when you leave, you have cancer. Anyway, everything worked. And I mean, it worked great. I am convinced that unit tests are to bugs what garlic is to vampires. It's like the unit tests observe the code, so you can go look at something else, and thereby Schrödinger's cat gets to live.
Posted on
March 16, 2008 08:24
by
JP
Categories:
Actions:
E-mail |
Permalink |
Comments (0) |
Trackback
public void main() {
Console.WriteLine("Hello, world!");
}
Posted on
March 15, 2008 06:37
by
JP
ideas
Categories:
Actions:
E-mail |
Permalink |
Comments (0) |
Trackback
I have been throwing around the idea of going back to school to get a degree in Mathematics for about a year now. Also, I am concerned about the level of education my kids are receiving in school. After talking things over with my wife we decided to do a family math night once a week. This will give me a chance to brush up on my math skillz as well as help my kids.
My oldest stepdaughter is going into the 6th grade next year, and my youngest will be going into the 5th. They are both very intelligent and interested in doing well in school. For them, I have a workbook consisting of basic Algebra and Geometry targeted (conveniently enough) at 5th and 6th graders. Oddly enough, they seem very enthusiastic about this. Honestly, I was expecting a hard sell, but apparently "getting ahead in the game" is something they want to do.
My wife and I are starting with Algebra and working up from there. My wife claims that she is not very mathematically inclined. However, I just don't believe statements like this. What I have discovered is that math is like anything else. You put in the time. You learn the rules. Then suddenly, you are mathematically inclined. Maybe I am wrong. We will see.
I am still trying to sort things out. I need online resources for generating practice problems with answers as well as tests. I have found a few good sites but admittedly I am still trying to work out the fine details. My goal is to come up with a good program that I can pass along. When I know something, you will know something.
Posted on
March 1, 2008 06:31
by
JP
experiments
Categories:
Actions:
E-mail |
Permalink |
Comments (0) |
Trackback
Well, on February 10th, I started selling books on Amazon. In 13 days I did over $700 in sales. Let me tell you something. People will buy anything. After Amazon sent my first check, I subtracted my expenses and sent the profits to my student loan provider(?) It amounted to two months worth of payments. All in all, I am very happy with the results.
Now, I have a problem. Where do I get more books? I am going to hit every Goodwill and thrift store in my area tomorrow. Garage sales, too. I don't know what I will find. My mission is just to get the lay of the land, because I have no idea how this business works. Do I need to pass around bribes to get access to the books? Is there a secret underground for this kind of thing? Who knows? I will tell you that I aim to find out. I am also desperately trying to rack my brain for more micro-businesses like this. My goal is to get 6 independent streams of income going.
Posted on
March 1, 2008 06:22
by
JP
Categories:
Actions:
E-mail |
Permalink |
Comments (2) |
Trackback
I am working on a large WinForms project utilizing MVP. Some of our views are really, really big with lots of tabs (hey, the users wanted this, not me). This makes things difficult for several reasons.
For one thing, the WinForms designer just can't keep up when it comes to large forms with all kinds of nested controls on it (maybe 2008 is better, I don't know). Last year we decided to make the contents of every tab a user control. It sounds ridiculous, because we don't reuse any of the stuff from screen to screen, but it really speeds things up in Visual Studio and we get far fewer designer crashes...for whatever reason. Also, even if we don't need reuse, the UserControls still provide a nice separation of concerns.
Things get interesting because we need to pass a lot of data around in our views. For instance, we have tons of lookup information that needs to get to various parts of the view in order to populate dropdown lists and other things. The fact that the view is broken up across x number of user controls makes things interesting.
If my presenter fetches the data and I pass it back to the view, it will have to be re-routed to the appropriate user control on a tab some place:
// from the presenter
_view.SetCountryCodes(codes);
// in the implementation somewhere
public void SetCountryCodes(IList<ILookupValue> codes)
{
this.ClientTab.SetCountryCodes(codes);
}
My views and presenters were starting to get tons of GetXXX and SetXXX methods on them. We thought about using events declared on the presenter because each user control (on every tab) has a reference to the presenter, so it would be relatively easy for each part of the view to subscribe to events they need in order to get data back from the presenter. The main reason I didn't want to use events like this is because I thought I would have an EventArgs Explosion (CountryCodeEventArgs, StateCodeEventArgs, EmployeeEventArgs, etc).
It's funny, but my mind still does not go to generics for solutions, even though I use them all the time.
But it hit me. I can just use generics and create an all-purpose event. Something that says "Hey, I have data that you need":
public class GenericEventArgs<T> : EventArgs
{
private readonly T _data;
public GenericEventArgs(T data)
{
_data = data;
}
public T Data
{
get { return _data; }
}
}
This allows me to declare type-safe albeit scary-looking events in my presenter like this:
public event EventHandler<GenericEventArgs<IList<ILookupValue>>> SetCountryCodes;
Each part of my view can subscribe to the events on the presenter that are pertinent. My view interface doesn't have a million methods defined on it. And finally, this stuff is very easy to test.
Another pattern I have utilized is Introduce Parameter Object [Fowler Refactoring] (well, kind of). Instead of having an event for each type of data that I want to send to various parts of my view, I create a single class that contains all of my lookup data:
public class LookupData
{
public IList<ILookupValue> _countryCodes;
public IList<ILookupValue> _stateCodes;
public IList<ILookupValue> _projectTypeCodes;
public IList<ILookupValue> _uomCodes;
public IList<ILookupValue> CountryCodes
{
get { return _countryCodes; }
set { _countryCodes = value; }
}
public IList<ILookupValue> StateCodes
{
get { return _stateCodes; }
set { _stateCodes = value; }
}
public IList<ILookupValue> ProjectTypeCodes
{
get { return _projectTypeCodes; }
set { _projectTypeCodes = value; }
}
public IList<ILookupValue> UomCodes
{
get { return _uomCodes; }
set { _uomCodes = value; }
}
}
Now, I can pass everything via a single event:
public event EventHandler<GenericEventArgs<LookupData>> SetLookupData;
Tab A might need country codes. Tab B might need project type code. Every part of the view gets the same object, but just takes what it needs out of it.