Thursday, June 28, 2007
The most valuable things I learnt at uni were the ability to critically think, analyse situations and "learn how to learn". Although I really don’t use a lot of my studies on a daily basis I believe it helps me every day mainly in R&D
Wednesday, June 27, 2007
This highlights a point: Its nice to generate what you can. Hell, if you have already written the database tables, why not Gen the majority of your data access? You still however, have to know what is going on under the hood, whether its nhibernate, other ORM or straight ADO.Net. Otherwise how fix you fix lower level problems when you run in to them...
Tuesday, June 26, 2007
I did want to share some of my reasons, that may not be so text book, for using TDD. I will start with aspects of TDD, that on my most recent project, I have directly benefited from:
Define the Functionality of the Module
In the last project requirements were somewhat lose, so writing the unit test help the guy with the business know how and myself knuckle out what exactly we wanted these blocks of code to do. The people that will have to maintain my code as I move to the next project will probably find this module easier to maintain because of the reasonably well named and documented tests that are in place, meaning reduced ongoing cost of the code base.
Ability to Refactor with Confidence
As I was receiving information about the requirements in a piecemeal fashion, I was forced to write code for the functionality as I got it. This quickly became quite a large amount of code which later we found had aspects replicated across multiple classes. Refactoring these classes to strategies that inherited from a base strategy which inturn implemented an interface with the real business logic held in a handful of delegates meant we reduced the lines of code by 73%. As we refactored we made sure the entire block of unit tests still passed. The code is now a fraction of the size, very easy to read and maintain, fast and still fulfils the requirement set forth by the business. Refactoring all that code that took weeks to write was done in a day, in confidence because the unit tests were written up front.
Reduction of “Gold Plating”
In some case I get carried away and start writing things that I haven’t got a test for, because they may be needed in the future. This is by and large a bad habit of mine, I don’t get paid to gold plate, I get paid to provide a quality solution to a defined problem, even if that problem is not very well defined!
How has TDD helped? If it was not being covered by a unit test, it either needs to be or it gets removed. 9/10 it get removed as the tests are written first and they define the functionality.
Although test don’t prove you code is good (see TDD Anti Patterns) it odes show that I have thought about what I am doing and give other developers or interested parties a direct view at what my code does. Most of my test methods are named so it is pretty obvious what they do, sure some get pretty long but I can find a unit for a module that I wrote months ago pretty bloody quick and figure out with in seconds the exact functionality. This is especially helpful if you have no BA support or business requirement documentation (yes it happens). Not only am I more confident in my code but I am more confident in other code if it is unit tested.
Encourages Correct Separation of Concerns
Especially when using mocks it becomes apparent when projects are starting to take on more functionality than they should.
As I am writing tests for my code, as I go, I find that I am more likely to be within minutes of a previous compiling working solution. Formerly I used to go on tangents and write pages of code which may have been in a state far removed from a submittable state. If for some reason I was asked to shift on to other functionality I would have to shelve changes roll back and then work on something else. If I ever cmame back to that code I often had no idea where I was up to. Now I know exactly where I am up to… the method that breaks the unit tests! It is also more likely that I wouldn’t have to shelve as it is probably only a minute away from being in a compilable stae that I could check in to source control.
Easier to Make Changes
There have been some instances where the business requirements, or my understanding of them have been (a little bit) off. Having the test there means I can modify the test to assert correct assumption run the tests, see it fails and then make an isolated change in the code. As the test marry up nicely to the code the place where the change is required is very easily found and fix. ..Run test…. Pass test… Check in.
So how do i go about it? Well my"why" is covered above. For more reason check out http://www.testdriven.com or any other of the plethora of sites and books dedicated to TDD... as for the when and how...
When to test?
Before you have even written the functionality! Define what you want the method to achieve. You will probably find your self writing multiple tests per method and test fixtures are generally a lot larger than the class they test, bu the time you save in reduced debugging time and easier maintenance is well worth it.
How to test?
There are heaps of tools to use and can be a personal thing. Currently I am using TestDriven.Net with NCover and NUnit as well as ReSharper & Rhino mocks. As ReSharper is the only tool here I have paid for there is no reason not to get these widely used tools (I probably should throw some money at Testdriven.net).
Try to get a test project for each business project and a test fixtures should closely marry up with the projects classes. I don’t test minor thing like properties… there should be reason for the test!
Most frameworks now are very open to TDD, so there is very little reason not to use it. Right up to UI patterns, all but the view are very easy to test and mock. And as the view is completely stupid it should not have a lot scope for error.
So start testing; the initial growing pains are well worth it.
Monday, June 25, 2007
I have been trying to set 3 total values to right align at the decimal point in a panel on a WinFom app. It proves to be not as trivial as I expected.
I have to place each of them in a panel and then dock these labels to the right side of the each holder panel. What over kill! Why can’t the AutoSize and Anchor functionality do this for me? Oh well…
"...So imagine my surprise when we “Web Service-ized” a bunch of Java components that exposed just that kind of interface, and it didn’t work. After mucking around for almost the whole day, we started returning to basic principles. We started throwing out parameter after parameter, structure after structure, until we were left with something that should have just worked:
string SomeFunction(char c);
But it didn’t.
This was ridiculous. If Web Services couldn’t give me interoperability at this most basic level, I swore that the whole thing must have been a conspiracy. After some ill-mannered googling, I found out that:
The Java char datatype is not supported because of an omission in XML Schema..."
Tuesday, June 19, 2007
It was a good reminder that in times when you need to emphasise crucial points it probably best to talk in a language the other party will actually understand, and therefore "get" the significance of the problem. It is then up to them to make a more informed business decision from there.
It looks like there will have to be a trade off some where.
I am using the concepts from Fowler's recurrence essay and extending that. Putting that into a Database pushes me to wanting to use the XML datatype... the more i think about it tho, the less I like it as the querying power would be, well, not so good.
If I use table to map to the temporal expression it could get messy quick too. Either way i am wanting the abiltiy to create db entry for an instance of the recurrence so people can leave note etc for specific occurances...
this is going to be interesting... only post i could find so far has been
I may have to step back again and relook at what i'm doing ;)
Sunday, June 17, 2007
"Since dOOdads doesn't handle joins, I prepare the joins ahead of time by creating
.... arrrhg, OK.
Look's like dOOdads is off the list.
Tuesday, June 12, 2007
No need to go into the details of them, their sites explain all. I assume everyone is aware of NUnit.
I have decided to compile a list of issues that I have run in to in the last year, that I believe are potential short comings of the data related architecture. Often these points by themselves are not huge issues, but when I see one I usually can find another just around the corner.
Hopefully these come as some help to you and your design. Please remember this is coming from a developers perspective, a .Net and MS SQL developer at that, and I, in no way, proclaim myself to be a guru in any regard, however I feel these are basic points should be a general rule of thumb.
Normalisation to the 3rd normal is standard. If you don’t know what 3rd normal is then it is a good hint that maybe you may not be the best one to be designing the DB. Sure there are reasons to move away from this rule but it should be just that, a reason, not bad design. Perhaps you may even want to document these reasons so it is clear why.
There will always be a need for nullable columns, however when tables start to have a growing number of nullable columns, you should start questioning why. Perhaps these can be moved to a separate table.
If a table is starting to have a lot of columns and many of them are null then you may want to implement a Property table and a PropertyType table. This is relatively clean and easy to set up and if done properly, is a fast way of getting a potentially large albeit often unknown number of properties, and a lot cleaner.
Incorrect Use of the Primary Key
Recently I saw a table that had a multi column primary key over five columns. After spanning more than 2 columns alarm bells go off in my head. In this case this was just bad design. The table only needed one Primary Key with one index on another column. Often this set up I find is good especially when there are unique values such as “Product Codes” that could be the PK but are in a format that does not suit performance (e.g. varchar(1000)). Using a smaller data type for the primary key improves performance. I also generally prefer to use [int] IDENTITY(1,1) as the default primary key for tables. Using large columns as PK’s in my mind is a bit of a no-no. Some times GUID’s are used if there is movement across to other databases. If this is happening then there is probably a properly qualified DBA involved leaving us developers to move back up a layer J
Incorrect Use of the Foreign Key
I have actually seen foreign keys been “used” without the being specifically being set, meaning referential integrity can not be there! Why this was done, god only knows, as it was not documented.
Not Appling Basic Coding Standards
Commenting code is a given. I can’t stand working on projects where Classes, Methods, Properties or Parameter are not obviously named and well commented. Most developers share these views, especially one who have come into projects late. For some reason these principles are ignored when it comes to Database development. Columns get named things like “DscInd” and have no comments associated to them. As far as I am aware there are no real penalties for naming you columns something that is easily understandable. The benefits are however large. People now understanding what is actually being stored! These basic procedures also help spot flaws in any business logic. If the intention of a piece of code is explicitly commented then, if for some reason it is wrong, alarm bells go off a little easier.
Naming conventions are typically applied in managed code but again are often missed in DB Development. I could go on, but you get the general idea. Treat DB dev in the same way you would when it comes to basic procedure such as naming, commenting and using the correct types.
Monday, June 11, 2007
Saturday, June 9, 2007
I have no problem with not doing some because it is too expensive, however when you are building a business critical application for a publicly traded, Tier 1 company, you had better make sure that those things that you are not going to implement don’t bite you in the ass later.
Documentation and Unit testing should not be negotiable. Especially around business object and other lower level layers. If these layers are not working correctly, how can the layer dependent on these be reliable?
One thing I see more often than I like is not putting enough emphasis on DB design. If you are using a very basic OO model and the DB is literally just a persistence layer then I am all for ORMs. If you have complex set based structures, hire a good DB geek that can architect a proper data persistence approach in terms of DB design and helping with Data Access. Often a developer is not the right person to be doing this.
(I think I have already emphasized this enough on this blog)
Another issue is allowing for future changes. Udi Dahan proposed a design principle which I agree with and employee:
For any classes A and B in a system where both A and B have behavior, A should interact with B through an interface.
The interface which separates two concrete classes should be packaged separately from either of those classes
By employing the strategy above, you allow for the ability to have tests to isolate each “layer”. You also then allow for changing of dependency. As long as the new class implements the original interface, how the business logic occurs is irrelevant. This came up specifically this week with regards to the data access layer. Using this strategy we could investigate different options in terms of the DA, such as using the current implementation, a modified version of the current, an ORM or a Generated layer based on the DB schema. If this had been done earlier it would have take lesser than a minute for each class. Not really a huge time loss there.
I dont take all of this as bad things, it is learning from mistakes, whether they be yours or others. The point is we need to learn from them so we can find ways to avoid or fix future encounters.
Tuesday, June 5, 2007
As well as the CAB/ SCSF stuff ihave been working on at work, I have been playing with AR & AW at home. They dont really go with my normal views on enterprise level data access, however in my vague attampts to broarden my horizons I have started to dable in their worlds.
- Easy to read code. As all the DA is under the hood its code creates the illusion(?) of clearer code.
- Easy to create Business entities and DA, just drag and drop.
- Seperation of Business entities from UI
All of this can be done with Code smith, however I thought I would look at this as it is another "string to my bow" so to say. I am currently building a smalll web app from it to see how well it work under light load.
I can see these tools beign great for very basic web sites. Get someone who understands the data requirements to build a DB and AR classes then just palm it off to the UI guys as the model aspect of an MVC set up. Would be great from 3 tier app with basic data structure.
Ghost doc... well it just helps with documenting your code. Its very simple but anything that helps with the mundane is a good thing in my book.