About Me

Training

Nothin But .Net Developer Bootcamp

Navigation

Search

Categories

On this page

CoDe article just published
(Automated Build Script + ReSharper Solution Wide Error Analysis) == The Bomb
Read any good books lately?
Help Improve ReSharper
Multithreading Question - One Solution
Learning Some New Stuff - Adapting And Filtering
The Open Closed Principle. - How Far Do You Take It
WPF - A New Set Of Shiny Tools (and the fastest way to get upto speed on it!!)
One Class To Rule Them All
TDD Anti-Patterns
From CodeGen To TDD
Best Of Compendium!!
Build A Solid Core

Archive

Blogroll

 Agile Developer Venkat's Blog
 Ayende @ Blog
 B#
 Barry Gervin's Software Architecture Perspectives
 Boy Meets World
 Brad Abrams
 Canadian Developers
 Christopher Steen
 Claritude Software News
 Clemens Vasters: Enterprise Development and Alien Abductions
 Coding Horror
 Coding in an Igloo
 Dare Obasanjo aka Carnage4Life
 Darrell Norton's Blog [MVP]
 David Hayden [MVP C#]
 Don Box's Spoutlet
 Eric Gunnerson's C# Compendium
 EZWeb guy: Jeffrey Palermo [C# MVP]
 Fear and Loathing
 Generalities & Details: Adventures in the High-tech Underbelly
 Greg Young [MVP]
 Greg's Cool [Insert Clever Name] of the Day
 IanG on Tap
 Ingo Rammer's Weblog
 ISerializable - Roy Osherove's Blog
 James Kovacs' Weblog
 Jason Haley
 Jean-Luc David
 Jeremy D. Miller -- The Shade Tree Developer
 JetBrains .NET Tools Blog
 Jimmy Nilsson's weblog
 John Bristowe's Weblog
 John Papa [MVP C#]
 Jon Skeet's Coding Blog
 JonGalloway.ToString()
 Jump the Fence or Walk Around
 Lambda the Ultimate - Programming Languages Weblog
 Larkware News
 Lutz Roeder
 Marquee de Sells: Chris's insight outlet
 Martin Fowler's Bliki
 Mike Nichols - SonOfNun Technology
 MSDN Magazine - .NET Matters
 MSDN Magazine - All Articles
 OdeToCode Blogs
 Onion Blog
 Planet TW
 Raymond Lewallen [MVP]
 Rockford Lhotka
 RodMan's Corner
 Roger Johansson's blog
 Sahil Malik - blah.winsmarts.com
 Sam Gentile's Blog
 Scott Bellware [MVP]
 Scott Hanselman's Computer Zen
 ScottGu's Blog
 secretGeek
 Service Station, by Aaron Skonnard
 Signum sine tinnitu--by Guy Kawasaki
 Stephen Toub
 Steve Eichert's Blog
 Steven Rockarts
 The Blog Ride
 The Coding Hillbilly
 The Daily WTF
 TheServerSide.net: News
 Tim Gifford
 Vance Morrison's Weblog
 you've been HAACKED

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

RSS 2.0 | Atom 1.0 | CDF

Send mail to the author(s) E-mail

Total Posts: 397
This Year: 122
This Month: 0
This Week: 0
Comments: 1033

 Monday, April 30, 2007
Monday, April 30, 2007 5:24:13 PM (Mountain Standard Time, UTC-07:00) ( Articles )

I’d like to say thank to everyone at CoDe magazine, for coordinating with me to get a new article out of the door.

The article was created as a way to introduce people to the concepts of Layered Architecture, Dependency Inversion, and Dependency Injection.

You can check it out online here.

Comments [7] | | # 
Monday, April 30, 2007 5:19:59 PM (Mountain Standard Time, UTC-07:00) ( Tools )

Using ReSharper 3.0 for the last week and a bit has been an awesome experience. It is currently in the EAP phase, but so far it is proving to be the most solid eap of the product they have released to date (in my opinion).

Of all of the features that have been brought into the mix, I am particularly pleased with:

  • Solution wide error analysis
  • TODO Explorer
  • Member reordering

I asked for solution wide error analysis as a feature several months ago, I am pleased that other people must have also asked to ensure that it got brought into the mix.

The title of the post has to deal with the fact that coupled with the solution wide error analysis, I can now truly not need to do my compiles using studio at all. During this last week, I held another iteration of my Nothin But .Net coding bootcamp (1 10 hour day, 4 14 hour days!!). Aside from 2 times that I accidentally built in studio, the app evolved over the course of the week, and there was no need for me to use studio once to do a build.

The nice thing about the solution wide error analysis, is that I can deal with my error quicker than doing a NAnt compile, looking for the error, fixing, and repeating. I can just hit ATL-F12 to take me to the next error in the solution, fix the code, ensure that I am good to go solution wide, then I can do my build in NAant.

Cheers to the Jetbrains team for continuing to evolve a stellar product for .Net developers.

 

Comments [2] | | # 
 Friday, April 20, 2007
Friday, April 20, 2007 7:25:26 AM (Mountain Standard Time, UTC-07:00) ( Programming )

Having seen what Justice is upto, I thought I would take the time to answer a question that I get asked all the time “What’s books do you recommend I should read”?

While the scope of the books I could recommend is quite large, I am going to narrow my focus to the realm of the developer. Some of these books are ones that I wish I had read while I was still in school (of course, they might not have been out then!!). The list is ordered in the way “I feel” they should be read. More specifically, I have focused on books that I think can equip people (alongside real world experience) to “Build A Solid Core”

Here it is:

You’ll notice that I have not even touched on specialized topics such as web/windows development,object relational mapping, or even sql. We’ll save that list for another day. I have also published this as a listmania list to Amazon.

Happy Reading.

Comments [5] | | # 
 Wednesday, April 18, 2007
Wednesday, April 18, 2007 6:30:02 AM (Mountain Standard Time, UTC-07:00) ( Tools )

David Stennett over at JetBrains is soliciting existing users of ReSharper to pipe up and tell them about things they could do to improve the killer product we all know and love (all of us who use it that is!!).

Take a couple of minutes out of your busy day and fill out this survey which should arm them with more information with which they can continue to improve the single biggest productivity booster to grace Visual Studio.

Comments [1] | | # 
 Tuesday, April 17, 2007
Tuesday, April 17, 2007 1:35:11 PM (Mountain Standard Time, UTC-07:00) ( C# | Programming )

This morning had a good question asked:

Q: Basically we're writing the billing processing part of our business
application.  On the 1st and 15th of the month, we bill all our
policy holders and it's usually 10,000 or so transactions that need to
be run.  The processor gateway runs as a webservice.  Now since these
10,000 don't rely on each other at all, I figured to speed it up I
could run 10-20 at a time in a job.
 
So I wrote this simple class so far, but I'm not sure if it's even
close, it just takes a processing date, loads all the queued
transactions, and sends them into the authorize and payment manager.
It seems that async threads you have to delegate to a void
parameterless method, so I built a locked incrementer for the index on
the generic list of transactions and try to process them like that.
It's the while loop stuff that is lame, I'd really like it to just
spawn X number of threads where X is configurable.  Maybe I just dont'
get it, here's the code though: 

public class Billing { public Billing(DateTime ProcessDate) { _ProcessDate = ProcessDate; PopulateTransactions(); ExecuteBilling(); } private Int32 _TransactionIndex = 0; private List<Transaction _TransactionsToBill; private DateTime _ProcessDate; private void PopulateTransactions() { _TransactionsToBill = TransactionManager.GetQueuedTransactions(_ProcessDate); } private void ExecuteBilling() { do { Thread t1 = new Thread(new ThreadStart(ProcessTransaction)); t1.Start(); Thread t2 = new Thread(new ThreadStart(ProcessTransaction)); t2.Start(); Thread t3 = new Thread(new ThreadStart(ProcessTransaction)); t3.Start(); Thread t4 = new Thread(new ThreadStart(ProcessTransaction)); t4.Start(); Thread t5 = new Thread(new ThreadStart(ProcessTransaction)); t5.Start(); } while (_TransactionIndex < _TransactionsToBill.Count); } private void ProcessTransaction() { string Message; Transaction transaction = GetNextTransaction(); if (transaction != null) CyberSourceManager.AuthorizeAndCapture(transaction.InvoiceID,transaction.ID, out Message); } private Transaction GetNextTransaction() { Interlocked.Increment(ref _TransactionIndex); if (_TransactionsToBill.Count _TransactionIndex) { return _TransactionsToBill[_TransactionIndex - 1]; } return null; } }

A: The main problem that you are concerned about is : “I'd really like it to just spawn X number of threads where X is configurable”. The following code is another alternative implemented using the Monitor class to create a producer/consumer queue:

public class Billing { private Queue<Transaction> transactionQueue; private IList<Thread> workerThreads; private object mutex; public Billing(int numberOfWorkerThreadsToUse,IEnumerable<Transaction> itemsToProcess) { mutex = new object(); workerThreads = new List<Thread>(); transactionQueue = new Queue<Transaction>(); InitializeConsumers(numberOfWorkerThreadsToUse); QueueUp(itemsToProcess); QueueEmptyTransactionsForEachActiveThread(); } private void QueueUp(IEnumerable<Transaction> toProcess) { foreach (Transaction transaction in toProcess) { QueueForProcessing(transaction); } } private void QueueEmptyTransactionsForEachActiveThread() { foreach (Thread wokerThread in workerThreads) { QueueForProcessing(null); } } private void QueueForProcessing(Transaction transaction) { lock (mutex) { transactionQueue.Enqueue(transaction); Monitor.PulseAll(mutex); } } private void InitializeConsumers(int numberToInitialize) { for (int i = 0; i < numberToInitialize; i++) { Thread thread = new Thread(ProcessTransactions); workerThreads.Add(thread); thread.Start(); } } private void ProcessTransactions() { while (true) { Transaction transaction = null; lock (mutex) { while (transactionQueue.Count == 0) Monitor.Wait(mutex); transaction = transactionQueue.Dequeue(); } if (transaction == null) return; Process(transaction); } } private void Process(Transaction transaction) { //Do you work here } }

The advantage of this code over the prior code is it mitigates unecessary allocation of an unknown number of threads and opts for the creation of an explicit “known” number of worker threads that will process items on the queue. This code leverages the ability to wait on a locked object. When a transaction is Queued up, Monitor.PulseAll is invoked (on the mutex) to wake up all threads that may already be waiting on that mutex,based on which thread is currently highest in the lock queue, it will be able to Dequeue a single transaction from the “transaction” queue and process it.

The constructor for the Billing class allows you to specify how many worker threads should be created. You should notice, that the Consumer threads can start immediately processing Transactions the second a Transaction is queued for processing. This has the benefit of not needing to have the queue populated in its entirety before processing. As new items are added to the queue, a worker thread can pick it up and process it. Once all of the real transactions have been added to the queue for processing, a “null” transaction is placed onto the queue for each worker thread that was created. This ensures that each thread will actually terminate.

Notice how in the ProcessTransactions method, it does not stop processing if the number of items in the queue == 0. This is because (again, multi threaded coding is hard) since items are being added to the queue from a separate thread, and items are being processed by 1 of the many worker threads, the client thread may not have had the opportunity to place items on the queue before the (transactionQueue.Count == 0) condition is evaluated. If I used the count of the items in the queue as my termination condition, the worker thread would most likely terminate too early. Hence the need for the null transaction that each thread will have to handle. Once the worker dequeues a null transaction, it knows that it is time for it to finish.

I’m not saying this is the only way to solve this problem, I just wanted to demonstrate how you could share the load of the processing between a finite amount of worker threads, while utilizing the Monitor class to perform fine grained synchronization.

The usage for this class becomes very simple:

new Billing(5,transactionService.GetTransactionsToProcess());

 

 

Comments [2] | | # 
 Monday, April 16, 2007
Monday, April 16, 2007 9:11:37 AM (Mountain Standard Time, UTC-07:00) ( Programming )

Just started a new contract and got thrown into a world that I have relatively “no” experience in. The world of data warehouses, cubes, analysis services, SSIS.

Anyway, not having a good handle on some of this stuff I needed to get an understanding of how some of the pieces all fit together.  Never one to be too proud to ask for help, I turned to a good friend and awesome teacher who gave up a good couple of hours in his day to school me in all things OLAP centric!!

It’s times like this when I am reminded of the importance of why we all got into this profession in the first place. The mind stretch!!!! I don’t love the designer centric world of the tools that I am going to be having to use for the next couple of weeks, but they are the means to a quick end for a reporting deliverable that needs to be shot out the door. It’s also a chance to play around with a set of tools that are outside of the realm of tools that I usually develop with. Which ultimately will make me a more rounded devleoper (seems weird to call it development when there is little coding that actually goes on…).

On the topic of learning new things; in the past I have tried to follow the guidance of the Pragmatic Programmer and taken it upon myself to learn at least one new language a year for the last couple of years. Each year I bring a couple of new dev tools into the mix (usually open source). And each project, I try to force myself to think of different ways to solve problems that may be similar to ones I have already encountered.  Because of the set of tools, practices, and techniques I have been focused on over the last couple of years, I think I  became a little closed to the MS specific toolsets that were coming onto the market. Can you believe I’ve never even looked at the Analysis Services, and SSIS projects inside of studio before!! My personal experience has been that for most jobs I want to tackle, there are much more lightweight alternatives that do the job for me, than what has typically come out of the MS space.

Back to the “learning” thing, I think about times when I am asked  “How do you keep up with it all?”, I answer them simply – “I don’t”. I keep up with the things that have a direct impact on the projects that I am currently working on, and I keep my eyes peeled so I have a cursory knowledge of stuff coming down the pipe. Of all of the stuff that has come down the firehose in the last couple of months, the stuff that I am currently focused on (ie. actively working with) is:

  • Windows Communication Foundation
  • Windows Presentation Foundation

Wait JP, that’s it? That’s right. All of the other stuff I currently use, works and it works well for me on 90% of the projects that I have been presented with. It also allows me to narrow my focus on 2 new technologies that I want to learn really well, as opposed to being spread too thin trying to learn several tools not so well. This will once again augment my regular toolset, that usually consists of a large combination of open source tools, MS offerings, and a smattering of well deserved purchased tools that do a lot of heavy lifting for me.

My personal recommendation with regards to personal learning is to first and foremost focus on “building a solid core” which can be leveraged now and in the future to distill which technologies, practices, and tools can aid you on projects you are working with, as well as having a foundation that allows you to learn new tools and frameworks fairly quickly. Also, focus on being able to “filter” out the noise that is not currently part of your current “conversation”. This leaves you free to focus on the tasks at hand with the tools you know while simultaneously logging in your mind stuff that you could see benefit applying on future tasks.

Happy Learning.

 

 

Comments [2] | | # 
 Tuesday, April 10, 2007
Tuesday, April 10, 2007 11:42:17 AM (Mountain Standard Time, UTC-07:00) ( Programming )

A couple of good comments came up in the last post about the use of utility classes in the realm of SRP. I made the statement that I personally don’t mind using utility classes sparingly, as long as the class itself is adhering to the rules of SRP, meaning that the methods it is composed of revolve around one discrete area of functionality.

Ayende brought up a good code example and asked Jeff how he would handle the situation without using utility classes (Jeff posted a response to this question). This is the code that Ayende provided:

public void QueueToExecute(ICommand command)
{

  Validation.NotNull(command,
"command");

 
// do stuff
}

For those not familiar, the check that is being performed to ensure that the command is not null could be viewed as a simple validation check. Some developers refer to this as more than simple validation checking and refer to it as DBC (Design By Contract). Intentional or not, the explicit checking of the “non null precondition” is a DBC technique, used to indicate to the client developer preconditions that must be in place for the method to continue, I digress!!

So what does OCP have to do with any of the code that was talked about the other day? Looking at the code above, I could make an assumption that the method lives on some sort of ICommandQueue implementation (we’ll call it CommandQueue). And it could look something like this (lots omitted for brevity):

public class CommandQueue : ICommandQueue { private Queue<ICommand> commands; public CommandQueue() : this(new Queue<ICommand>()) { } public CommandQueue(IEnumerable<ICommand> initialSetToQueue) { commands = new Queue<ICommand>(initialSetToQueue); } public void QueueToExecute(ICommand command) { commands.Enqueue(command); } }

Notice that the current version of CommandQueue does not contain the check for nulls on the QueueToExecute method. I could leverage DBC to ensure that preconditions expected by the client are met before adding the Command to the queue. This results in the call to the utility Validation class that Ayende brought in earlier:

public void QueueToExecute(ICommand command) { Validation.NotNull(command,"command"); commands.Enqueue(command); }
 

This works. If the Validation class is simply a static container for procedural methods the NotNull method could look as follows:

public class Validation { public static void NotNull(object item,string itemDescription) { if (item == null) throw new ContractViolationException(itemDescription); } }

On the other hand, Validation could be a mere Gateway that provides convienient access to discrete Assertion objects etc. I could carry on but I would rather focus on the current consumer of the Validation class itself. The CommandQueue. In the original implementation of CommandQueue, it had no smarts about performing the null check on incoming commands. By introducing the explicit check in the QueueToExecute method I have satisfied a rule that needed to be encapsulated for the method, but in the process I have violated the Open Closed Principle.

The Open Closed Principle

“a class should be Open for extension but Closed for modification”.

Back to the CommandQueue example, the original CommandQueue implementation worked fine before the requirement came along that said that it should ensure that incoming commands are not null. If I wanted to adhere to OCP, the “Closed” part of the principle states that I should not need to change my original implementation to deal with the new requirement. The “Open” part of the principle means that my design should allow me to add new behaviour to a CommandQueue without needing to go in and actually change the code of the original CommandQueue implementation. There are a couple of ways I could accomplish this and still adhere to OCP. For now, I’ll use a Proxy to ensure that commands coming in cannot be null:

public class NullRejectingCommandQueue : ICommandQueue { private ICommandQueue queueToProxy; public NullRejectingCommandQueue(ICommandQueue queueToProxy) { this.queueToProxy = queueToProxy; } public void QueueToExecute(ICommand command) { Validation.NotNull(command,"command"); queueToProxy.QueueToExecute(command); } }

With this proxy in place, I can remove the validation check from the original CommandQueue, and I have extended it without changing it. In my service layer (or container preferably), I could ensure that all instances of CommandQueues get wrapped in the NullRejectingCommandQueue proxy so that the null check will be performed. Without bringing a container into the mix, I could use a factory to get instances of CommandQueues: 

public class CommandQueueFactory : ICommandQueueFactory { public ICommandQueue Create() { return new NullRejectingCommandQueue(new CommandQueue()); } }

Reality Check

I am hoping that most of you realize that this could very well be overkill for what you are trying to do. Part of evolving as a good designer is knowing when trying to adhere to a principle, or leverage a pattern can actually be detrimental to your code. What can help you answer that question? Time and practice. The first step in becoming a good designer, is being able to first identify the smells in your code. Just because you have a cold does not mean that everyone else can’t smell the fish in your garbage can. Once you are able to identify the code smells, before even looking at design patterns, you should get a good handle on some of the fundamental design principles that can lead you to cleaner OO designs (SRP and OCP being 2 of them).

Remember how I said that all of the design principles in one way or another tie back to SRP. In this example, performing the check for null commands was not an intended “responsibility” of the command queue class. It’s responsibility was to queue commands for execution. By adding the null check, we added added another responsibility to the CommandQueue class. I am not suggesting that the null check should not be there. I just wanted to demonstrate how you can extend the behaviour of an object (open it up with new responsibilities) without having to change the target object itself.

Comments [2] | | # 
Tuesday, April 10, 2007 7:33:37 AM (Mountain Standard Time, UTC-07:00) ( .Net 3.0 )

For those of you who have not started looking into WPF, time to start!! Even if you don’t care about the flash and jazz of the UI bits, there are pieces in there that you might want to think about leveraging in your own applications right now. One of the things that is immediately apparent to me is the evident design work that went into the development of WPF. Some of the things I have had a chance to play with that have stuck me are:

  • Logical and Visual Trees
  • Dependency Properties
  • Routed Events
  • ICommand interface (finally I can stop rolling my own!!)
  • First class command pattern support for common UI widgets
  • Even though I am not a fan of databinding, some of the enhancements that have been brought to the table are pretty impressive:
    • CompositeCollections
    • MultiBindings
    • PriorityBindings (again, finally I can stop rolling my own!!)
  • ValidationRules and ValidationResults (again,.. you get the point)!!
  • Retained-mode graphics system!!
  • Animation

I could carry on, but I think you get the point. As a developer who errs to the side of writing custom explicit code to make the UI more maintainable, WPF brings to the table a host of features that I can leverage to mix the declarative nature of XAML, with the explicitness of writing clean well-factored code that leverages proper separation of responsibilities while also taking advantage of not needing to hand roll so much stuff that I had to do with prior versions of .Net.

If you want to get upto speed quickly on what WPF can do for you, I recommend rushing to pick up a copy of the book Windows Presentation Foundation Unleashed by Adam Nathan. The book is an awesome read, and it gives you a solid grounding in all of the root concepts that you need to GROK to utilize WPF in a practical fashion.

 

Comments [3] | | # 
 Monday, April 09, 2007
Monday, April 09, 2007 6:17:51 AM (Mountain Standard Time, UTC-07:00) ( Programming )

One of the things that has really been hitting me in the face lately is the importance of adhering as closely as possible to the Single Responsibility Principle.

SRP simply states that:

 “A class should have only one reason to change”.

On the surface this can be a very simple principle to grok, the reality is that ensuring that a class is doing only one thing can be a skill that developers will continue to evolve over the course of their career.

Most people have come across the term cohesion, which describes how well the different behaviors of an object work together to accomplish a common task. Cohesion and SRP are one in the same. When looking at any arbitrary class in your codebase, it can often be very easy to determine whether a class is breaking SRP:

  • A UI that performs direct DB manipulation as well as validation of data entry.
  • “Bucket” utility classes that do everything from sending email to performing string manipulation.

Each extra responsibility you add to a class gives it another reason to change. Instead of composing highly cohesive objects each with a discrete responsibility that can be orchestrated together to accomplish a common task, many people opt for the behavior bloat that often can result when the time to factor out discrete behaviors has been skipped.

In my experience over the last couple of years, when you have someone sitting beside you, making you question strongly as to whether a particular piece of behavior is being placed correctly, it will almost always help drive out more cohesive objects that are focused around a single responsibility. Not only does this make them more testable. It also shields the rest of the system from any changes that may come along in that component, as its set of behaviors are fixed around one particular piece of functionality.

Single Responsibility is what drives us to create object oriented systems, that also leverage layering schemes, to ensure that ,even at the logical layering level, a “layer” as a whole is adhering to SRP. This means that when I create a “Presentation” layer, the layer and any of its accompanying components are focused around presentation related behavior. A DAL will be focused solely around providing data access services to the rest of the application. The domain model will be focused around encapsulating the business rules, and the heart of the system.

When you look at your codebases, ask yourself some hard questions and see whether or not you are placing too much responsibility on one object, component, or layer. By striving to follow this principle more diligently you will foster and encourage practices that lead to more loosely coupled, highly cohesive systems. Ultimately, all of the principles and practices of good OO software design come back in one way or another to trying to follow this principle as closely as possible!!

Comments [0] | | # 
 Sunday, April 08, 2007
Sunday, April 08, 2007 8:58:07 PM (Mountain Standard Time, UTC-07:00) ( Agile )

This was published a while ago, but it is an awesome read. Made me laugh, and I just read it for the first time last week!!

Gives people some good things to watch out for when they are getting into/heavily into TDD.

Comments [1] | | # 
Sunday, April 08, 2007 8:46:39 PM (Mountain Standard Time, UTC-07:00) ( Agile )

One of my readers asked me a question that I thought I would share the answer to publicly. I have omitted his name to maintain his privacy:

Question:

I have been reading your blog for quite sometime now and had a quick question on TDD. I saw your screencasts and saw that you develop your tests first and then your actual classes. I use CodeSmith to generate most of my code although I tweak it to not be modeled exactly around my tables. Given this how do I make the jump to TDD? Using the method you showed, wouldn't it take a very long time to finish the project as you are hand coding each class one by one. I basically hand coded one module (from ASPX to all the way upto the backend) and then designed my CodeSmith templates around it.

 

My Answer:

 

The first step for you to make the jump to TDD properly is to drop the code gen tools for a while. The whole premise of TDD is to design your code using tests as the design artifact to help drive out the solution incrementally. Most code gen tools do a big bang approach of code gen which you as the developer then need to go in an tweak to make work for your scenario. Utilizing code gen will not help you get into the habit of:

 

·         Writing a failing test for a requirement.

·         Getting the test to compile

·         Coding up the necessary behavior to make the test pass.

·         Cleaning up

·         Continuing

 

One of the main reasons people have a hard time getting into TDD is that it is a radical departure from the way most people normally develop. In the beginning you will walk slowly, stumbling and falling often. The tests that you initially write may not be overly good. This is because you are now crafting your skills in a new art. Over time, what initially seemed alien and uncomfortable will seem normal, rapid, and welcoming.

 

“Wouldn’t it take a very long time to finish the project as you are hand coding each class one by one?”

 

One of the things that is hard to appreciate from the small video that I showed on DNRTV, is the tools and techniques that come into play when you become a proficient test driven developer. In the class that I just finished teaching in Richmond,VA, we built a full portion of an enterprise e-commerce application with a Rich Domain Model, O/R Mapping Layer etc all over the course of a week using Test Driven Development, Design Patterns etc. One of the comments that someone made was the fact that not once during the course of the week did I use studio to either compile or run the project!

 

Again, that might seem like something out of the blue, but it is the little things that make you much more proficient as you get more accustomed to TDD. Once you are into the swing of it, you can bring your CodeGen tools back into the mix where they make sense. More often than not, most people who get swallowed up by TDD start to seriously question the value of Code Gen tools. It’s not to say that they don’t have their place, their use just becomes considerably diminished to how you may be using it right now.

 

I hope this answers your question.

 

Comments [0] | | # 
 Friday, April 06, 2007
Friday, April 06, 2007 8:06:08 PM (Mountain Standard Time, UTC-07:00) ( Programming )