<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Yet Another Coding Blog : api</title><link>http://blogs.msdn.com/avip/archive/tags/api/default.aspx</link><description>Tags: api</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>On using Arrays</title><link>http://blogs.msdn.com/avip/archive/2008/09/23/on-using-arrays.aspx</link><pubDate>Tue, 23 Sep 2008 03:52:32 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8961772</guid><dc:creator>Avi Pilosof</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/avip/comments/8961772.aspx</comments><wfw:commentRss>http://blogs.msdn.com/avip/commentrss.aspx?PostID=8961772</wfw:commentRss><wfw:comment>http://blogs.msdn.com/avip/rsscomments.aspx?PostID=8961772</wfw:comment><description>&lt;p&gt;Eric Lippert has a great article on arrays:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://blogs.msdn.com/ericlippert/archive/2008/09/22/arrays-considered-somewhat-harmful.aspx" href="http://blogs.msdn.com/ericlippert/archive/2008/09/22/arrays-considered-somewhat-harmful.aspx"&gt;http://blogs.msdn.com/ericlippert/archive/2008/09/22/arrays-considered-somewhat-harmful.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;I think this is especially useful to consider if you’re writing an API. Consider not just arrays, but any time you’re returning any collection: Are you returning &lt;em&gt;values&lt;/em&gt; or a &lt;em&gt;variables&lt;/em&gt;? Did you mean to?&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Avi&lt;/p&gt;  &lt;p&gt;&lt;!-- AddThis Button BEGIN --&gt;
&lt;a href="http://www.addthis.com/bookmark.php" onclick="window.open('http://www.addthis.com/bookmark.php?wt=nw&amp;pub=avip&amp;url='+encodeURIComponent(location.href)+'&amp;title='+encodeURIComponent(document.title), 'addthis', 'scrollbars=yes,menubar=no,width=620,height=520,resizable=yes,toolbar=no,location=no,status=no,screenX=200,screenY=100,left=200,top=100'); return false;" title="Bookmark and Share" target="_blank"&gt;&lt;img src="http://s9.addthis.com/button1-share.gif" wid&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8961772" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/avip/archive/tags/api/default.aspx">api</category><category domain="http://blogs.msdn.com/avip/archive/tags/architecture/default.aspx">architecture</category><category domain="http://blogs.msdn.com/avip/archive/tags/programming/default.aspx">programming</category></item><item><title>On Writing Safer APIs</title><link>http://blogs.msdn.com/avip/archive/2008/06/19/on-writing-safer-apis.aspx</link><pubDate>Thu, 19 Jun 2008 05:08:57 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8619813</guid><dc:creator>Avi Pilosof</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/avip/comments/8619813.aspx</comments><wfw:commentRss>http://blogs.msdn.com/avip/commentrss.aspx?PostID=8619813</wfw:commentRss><wfw:comment>http://blogs.msdn.com/avip/rsscomments.aspx?PostID=8619813</wfw:comment><description>&lt;p&gt;Our team owns lots of smallish applications; all of them have a DB layer, an OM/API layer, logic and UI layers. What happens over time is that we have different people working on the same apps, switching between them over the course of time.&lt;/p&gt; &lt;p&gt;This is great for cross-training, for support, for finding missed bugs, for preventing boredom-induced suicides, etc. However, the price you pay is losing that intense expert focus that someone gets from living+breathing a single app for years. That can lead to a few more bugs.&lt;/p&gt; &lt;p&gt;I've noticed that at the core of many of these bugs is the OM/API layer, and I wanted to summarize some issues I've seen and some suggested fixes. I'd also love to hear any other pointers you guys have.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;u&gt;Problem 1: Database call abuse.&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;We take great pride in squeezing the most out of our database servers. One of the primary ways to do this is to hand-code your DB access via sprocs and ensure that they return multiple result sets where possible. So for example, if I know that the main build status page needs to show builds &lt;em&gt;and &lt;/em&gt;their comments &lt;em&gt;and &lt;/em&gt;their last 15 status events, then I'll make sure that one sproc call returns &lt;em&gt;all &lt;/em&gt;of those for &lt;em&gt;all &lt;/em&gt;the builds - optimize for reducing the number of DB round trips. BTW, you can do this with LINQ-to-SQL.&lt;/p&gt; &lt;p&gt;However, this generally conflicts with writing a "neat" OM which performs simple concise tasks; and is often people's &lt;a title="(I disagree with this guy, FWIW. There are ways to cater for this in good ORMs)" href="http://database-programmer.blogspot.com/2008/06/why-i-do-not-use-orm.html"&gt;resistance to using ORMs&lt;/a&gt;. You need to learn how to balance the two.&lt;/p&gt; &lt;p&gt;Invariably, you'll eventually realize that some page is relying on some call which relies on a deep OM call which makes a sproc call. But that parent page makes the call 300 times; one for each item... Ouch.&lt;/p&gt; &lt;p&gt;Some solutions:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;ABP: Always Be Profiling&lt;/strong&gt;. This simple and brilliant idea comes courtesy of my teammates &lt;a href="http://blogs.msdn.com/jasonward/"&gt;Jason&lt;/a&gt; and &lt;a href="http://blogs.msdn.com/karthik/"&gt;Karthik&lt;/a&gt;. Basically, as you're fixing bugs on an app, have the SQL Profiler running on your 2nd monitor and watch out for crazy spikes in traffic coming from your app.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Caching&lt;/strong&gt;: When possible/applicable, cache the results of your DB calls at the lowest level that makes sense. You can cache for the whole lifetime of the app, for the session, for the context, or using a custom caching policy with the caching object. The point is; ask yourself whether you really need to read that stuff from the DB.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Commenting&lt;/strong&gt;: One of my favourite VS features is that the "/// &amp;lt;summary&amp;gt;" comments show up as intellisense hints. This means that as your API consumer (your team-mate!) is using the method call, they get free documentation. So, if the method being called doesn't cache, call it out. It'll cost you 20 seconds:&lt;/p&gt; &lt;div&gt; &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// Get the comments for a build.&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// NO CACHING - this always makes a DB call.&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;u&gt;Problem 2: Units of measurement&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This might seem obvious/stupid, but I bet it happens to &lt;a title="NASA's metric confusion caused Mars orbiter loss" href="http://www.cnn.com/TECH/space/9909/30/mars.metric/"&gt;the best of us&lt;/a&gt;. Take a look at this call:&lt;/p&gt;
&lt;div&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; BuildSize = build.Size;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;"Size", eh? Bytes? Megabytes? Gigabytes?&lt;/p&gt;
&lt;p&gt;Some solutions:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Naming&lt;/strong&gt;: If you suffix your properties/methods with the units they return, this is unlikely to happen. &lt;em&gt;SizeInBytes&lt;/em&gt;, &lt;em&gt;SizeInGB&lt;/em&gt;, etc. Really cheap.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Typing&lt;/strong&gt;: Rather than &lt;em&gt;Size&lt;/em&gt; being of type &lt;em&gt;int&lt;/em&gt;, have it be of type "Gigabyte", which you can create yourself. The type system will then ensure you don't make silly mistakes. This can be a little more costly if you do it pervasively, but it's quite powerful and allows for centralizing your unit conversions (are there 1000 MB in a GB, or 1024?).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Commenting&lt;/strong&gt;: Again with the summary comments. Check it out:&lt;/p&gt;
&lt;div&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// Get the size of the build, in BYTES.&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;So cheap.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;u&gt;Problem 3: Discoverability&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I'm new to this application and I want to find the size of the build. My instinct is to look for &lt;em&gt;build.Size&lt;/em&gt; (sorry, &lt;em&gt;SizeInGB&lt;/em&gt;! :)), but I don't see it. So I go off and write it, to later find out that there already was a &lt;em&gt;build.GetSize()&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Some suggestions:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Properties vs. Methods&lt;/strong&gt;: Some people would deliberately use the &lt;em&gt;GetSize()&lt;/em&gt; method rather than the &lt;em&gt;Size&lt;/em&gt; property if determining the size required some "work" (DB call, expensive calc), to indicate to the caller not to take this call too lightly. Personally, I think it's confusing. I think that if something is a logical property, then it should be declared as a property; methods are for "doing stuff"; although sometimes that's a gray area. Whatever you choose, ensure that you're consistent across your app(s) when doing this.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Smaller classes&lt;/strong&gt;: Often easier said than done, but a class with 30-40 methods and 20 properties is going to have discoverability problems, not to mention other issues. Break it up into smaller classes or helper classes where possible. &lt;a title="Refactoring: Improving the Design of Existing Code, by Martin Fowler" href="http://www.amazon.com/Refactoring-Improving-Existing-Addison-Wesley-Technology/dp/0201485672/ref=sr_11_1?ie=UTF8&amp;amp;qid=1213840370&amp;amp;sr=11-1"&gt;Read this&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Design the API&lt;/strong&gt;: Often, the API just "happens" as a result of writing the application; don't pretend you haven't done it! I think that designing the API up front with a view to having it used by other people makes for a much better, more well rounded API that has more discoverable avenues for success and needs less documentation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pretty files&lt;/strong&gt;: This goes in the "Commenting" bucket. Use regions to separate your class file into logical parts. Put all the properties together in one place; put all related methods close to each other. Ensure that methods are named similarly when they do similar things.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;If there are suggestions for other solutions (or other problems), please contribute; I've got lots to learn.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Avi&lt;/p&gt;
&lt;p&gt;&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;script type="text/javascript" src="http://www.reddit.com/button.js?t=1"&gt;&lt;/script&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;script type="text/javascript"&gt;
digg_skin = 'compact';
&lt;/script&gt;
&lt;script src="http://digg.com/tools/diggthis.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8619813" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/avip/archive/tags/api/default.aspx">api</category><category domain="http://blogs.msdn.com/avip/archive/tags/architecture/default.aspx">architecture</category></item></channel></rss>