tag:blogger.com,1999:blog-71138885915368374372024-03-13T08:58:05.681-07:00Code LiabilityCode is a liability!D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.comBlogger48125tag:blogger.com,1999:blog-7113888591536837437.post-69320712410685263472016-09-10T11:25:00.001-07:002016-09-10T11:25:12.741-07:00<center>
<table style="background-color: white; border-color: black; border-style: solid; border-width: 1px; font-size: 14px;"><tbody>
<tr><td style="margin: 0px; padding: 0px;"><table style="margin: 1px; padding: 1px;"><tbody>
<tr><td colspan="2" style="background-color: #7f9db9; color: white; font-weight: bold; line-height: 1.3; text-align: center;">Typing Stats</td></tr>
<tr><td style="color: black; text-align: left;">Words Per Minute (WPM): </td><td style="color: black; text-align: right;">86</td></tr>
<tr><td style="color: black; text-align: left;">Characters Per Minute (CPM): </td><td style="color: black; text-align: right;">432</td></tr>
<tr><td style="color: black; text-align: left;">Fastest Finger: </td><td style="color: black; text-align: right;">Left Index</td></tr>
<tr><td style="color: black; text-align: left;">Slowest Finger: </td><td style="color: black; text-align: right;">Left Ring</td></tr>
<tr><td style="color: black; text-align: left;">Word Accuracy: </td><td style="color: black; text-align: right;">100%</td></tr>
<tr><td style="color: black; text-align: left;">Language: </td><td style="color: black; text-align: right;">English</td></tr>
<tr><td style="color: black; text-align: left;">Letter Casing: </td><td style="color: black; text-align: right;">Mixed</td></tr>
<tr><td style="color: black; text-align: left;">Keyboard Layout: </td><td style="color: black; text-align: right;">QWERTY</td></tr>
<tr><td style="color: black; text-align: left;">Test Duration: </td><td style="color: black; text-align: right;">30 Seconds</td></tr>
</tbody></table>
</td></tr>
</tbody></table>
<div style="font-face: Verdana, arial, helvetica, sans-serif; font-size: 14px;">
Stats From PAT or JK's <a href="http://patorjk.com/typing-speed-test/">Typing Speed Test</a></div>
</center>
<hr />
<center>
<table style="background-color: white; border-color: black; border-style: solid; border-width: 1px; color: black; font-size: 14px;"><tbody>
<tr><td style="margin: 0px; padding: 0px;"><table style="margin: 1px; padding: 1px; width: 300px;"><tbody>
<tr><td colspan="2" style="background-color: #7f9db9; color: white; font-weight: bold; line-height: 1.3; text-align: center;">Average Finger Response Time</td></tr>
<tr><td style="color: black; text-align: left;">Left Pinky: </td><td style="color: black; text-align: right;">138 Milliseconds</td></tr>
<tr><td style="color: black; text-align: left;">Left Ring: </td><td style="color: black; text-align: right;">343 Milliseconds</td></tr>
<tr><td style="color: black; text-align: left;">Left Middle: </td><td style="color: black; text-align: right;">122 Milliseconds</td></tr>
<tr><td style="color: black; text-align: left;">Left Index: </td><td style="color: black; text-align: right;">112 Milliseconds</td></tr>
<tr><td style="color: black; text-align: left;">Right Index: </td><td style="color: black; text-align: right;">144 Milliseconds</td></tr>
<tr><td style="color: black; text-align: left;">Right Middle: </td><td style="color: black; text-align: right;">118 Milliseconds</td></tr>
<tr><td style="color: black; text-align: left;">Right Ring: </td><td style="color: black; text-align: right;">154 Milliseconds</td></tr>
<tr><td style="color: black; text-align: left;">Right Pinky: </td><td style="color: black; text-align: right;">177 Milliseconds</td></tr>
<tr><td style="color: black; text-align: left;">Thumb(s): </td><td style="color: black; text-align: right;">114 Milliseconds</td></tr>
</tbody></table>
</td></tr>
</tbody></table>
<div style="font-face: Verdana, arial, helvetica, sans-serif; font-size: 14px;">
Stats From PAT or JK's <a href="http://patorjk.com/typing-speed-test/">Typing Speed Test</a></div>
</center>
D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com0tag:blogger.com,1999:blog-7113888591536837437.post-10382597044708661342014-12-24T11:19:00.001-08:002014-12-24T11:20:25.603-08:00Cables are the fountain drinks of technology salesI just took a trip to my local MicroCenter store to purchase a 6' USB 3.0 A Male to Micro B cable. I looked at BestBuy, Target and Walmart and not being able to find anything but overpriced USB 2.0 cables. I knew that MicroCenter would have what I was looking for at a reasonable price. I need the cable right away.<br />
<br />
I did search on Amazon before I got in my car and found that Amazon's Basic brand had one for $5.99. I expected to pay a little more at MicroCenter.<br />
<br />
After finding the isle and staring at the USB cables for a while I found that the 6' cables were $27.99. Yikes! As I was standing in the isle, another couple looking at some other cables said loudly, "Wow, these are expensive!" <br />
<br />
I found a sale associate and asked if they would price match online prices (as they are also an online retailer). He said they would. I showed him the item on Amazon and he said would have to be the exact brand. I searched for the brand on my phone and matched the product number. Bingo $5.50 + $1.10 shipping for the same exact cable at Amazon. A 424% mark up! He said we would need to speak to a manager. I said, "Great, let's find one"<br />
<br />
The manager says, "Is it sold my Amazon or a third party?". Checking my phone I informed him that it was a third party. He said that there is no guarantee that I would actually receive the item if I ordered from Amazon. I shouldn't have to explain this to him (but I did) that Amazon does guarantee my purchase. He would not go for the $5.50.<br />
<br />
I ask if he would meet me half way at a reasonable price. The answer was "No". <br />
<br />
I dropped the item and turned and walked out.<br />
<br />
So just remember, do <b>not </b>buy computer or AV cables in any retail stores. These items are marked up as much as 500%. Just like how restaurants make a majority of their profits on fountain drinks.<br />
<br />
<a href="http://www.amazon.com/QVS-CC2228C-06-SuperSpeed-Micro-Cable/dp/B003DZ9Y24/ref=sr_1_5?s=electronics&ie=UTF8&qid=1419448305&sr=1-5&keywords=QVS+USB+3.0+6%27">Amazon</a><br />
<br />
<a href="http://www.microcenter.com/product/328164/USB_30_5Gbps_Type_A_Male_to_Micro-B_Male_Cable_6_Feet">MicroCenter</a><a href="https://www.blogger.com/"></a><span id="goog_381035003"></span><span id="goog_381035004"></span><br />
<br />D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com0tag:blogger.com,1999:blog-7113888591536837437.post-48397407135084008952012-03-29T09:53:00.000-07:002012-03-29T09:53:54.315-07:00Slow Insert Hyperlink dialog in OfficeWhen I am creating e-mails in Outlook or documents in Word and press Ctrl-K to insert a Hyperlink, the dialog would freeze for 5-10 seconds. It was very annoying and I've been dealing with this for quite a while on my work laptop.<br />
<br />
I turns out I had 8 shortcuts in the "My Documents" folder. Once I deleted them, the Insert Hyperlink dialog opened with no delay.<br />
<br />
Microsoft must have some issue with parsing shortcuts. I hope this helps someone else if they encounter this issue.D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com0tag:blogger.com,1999:blog-7113888591536837437.post-84997962952356296322011-10-05T17:06:00.000-07:002011-10-05T17:20:11.289-07:00Review your Event LogsI was just browsing my event log and found the following entry in system:<br />
<br />
<i>Remote session from client name a exceeded the maximum allowed failed logon attempts. The session was forcibly terminated.</i><br />
<br />
This normally would not be a concern except I've the message was logged every minute or so. After further review I see that this has been going on for the last 3 months! (as far back as my event goes)<br />
<br />
Clearly someone is trying to hack into my computer through the Remote Desktop Service. I do have a forwarding rule in my ISP's router that forwards port 3389 to my desktop. Being as 3389 is the default port for remote desktop, I guess I should not be surprised that this was happening.<br />
<br />
So what did I do? I changed the default RDP port. Yes, that's right "Security by obscurity" Not the preferred solution but it should slow down the attacks.<br />
<br />
I updated the forwarding rule in the ISP router/firewall and updated my desktop RDP port using <a href="http://support.microsoft.com/kb/306759">http://support.microsoft.com/kb/306759</a> The desktop computer firewall also had to modified to support the new port. The firewall rule for RDP on port 3389 is locked so I just created a new one for the new port.<br />
<br />
I also changed the Local Security Policy's Account Lockout Policy to 3 attempts and 30 minutes to reset. This should slow someone down as well.<br />
<br />
Luckily I have a strong password according to <a href="http://www.passwordmeter.com/">http://www.passwordmeter.com/</a><br />
<br />
<span class="Apple-style-span" style="font-family: Verdana, 'Trebuchet MS', 'Lucida Grande', Arial, sans-serif; font-size: 13px; line-height: 16px;"></span><br />
<table border="0" cellpadding="5" cellspacing="1" id="tablePwdCheck" style="background-attachment: initial; background-clip: initial; background-color: #334455; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; margin-bottom: 10px; width: 610px;"><tbody>
<tr><th style="background-attachment: initial; background-clip: initial; background-color: #445566; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; color: white; text-align: left; vertical-align: top;">Score:</th><td style="background-attachment: initial; background-clip: initial; background-color: #eeeeee; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; text-align: left; vertical-align: top;"><div id="scorebarBorder" style="background-attachment: initial; background-clip: initial; background-color: #333333; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-color: rgb(0, 0, 0); border-bottom-style: solid; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(0, 0, 0); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(0, 0, 0); border-top-style: solid; border-top-width: 1px; height: 16px; margin-bottom: 2px; width: 100px;"><div id="score" style="color: black; font-size: 11px; font-weight: bold; position: absolute; text-align: center; width: 100px; z-index: 10;">79%</div><div id="scorebar" style="background-image: url(http://www.passwordmeter.com/images/bg_strength_gradient.jpg); background-position: -316px 50%; background-repeat: no-repeat no-repeat; position: absolute; width: 100px; z-index: 0;"></div></div></td></tr>
<tr><th style="background-attachment: initial; background-clip: initial; background-color: #445566; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; color: white; text-align: left; vertical-align: top;">Complexity:</th><td style="background-attachment: initial; background-clip: initial; background-color: #eeeeee; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; text-align: left; vertical-align: top;"><div id="complexity">Strong</div></td></tr>
</tbody></table><br />
<br />
So I suggest you do take some time to review your event logs. It's surprising what you might learn.D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com1tag:blogger.com,1999:blog-7113888591536837437.post-29452183808400107602011-02-20T08:19:00.001-08:002011-02-20T08:19:39.172-08:00Some important Google Chrome Add-OnsGoogle Chrome has been released more than two years ago and it's the browser of choice for many people. Despite having won hearts for its speed and elegance, Google Chrome does have some minor flaws that you might want to fix. Here are some of them: <br /> <p>1. No confirmation when closing multiple tabs</p> <p>Google Chrome does't show a warning when you close a window with multiple tabs. If you accidentally close Chrome windows, you can install <a href="https://chrome.google.com/extensions/detail/fjccknnhdnkbanjilpjddjhmkghmachn">Chrome Toolbox</a>. The next time you close many tabs, you'll at least get a warning. <br /><img border="0" alt="alt" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFF3CykpQdIPLESs5fJhz0LpOMgHTm7UV76lvCF3ftRP8TfAL1eiVJkAaitHo1E-FA7XB2RZn4_tKWiv5RT-lj_6ai4ax1L4DBjAupXzqY9yXt3MFzB0uE8_fYIn1nh0caNh0ycKNITvy_/s640/guest-chrome-1-confirmation-dialog.png" width="400" height="141" /> <br /></p> <p>2. Basic history page</p> <p>Google Chrome's history page is pretty basic and you can't restrict the list to a certain time interval. <br />The <a href="https://chrome.google.com/extensions/detail/cahejgbbfgmlmjgdjlibphdjeldhagkp">History 2</a> extension comes to the rescue by allowing you to sort web pages based on the day/week you visited them. History </p> <p>2 allows you to delete multiple items from your history page at the click of a button – something that's not possible by default.</p> <p><img border="0" alt="alt" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBG1VTObmn2hZa9iDec9cxpmP4S-JfaAAT8EIELQ6trgtZufbx68cwKHjftO2W_1aX4jkF5RXLMRy1myiIRQViaigpn4B5i6b1cwhdM0i79RAWN5V7z5RREm3j48qGj1j1QUyPPynHMhvk/s640/guest-chrome-2-better-history.png" width="400" height="213" /> <br /></p> <p>3. Missing image properties</p> <p>There's no way to quickly examine an image when you're in Chrome. Fortunately, you can install <a href="https://chrome.google.com/extensions/detail/khagclindddokccfbmfmckaflngbmpon">Image Properties Context Menu</a>, an extension that lets you right-click on an image and find information about the image size, location, dimensions and more. <br /><img border="0" alt="alt" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKNjlOBYg7Ud_mgDTEMQ03QrvQt2Nu8PmNfEGA_IsXSQ26CwxpC3bXzeo4iHQaefdLtUlfU3aIvkvCKPOEDCjdoZr0mLTQlyyqyVieqm2pPllP7clOcf1HNZm6L4eRrdmbVSxQq23eim-d/s640/guest-chrome-3-image-properties.png" width="400" height="140" /> <br /></p> <p>4. No support for feeds</p> <p>Chrome simply doesn't recognize RSS feeds and all you get is a page with gibberish text. If you install the <a href="https://chrome.google.com/extensions/detail/nlbjncdgjeocebhnmkbbbdekmmmcbfjd">RSS Subscription</a> extension developed by Google, you can quickly subscribe to any feed using Google Reader, iGoogle, Bloglines or My Yahoo. <br /><img border="0" alt="alt" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhf9sVviIZ7Jog9qZA9YlAzzVCm37R0VZQDtEdE2cuEtxkQvNyPVD12-vwwHpVu8MzV-iYVXWMb-Dn_jKkGMIaaacy1Z5SnpW9LIGBhpNcL7l7VhrkaUsDxzaj40NS2LWenRYf4_740i6Od/s640/guest-chrome-4-rss-support.png" width="400" height="193" /> <br /></p> <p>5. You can't send a web page by email</p> <p>While other popular browsers allow you to quickly send any web page you're viewing by email, such an option is nowhere to be found in Google Chrome. <br />Worry not, because you can create <a href="http://www.tech-recipes.com/rx/3024/google_chrome_add_send_link_button_to_bookmarks_bar/">a simple Javascript bookmarklet</a> to open your default email program with the current URL. If Gmail is what you use, you can alternatively install the <a href="https://chrome.google.com/extensions/detail/pgphcomnlaojlmmcjmiddhdapjpbgeoc">Send from Gmail</a> extension to send the web page to Gmail. <br /></p> <p>6. No session manger</p> <p>Closing Google Chrome and reopening it does not restore previously opened tabs. In order to do that, go to the Options dialog and enable Reopen tabs that were open last. <br />If you want advanced session saving options like the ability to create multiple sessions, try the <a href="https://chrome.google.com/extensions/detail/edacconmaakjimmfgnblocblbcdcpbko">Session Buddy</a> addon for Google Chrome.</p> <p>7. You can't switch to a tab from the Omnibox</p> <p>Firefox 4 lets you switch to any open tab by typing relevant words into the address bar. If you'd like to see a similar feature in Chrome, install the<a href="https://chrome.google.com/extensions/detail/gbfhhcljihbgcobpfnceegfmooomhhli">Switch To Tab</a> extension. <br />The next time you have too many open tabs, just type sw followed by some words from the page. Hitting Enter switches to the tab that's listed as the first match. <br /><img border="0" alt="alt" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijWusnveANXxnwuu7zIg7J-J-gD02r5Dmum4IxcD_tIfZZvBsevnadsAOj0Arc4aiC9tWmRaVP4bvk-pki8Xi_nPv_hYOErPbUzgYeajS_OLeWfhX5YK9G-hjHoiBZXU4LkXYHuC4GXOFo/s640/guest-chrome-7-switch-to-tab.png" width="400" height="133" /> <br /></p> <p>And as a bonus, on You Tube you can not set you’re preferred stream to HD.  Get the <a href="https://chrome.google.com/webstore/detail/kaielpkecabnggniojjhghggjedkecfj#">Auto HD for YouTube</a></p> <p>Enjoy.</p> D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com1tag:blogger.com,1999:blog-7113888591536837437.post-54666624658427721762011-02-12T10:26:00.001-08:002011-02-12T13:12:36.890-08:00Reviewing ReactiveUI<p>I am reviewing the <a href="https://github.com/xpaulbettsx/reactiveui">ReactiveUI</a> code now and I have to say it’s some of the coolest code I’ve seen in a while!</p> <p>I really like the base ReactiveValidatedObject class for building ViewModels.  The view models become so much easier for validation and INotifyPropertyChanged:</p> <pre class="code"><span style="color: blue">string </span>_Name;<br />[<span style="color: #2b91af">Required</span>]<br />[<span style="color: #2b91af">StringLength</span>(35, MinimumLength = 3, ErrorMessage = <span style="color: #a31515">"Names have to be between 3 and 35 letters long"</span>)]<br /><span style="color: blue">public string </span>Name {<br /> <span style="color: blue">get </span>{ <span style="color: blue">return </span>_Name; }<br /> <span style="color: blue">set </span>{ _Name = <span style="color: blue">this</span>.RaiseAndSetIfChanged(x => x.Name, <span style="color: blue">value</span>); }<br />}</pre><br /><br /><p>The MemoizingMRUCache class looks very handy and I also like how the logging is accomplished.</p><br /><br /><p>The sample that comes with it has great comments and I learned more about MEF in the process.</p><br /><br /><p>It has a Ruby feel to with with a rake build script.</p><br /><br /><p>I have so much more to review. </p> D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com1tag:blogger.com,1999:blog-7113888591536837437.post-11829309620551743902011-02-04T03:36:00.000-08:002011-02-04T03:36:22.485-08:00we hatez your browser or how not to design web sites in 2011!While visiting the www.MVA.Maryland.gov website I discovered the following message:<br />
<br />
<span class="Apple-style-span" style="font-family: Arial, Verdana;"><strong>The eMVA store is not available to Google Chrome users. Please use another browser.</strong></span><br />
<span class="Apple-style-span" style="font-family: Arial, Verdana;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: Arial, Verdana;">In the words of Jar Jar... "how rude"</span>D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com0tag:blogger.com,1999:blog-7113888591536837437.post-82336763516925330142010-11-22T15:33:00.001-08:002010-11-22T15:33:49.554-08:00Cheating at Bejeweled Blitz on FacebookMy new bot is complete and is scoring greater than 800k.<br />
<br />
Check it out at <a href="http://cheatatbejeweledblitz.com/">http://cheatatbejeweledblitz.com/</a>D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com0tag:blogger.com,1999:blog-7113888591536837437.post-27323865955882621572010-10-21T05:24:00.000-07:002010-10-21T05:24:44.648-07:00Your Android may one day be infected at it's coreLast night's BaltoMSDN presentation by Mike Wolf was on Windows Phone 7 development. When I heard that all apps would need to be certified by Microsoft, I thought, "Oh, No. Here we go with the oppressive oversight". But after a little surfing this morning regarding mobile OS's and security I came across this white paper describing how the entire Android OS could be infected with Ad/Malware.<br />
<br />
<a href="http://appanalysis.org/tdroid10.pdf">http://appanalysis.org/tdroid10.pdf</a><br />
<br />
Let's hope Microsoft get's security right on the WP7 but is not as oppressive as Apple in app certification.D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com0tag:blogger.com,1999:blog-7113888591536837437.post-76519392555224447682010-10-10T18:25:00.001-07:002010-10-10T18:26:50.920-07:00HTML5 CanvasI thought it was time to start learning some HTML5 so I dove into the Canvas element. <br />
<br />
<a href="http://amazonfoobar.s3.amazonaws.com/HTML5/canvas.html">View it here</a>D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com0tag:blogger.com,1999:blog-7113888591536837437.post-71141261731615432332010-08-13T13:42:00.000-07:002010-08-13T14:11:49.583-07:00Node.js can't use multiple CPU/CoresI just install Ubuntu 10.04 and got <a href="http://nodejs.org/">Node.js</a> up and running.<br />
<br />
It's scary how easy it is to create a highly scalable web / socket application.<br />
<br />
Don't get too excited yet. The gurus at Yahoo had this to say:<br />
<br />
<i>But all is not sunshine and lollipops in NodeJS land. While single-process performance is quite good, eventually one CPU is not going to be enough; the platform provides no ability to scale out to take advantage of the multiple cores commonly present in today's server-class hardware. With current NodeJS builds, the practical limits of a single CPU acting as an HTTP proxy are around 2100 reqs/s for a 2.5GHz Intel Xeon.</i><br />
<i><br />
While Node is relatively solid, it does still crash occasionally, adversely impacting availability if you're running only a single NodeJS process. Such problems can be particularly common when using a buggy compiled add-on that can suffer from the usual cornucopia of C++ goodies such as segfaults and memory scribbling. When handling requests with multiple processes, one processing going down will simply result in incoming requests being directed at the other processes.<br />
</i><br />
<br />
And lastly, Alex Payne sums up what large scalability and why node.js might just remain the realm of the less than skilled programmers.<br />
<br />
<a href="http://al3x.net/2010/07/27/node.html">http://al3x.net/2010/07/27/node.html</a><br />
<br />
Threads are not dead!<br />
<br />
This looks interesting for javascript : <a href="http://documentcloud.github.com/underscore/">http://documentcloud.github.com/underscore/</a>D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com0tag:blogger.com,1999:blog-7113888591536837437.post-52299350122731226672010-05-01T05:09:00.001-07:002010-05-01T05:09:25.760-07:00CQRS and User Interface Design<p>I am beginning to have a shift in thinking about user interface design as I study the CQRS architectural pattern. The pattern really forces you to think about design UI’s around tasks.</p> <p>You have to ask yourself, “Why would a user want to change the state of the system?”</p> <p>Why would the user want to change the address of a customer?  Was it a mistake?  Did they move?  These might be important to know.  If they made a mistake and they have pending orders about to ship it might imply very different business rules.</p> <p>It also forces you to think about the experience from the user’s perspective.</p> <p>Udi Dahan said it perfectly during one of his talks: "User Interface design is as much a part of architecture as anything else that you do"</p> D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com0tag:blogger.com,1999:blog-7113888591536837437.post-44065537874053709162009-07-22T13:40:00.000-07:002009-07-22T13:42:24.588-07:00Google Hates Internet Explorer<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_4hw5ZShkMy8/Smd5n6zY15I/AAAAAAAACXM/aaDe8HY5eFU/s1600-h/GoogleVsFireFox.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 66px;" src="http://1.bp.blogspot.com/_4hw5ZShkMy8/Smd5n6zY15I/AAAAAAAACXM/aaDe8HY5eFU/s200/GoogleVsFireFox.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5361387608114517906" /></a><br />Just went to look something up and was using IE. Google is advertising Chrome in IE but not FireFox.D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com0tag:blogger.com,1999:blog-7113888591536837437.post-17622538396708691812008-08-30T06:09:00.001-07:002008-08-30T06:11:17.135-07:00Open Source Code Review - A choice to name a method "Inscrutable"?<div class="csharpcode">I've been reviewing various open source projects related to Amazon S3 and discovered the excellent <a href="http://www.codeplex.com/resourceful">Resourceful</a> library and the related project <a href="http://www.codeplex.com/spaceblock">SpaceBlock</a>.  The following code is a utility class in the SpaceBlock project.  </div> <div class="csharpcode"> </div> <div class="csharpcode">The method I found offensive was named <a href="http://www.codeplex.com/spaceblock/SourceControl/FileView.aspx?itemId=90714&changeSetId=11381">"Inscrutable" and is located in the class named F</a>.  The definition of "<a href="http://dictionary.reference.com/search?q=inscrutable">Inscrutable</a>" from dictionary.com is "incapable of being investigated, analyzed, or scrutinized; impenetrable."  This reminds me of a quote I heard 25 years ago from an old mainframe programmer at Westinghouse.  I was complaining about the understandability of his VMS code and he said "If it was hard to write, it should be hard to understand".  I couldn't have disagreed with him more.  I believe in intellectual manageability of the code you write.  You don't write code for yourself or the compiler.  You write it for other people.  By naming a function "Inscrutable" you are flipping me and everyone else the bird!  </div> <div class="csharpcode"> </div> <div class="csharpcode">I guarantee this will happen to you one day (if it has not already).  You will be reviewing your own code for a bug fix and discover a particularly tricky piece of code that you didn't comment or name your function properly.  If you were so arrogant as to name your method "YouAreTooStupidToUnderstandHowThisWorksSoDontEvenTry" you will be essentially flipping yourself the bird!  You will then end up spending way too much time figuring out and reflecting on exactly you were thinking when you wrote that code.</div> <div class="csharpcode"> </div> <div class="csharpcode">Now, I'm not saying I'm not guilty of doing similar complexities with my code.  In fact, I can hear my co-workers now shouting over the cubical walls "Hey, isn't that the pot calling the kettle black".  I'm posting this as a reminder to myself and all developers to never do something this blatant and egotistic as this in our code.</div> <div class="csharpcode"> </div> <div class="csharpcode">I am not slamming these projects. I think they are well written and have a great coding style. I plan to use them in the future.</div> <div class="csharpcode"> </div> <div class="csharpcode"></div> <style type="text/css"><br />.csharpcode, .csharpcode pre<br />{<br /> font-size: small;<br /> color: black;<br /> font-family: consolas, "Courier New", courier, monospace;<br /> background-color: #ffffff;<br /> /*white-space: pre;*/<br />}<br />.csharpcode pre { margin: 0em; }<br />.csharpcode .rem { color: #008000; }<br />.csharpcode .kwrd { color: #0000ff; }<br />.csharpcode .str { color: #006080; }<br />.csharpcode .op { color: #0000c0; }<br />.csharpcode .preproc { color: #cc6633; }<br />.csharpcode .asp { background-color: #ffff00; }<br />.csharpcode .html { color: #800000; }<br />.csharpcode .attr { color: #ff0000; }<br />.csharpcode .alt <br />{<br /> background-color: #f4f4f4;<br /> width: 100%;<br /> margin: 0em;<br />}<br />.csharpcode .lnum { color: #606060; }</style> D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com3tag:blogger.com,1999:blog-7113888591536837437.post-21994475838428504792008-08-30T05:14:00.001-07:002008-08-30T05:14:22.753-07:00C# 4.0: Meet the Design Team<p></p> <p>Anders and crew meet in the room where C# was birthed and talk about the future.</p> <p><iframe src="http://channel9.msdn.com/posts/Charles/409364/player/" frameborder="0" width="320" scrolling="no" height="325"></iframe> <br /><a href="http://channel9.msdn.com/posts/Charles/C-40-Meet-the-Design-Team/">C# 4.0: Meet the Design Team</a></p> D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com0tag:blogger.com,1999:blog-7113888591536837437.post-78370759292328297892008-05-07T11:08:00.001-07:002008-05-07T11:08:28.348-07:00Edward Tufte One Day Seminar<p>Yesterday I attended a one day seminar in Arlington, VA presented by <a href="http://www.edwardtufte.com/tufte/">Edward Tufte</a>. </p> <p>It was a great presentation and I picked up all four of his books.</p> <p> quotes and general notes:</p> <p>Great designs are transparent</p> <p>Never segregate data by the mode of production.</p> <p>Show all the data, it provides credibility.</p> <p>We should be concerned with the quality of thought.</p> <p>Don't use lowest common denominator design or you will have an intellectual disaster.</p> <p>Tables out perform graphs for data less than 1000 points.</p> <p>Screens should be 95% content and 5% administrative debris (scrollbars, toolbars, etc.).  Measure it.</p> <p>Design the surface first.  Outside-In design.  iPhone designed the hardware platform before the software.  iPhone has one of the highest DPI of any consumer device.</p> <p>Don't provide an application solution.</p> <p>Leave the UI alone once it's done.</p> <p>There is no relationship between the amount of information and the ability to process.  The human eye can process 10mbit/sec.</p> <p>Don't be an original.  Steal a good design.</p> <p>Consider a "super graph".  It unifies and relates the audience to the data or theme.</p> <p>Increase information throughput</p> <p>Examine how newspapers report data and clone it. Examine "Nature" magazine.</p> <p>Multivariant problems are the only interesting problems.</p> <p>Progress in technology is measured in resolution</p> <p>Don't use legends on graphs.  Put the text on the line.</p> <p>Maximize content reasoning and minimize decoding</p> <p>"We want to be approximately right rather than absolutely wrong"</p> <p>Use <a href="http://www.fonts.com/findfonts/detail.htm?pid=427675&gclid=CIu-wbb8lJMCFQ4yGgodyVlCgw">Gill Sans Font</a></p> <p>Annotate everything</p> <h4>about presentations</h4> <ul> <li>Show up early for your own presentation to meet people, to show a gracious gesture, and to hand out materials early.</li> <li>Use presentations as a review of the material distributed prior to the meeting.  Maybe simply ask "Are there any questions?" and end the meeting.</li> <li>Use Power Point as a projector operating system</li> <li>Give out handouts before meeting - people can read 2x-4x times faster than you can talk.</li> <li>What is the problem?</li> <li>Who cares? the relevance</li> <li>The solution</li> <li>Have a summary</li> <li>Say you will answer questions when they are done reading</li> <li>Use sentences.  No laundry lists of nouns.  Sentences for you to think causally.</li> <li>Don't use bullet reveals.</li> <li>Practice in front of a friend or a video camera</li> <li>Turn off the video and listen to the audio</li> <li>Ask a trusted friend for criticisim</li> <li>Never begin with an all purpose joke</li> <li>Never apologize at the start of the presentation</li> <li>Stay out of the first person during the introduction</li> <li>Stay on content</li> <li>Finish early </li> </ul> D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com1tag:blogger.com,1999:blog-7113888591536837437.post-47249602279077594282008-04-16T07:35:00.001-07:002008-04-16T07:35:47.582-07:00Patterns and Practices releases Unity 1.0<p>How did I miss this?</p> <p><a title="http://www.codeplex.com/unity" href="http://www.codeplex.com/unity">http://www.codeplex.com/unity</a></p> D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com0tag:blogger.com,1999:blog-7113888591536837437.post-87172783953984608732008-04-16T07:32:00.001-07:002008-04-16T07:32:57.525-07:00He's worse than dead!<p></p> <embed src="http://www.youtube.com/v/qJQwHwP0ojI&rel=0" width="425" height="355" type="application/x-shockwave-flash" wmode="transparent" /> D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com0tag:blogger.com,1999:blog-7113888591536837437.post-55647737912378313882008-03-26T05:39:00.001-07:002008-03-26T05:39:57.552-07:00Quote of the day<div id="banner"><q>Good judgement is the result of experience ... Experience is the result of bad judgement.</q> — <author>Fred Brooks</author> </div>D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com0tag:blogger.com,1999:blog-7113888591536837437.post-77624674374457397082008-01-30T07:28:00.000-08:002008-01-30T07:30:18.152-08:00Playing with the .NET FCL symbols and source code<p class="MsoNormal">I’m playing with the debug symbols for the .NET framework and came across some interesting things in code.<o:p></o:p></p> <p class="MsoNormal">Dropping back to memory manipulation for performance from the String class<o:p></o:p></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas;"><span style=""> </span><span style="color: green;">// Returns the entire string as an array of characters. <o:p></o:p></span></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas;"><span style=""> </span><span style="color: blue;">unsafe</span> <span style="color: blue;">public</span> <span style="color: blue;">char</span>[] ToCharArray() {<o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas;"><span style=""> </span><span style="color: green;">// <strip> huge performance improvement for short strings by doing this </strip> <o:p></o:p></span></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas;"><span style=""> </span><span style="color: blue;">int</span> length = Length;<o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas;"><span style=""> </span><span style="color: blue;">char</span>[] chars = <span style="color: blue;">new</span> <span style="color: blue;">char</span>[length];<o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas;"><span style=""> </span><span style="color: blue;">if</span> (length > 0)<o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas;"><span style=""> </span>{ <o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas;"><span style=""> </span><span style="color: blue;">fixed</span> (<span style="color: blue;">char</span>* src = &<span style="color: blue;">this</span>.m_firstChar)<o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas;"><span style=""> </span><span style="color: blue;">fixed</span> (<span style="color: blue;">char</span>* dest = chars) <o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas;"><span style=""> </span>wstrcpyPtrAligned(dest, src, length); <o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas;"><span style=""> </span>}<o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas;"><span style=""> </span><span style="color: blue;">return</span> chars; <o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas;"><span style=""> </span>}<o:p></o:p></span></p><p class="MsoNormal">AMD Specific code!<o:p></o:p></p><p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas; color: blue;">#if</span><span style="font-size: 12pt; font-family: Consolas;"> AMD64 <o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas; color: gray;"><span style=""> </span>// for AMD64 bit platform we unroll by 12 and<o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas; color: gray;"><span style=""> </span>// check 3 qword at a time. This is less code <o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas; color: gray;"><span style=""> </span><span style=""> </span>// than the 32 bit case and is shorter<o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas; color: gray;"><span style=""> </span>// pathlength<o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas; color: gray;"><o:p> </o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas; color: gray;"><span style=""> </span>while (length >= 12) <o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas; color: gray;"><span style=""> </span>{<o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas; color: gray;"><span style=""> </span>if (*(long*)a<span style=""> </span>!= *(long*)b) break; <o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas; color: gray;"><span style=""> </span>if (*(long*)(a+4) != *(long*)(b+4)) break; <o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas; color: gray;"><span style=""> </span>if (*(long*)(a+8) != *(long*)(b+8)) break;<o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas; color: gray;"><span style=""> </span>a += 12; b += 12; length -= 12; <o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas; color: gray;"><span style=""> </span>}<o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas; color: blue;">#else<o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas;"><span style=""> </span><span style="color: blue;">while</span> (length >= 10)<o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas;"><span style=""> </span>{ <o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas;"><span style=""> </span><span style="color: blue;">if</span> (*(<span style="color: blue;">int</span>*)a != *(<span style="color: blue;">int</span>*)b) <span style="color: blue;">break</span>;<o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas;"><span style=""> </span><span style="color: blue;">if</span> (*(<span style="color: blue;">int</span>*)(a+2) != *(<span style="color: blue;">int</span>*)(b+2)) <span style="color: blue;">break</span>; <o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas;"><span style=""> </span><span style="color: blue;">if</span> (*(<span style="color: blue;">int</span>*)(a+4) != *(<span style="color: blue;">int</span>*)(b+4)) <span style="color: blue;">break</span>; <o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas;"><span style=""> </span><span style="color: blue;">if</span> (*(<span style="color: blue;">int</span>*)(a+6) != *(<span style="color: blue;">int</span>*)(b+6)) <span style="color: blue;">break</span>;<o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas;"><span style=""> </span><span style="color: blue;">if</span> (*(<span style="color: blue;">int</span>*)(a+8) != *(<span style="color: blue;">int</span>*)(b+8)) <span style="color: blue;">break</span>; <o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas;"><span style=""> </span><span style=""> </span>a += 10; b += 10; length -= 10;<o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas;"><span style=""> </span>}<o:p></o:p></span></p> <p class="MsoNormal" style=""><span style="font-size: 12pt; font-family: Consolas; color: blue;">#endif<o:p></o:p></span></p> <p class="MsoNormal"><o:p> </o:p></p> <p class="MsoNormal"><o:p> </o:p></p>D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com1tag:blogger.com,1999:blog-7113888591536837437.post-53672768924716137202007-12-14T12:23:00.000-08:002007-12-14T12:25:40.396-08:00DBPro for unit testing - PITADBPro for unit testing has been a PITA for the following reasons:<br /><br />1. Roll back of initial test state is difficult<br /><br />There is no easy way to begin a transaction in the setup and rollback in the tear down without modifying the generated code to use transaction scope. The setup/tear down methods cannot be used because they run on a separate connection than the test is executed. This is important for security testing but not all that applicable to the work that we perform. I don’t think it’s reasonable for the tear down methods to have to reverse all the work of the test setup methods. Database rollback is the appropriate approach. Therefore, we have reverted to not using anything but the body of the test.<br /><br />2. Inability to share T-SQL code to setup common state across tests<br /><br />This is forcing us write T-SQL setup code that is duplicated across multiple tests or we resort to putting all the testing for a given state into single test. These tests are then testing a single unit (stored proc, trigger, view, etc.) but are testing multiple conditions. If the first condition fails, all subsequent tests will not execute. Also, using state that was modified by a previous test can be very problematic and creates interdependencies between tests.<br /><br />3. Test designer for specifying test conditions is difficult<br /><br />The point/click interface for editing many test conditions becomes laborious for large numbers of result sets and columns. Managing inline T-SQL with RAISERROR statements is easier and allows a script to be reviewed without the designer surface.<br /><br />4. T-SQL test editing designer is not friendly for debugging your test<br /><br />Most people find that using SQL Management Studio to write/debug your unit tests is easier. In order to use SMS you must copy-paste your code in and out of the DBPro test designer. This process is error prone and laborious.<br /><br />5. DBPro is slow at executing tests<br /><br />6. Data Generation Plans are not useful<br /><br />I may be wrong but I don’t find the Data Plan Generation facility very useful for most unit tests. I see how it would be useful for performance or load testing but these types of tests are much higher level.<br /><br />7. Integrating the DBPro tests into the build process is not easy<br /><br />This has not been attempted yet but it does not appear on the surface to be easy.D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com0tag:blogger.com,1999:blog-7113888591536837437.post-56334267654804442202007-11-30T09:40:00.000-08:002007-11-30T09:41:53.966-08:00ObjectBuilder Documentation is incorrect.The following is the default Object Builder Pipeline Stages:<br /><br />PreCreation<br /> Microsoft.Practices.ObjectBuilder.TypeMappingStrategy<br /> Microsoft.Practices.ObjectBuilder.SingletonStrategy<br /> Microsoft.Practices.ObjectBuilder.ConstructorReflectionStrategy<br /> Microsoft.Practices.ObjectBuilder.PropertyReflectionStrategy<br /> Microsoft.Practices.ObjectBuilder.MethodReflectionStrategy<br /><br />Creation<br /> Microsoft.Practices.ObjectBuilder.CreationStrategy<br /><br />Initialization<br /> Microsoft.Practices.ObjectBuilder.PropertySetterStrategy<br /> Microsoft.Practices.ObjectBuilder.MethodExecutionStrategy<br /><br />PostInitialization<br /> Microsoft.Practices.ObjectBuilder.BuilderAwareStrategyD. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com0tag:blogger.com,1999:blog-7113888591536837437.post-23467535147842807102007-11-25T17:39:00.000-08:002007-11-25T18:01:48.837-08:00My Digital Picture Frame project (DPF)<p>I considered purchasing one of these cool toys but had high requirements for it.<br /></p><ol><br /><li>WiFi</li><br /><li>Support Pictures via RSS with local storage media as fall back.</li><br /><li>Remote Administration</li><br /><li>Re-chargeable battery</li><br /><li>Options for wood frames</li><br /></ol><br />Of course the few that actually fit these most were > $500 up to $1000. There was only one that supported RSS.<br /><br />So I used an old Tecra 8100 laptop and set out this long holiday weekend to build my own. I purchased a frame and shadowbox at Micheal's craft store at a total cost of $22.<br /><br />Three hours later I had produced this:<br /><br /><a href="http://picasaweb.google.com/lindell.mark/DMarkLindell/photo?authkey=c-slMoxvKFU#5136957495729579234"><img src="http://lh4.google.com/lindell.mark/R0ojoCc95OI/AAAAAAAAAwc/m8d8OoXiQFM/s400/DSCN0484.JPG" /></a><br /><a href="http://picasaweb.google.com/lindell.mark/DMarkLindell/photo?authkey=c-slMoxvKFU#5136957512909448434"><img src="http://lh4.google.com/lindell.mark/R0ojpCc95PI/AAAAAAAAAwk/ahG5l6YcFrQ/s400/DSCN0486.JPG" /></a><br /><br />The laptop already had windows XP loaded on it so it was just a matter of:<br /><ul><li><a href="http://support.microsoft.com/kb/315231">Setting windows to automatically login</a></li><br /><li>Loading the <a href="http://pack.google.com/screensaver.html">google screen saver</a> which supports local media as well as RSS feeds.</li><br /><li>Loading up <a href="http://www.tightvnc.com/">TightVNC</a> for remote administration</li><br /><li>Adding <a href="http://www.nirsoft.net/utils/nircmd.html">nircmd.exe screensaver</a> as a startup item.<br /></li></ul>When I unplug the laptop and it will run for an hour or so and then go into standby mode. luckily, (this particular laptop) when you plug it back it it comes right back on and begins charging again.<br /><br />I decided I had better leave the back panel of the shadowbox to allow air flow. The laptop does get a little bit warm.<br /><br />I hope this inspires you to build your own DPF!D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com1tag:blogger.com,1999:blog-7113888591536837437.post-69966311908783834132007-11-21T13:59:00.000-08:002007-11-21T14:00:02.363-08:00Effective Code Reviews... the next steps.I've been giving a lot of thought as to how to move closer toward pair programming within our development organization. Code reviews today are somewhat effective but tend to take a back seat when the pressure is on to make schedules to release code. e.g. The urgent always wins over the important. (Stephen Covey)<br /><br />So developers and managers under pressure will delaying code reviews until after the release. That's just a stall tactic as sometimes that occurs and sometimes it doesn't. Either way, it's POINTLESS! The further in time you are away from when the code was written the more chance you have of making a breaking change. (ignoring unit test coverage and unit test quality)<br /><br />Most code reviews reveal code that can be improved but is not incorrect. These types of changes should never be made on released code! Sometimes it's even worse in that the code requires design changes that we glossed over during the design phase but we obvious design concerns now that the code is complete.<br /><br />Perhaps the best approach to shortening the time between when the code is written to when the code is reviewed is to enforce check-in policies. This would require at least another developer to review code changes before it could be committed to the source code repository.<br /><br />I have noticed that TFS contains a field to indicate that the code was reviewed. I imagine a combination of shelving and using this flag with policies in place could begin to move code reviews more into the daily coding work flow rather than waiting until there is no time at the end of the schedule.<br /><br />Another possibility to get closer to pair programming is to all developers be requires to spend one hour each day reviewing (hence pairing) on another developers work for the day.<br /><br />I just don't think the culture shift to pair programming is going to be something that is ever dropped into an existing organization. We need to find methods to introduce it in small doses in order to succeed.<br /><br />As Einstein once said, "Insanity is doing the same thing over and over again and expecting different results."D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com0tag:blogger.com,1999:blog-7113888591536837437.post-1119776418949074182007-10-28T06:29:00.001-07:002007-10-28T06:56:01.882-07:00Presenter communication with the view - events or direct communication.I just started reading <a href="http://codebetter.com/blogs/jeremy.miller/default.aspx">Jeremy Miller</a>'s excellent blog post series on <a href="http://codebetter.com/blogs/jeremy.miller/archive/2007/07/25/the-build-your-own-cab-series-table-of-contents.aspx">Build your own CAB series</a>. I'm currently up to his 6th post on "<a href="http://codebetter.com/blogs/jeremy.miller/archive/2007/06/04/build-your-own-cab-part-6-view-to-presenter-communication.aspx">View to Presenter Communication</a>" and found the discussion of using events vs. callbacks on the presenter very interesting and relevant to my current work.<br /><br />Let me share a recent experience...<br /><br />I've been using events from my view to communicate with the presenter and ran across a bug that was related to using event inadvertently. While working one day, I accidentally pressed Ctrl-L and duplicated a line in my presenter constructor. The line I duplicated was a hook of a view event. This caused my presenter event delegate to be called twice.<br /><br />I found out later that my unit tests for the presenter were correctly checking that I wired all the view events but they were not checking that the events were only wired once. All my integration testing was in debug mode! Then ran the application in release mode. BOOM!<br /><br />It turns out the events fired in a different order under release mode and caused a null reference exception with a state change in the model.<br /><br />If the purpose of events is to allow multiple listeners, when would I ever design the use of a single event to communicate multiple methods in the presenter?<br /><br />Perhaps I would but that appears to be more of an edge case and not very good design. It would lead me back towards a design where events don't communicate specifics but something more abstract as the 'SomethingChanged' event.<br /><br />Would I ever have multiple presenters for the same view? Never.<br /><br />So is using events a good design principle to create loose coupling? Yes, but only if you require multiple listeners. If you don't, are you over engineering the solution? Perhaps.<br /><br />Now when it comes to the model, events are essential! I have multiple presenters listening to model objects!<br /><br />I've also been fighting memory leaks due to the use events on my model objects. My model has certain objects that can be retrieved from cache and exist for the life of the process. When my presenter hooks these events, it was causing my presenter to not unload when the view was destroyed. This cause me to have to disconnect my model events from the model objects when the presenter was disposed. This also required me to dispose my presenter when the code that first created the presenter fell out of scope.<br /><br />On a side note, I found the memory leak using <a href="http://memprofiler.com/?gclid=CM3v_tvcsY8CFRGoGgod3ne7SQ">SciTech's excellent memory profiler</a>. If you are creating WinForm applications, I suggest you download it and try it against your application. You might be surprised to find you have memory leaks in your applications. It also has an API so you can build integration or unit tests to check for memory leaks.<br /><br /><br /><br /><br /><br /><br /><br /><h1 class="CommonTitle"><a href="http://codebetter.com/blogs/jeremy.miller/default.aspx"><br /></a></h1>D. Mark Lindellhttp://www.blogger.com/profile/06102973229672434002noreply@blogger.com0