Friday, November 11, 2011

Intention-Revealing Interfaces

Amazingly well put:

If a developer must consider the implementation of a component in order to use it, the value of encapsulation is lost. If someone other than the original developer must infer the purpose of an object or operation based onits implementation, that new developer may infer a purpose that the operation or class fulfills only by chance. If that was not the intent, the code may work for the moment, but the conceptual basis of the design will have been corrupted, and the two developers will be working at cross-purposes.

Domain Driven Design by Eric Evans, page 246

Working with Selections and Ranges in CKEditor

Working with ranges and selections in CKEditor is almost unbearable. In order to make it a bit easier, i recommend using rangy, a free library that makes the html selection/range api cross-browser-proof. Well, at least it made what i was trying to accomplish cross-browser...

Monday, October 3, 2011

Inlining in .NET

I spent some time today debugging a huge, huge function. I remember one of the quotes a professor of mine told me about function length. It might of been about class length, actually.

"Never write a function longer than your screen."

I think its a good rule. There's something to be said for being able to sum up a piece of code just by looking at it. Did you know that .NET does the same thing behind the scenes? And that it has trouble with huge functions?

Enter Inlining

From what i understand, back in the C++ days, programmers used to be able to specify what functions would be embedded into the calling function. The advantage was one less function that the execution would have to call--because on execution of a function "some stuff happens" that i'm not going to go into here. The point i'm trying to make is that if you didn't call that function, you wouldn't have to do "that stuff." So, instead of putting that piece of reusable code in every place they wanted it to go, they kept DRY and marked it to be inlined--for the compiler to manually place it in every place it was called.

.NET Inlines for You

It's true. .NET will inline your code for you during JIT if it deems it a good place to do so. But here's the catch: if you're writing functions that are miles long, there's no chance whatsoever that .NET can inline it and you'll never get the performance benefits of letting .NET upgrade your code.

Keep It Simple

Write functions that do one thing, really well. Make them reusable, testable pieces, and short enough that even .NET can sum them up...

Sunday, October 2, 2011

The Repository Pattern

I'm not sure if Martin Fowler conceptualized the repository pattern, but his book Patterns of Enterprise Application Architecture (PoEAA) is where I first came across the definition:

"Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects."

He has very carefully selected his words. I have my own definition. Consider it the layman's version:

"Separates data from its source." 

Let's dig into an example.

The Repository Pattern in .NET

Every .NET programmer has written some sort of code that accesses a database or web service and returns something. Traditionally, the ever-present n-tier/three-tier philosophy dictates that the code for that should be in its own package/layer, the data access layer. What that philosophy does not dictate is the method signature and the return type; they're extremely important. Let's look at your traditional DAL:

What will the dev on this project do if the People DB gets outsourced and is now accessed via webservice? Convert the web service return into datasets, or change all the business layer classes to work with whatever the new return is? Or, what if they change to a db that doesnt easily convert into datasets? Not a great position to be in... Why not change it to something more generic that will never change?...

Here's a look at the repository pattern implementation:

Notice how this implementation could survive through any sort of data source change because it is using "a collection-like interface"? Much more maintainable.

The Repository Pattern in JavaScript

JavaScript's implementation would need to take into account the fact that AJAX requests (or all node.js functions) are meant to happen asynchronously. In order to allow for this, all we really need to do is implement the callback pattern, which really just boils down to passing an extra function.

That's it!

Wednesday, December 1, 2010

.NET-- Explicit Cast or Use "as"?

In .NET there are 2 different ways to cast an object from one to another-- by explicitly casting like (OtherObject)startObject (I call this the explicit cast) or by using the as keyword like startObject as OtherObject. What are the advantages/drawbacks of using one or the other?


Why You Should Use "as"

Do you know what goes on behind an explicit cast? If the type to be converted does not match the wanted type at runtime, it tries to use any user defined conversions to create a completely new type. Also, if the explicit cast doesn't work it throws an error.

The "as" keyword doesn't have these drawbacks. If the cast fails, the newly created object is null; there's no error. And again, no conversion/new object creation occurs. Win-win.

"As" does have a downside though--it cannot be used on value types. Doesn't really come as a surprise though, remembering that it will not do new object creation...

Thursday, May 20, 2010

How to Add a Facebook Like Button to Your Blogger Posts

A friend of mine that owns a Pittsburgh-based custom t-shirts and screen printing business asked me the other day if I could research adding Facebook like buttons to his posts. Here is the result of said research:

Step One: Sign Up for Facebook Developer Access

I'm hoping you already have a facebook login. Using said login, head over here and fill out the form supplying your page name and url.

After that is done it will give you the application ID-- you're going to need this for the next step.

Editing Your Blogger Template

Ok so sign in to your blogger admin and navigate to layout > edit html. Make sure you check the "Expand Widget Templates" checkbox.

Now comes the tricky/nerdy inserting code part. Inside of that box where the code is, you'll see at the top of it a tag that starts with <html. We need to add xmlns:fb='http://www.facebook.com/2008/fbml' inside of that tag (which means we need to put it inbetween the < and > symbols for those of you not too html savvy). . So your final <html> tag should look similar to this:

<html expr:dir='data:blog.languageDirection' xmlns='http://www.w3.org/1999/xhtml' xmlns:b='http://www.google.com/2005/gml/b' xmlns:data='http://www.google.com/2005/gml/data' xmlns:expr='http://www.google.com/2005/gml/expr' xmlns:fb='http://www.facebook.com/2008/fbml'>

The important part is that you got that xmlns:fb facebook part. The next step is to scroll down and look for the <body> tag. In the picture below you'll see the body tag, and then the code you need to insert below it.

You're going to substitute my app id for your app id--which should be a string of numbers--no symbols, letters or anything else. Your final code should look like so:

<div id='fb-root'/>
<script>
  window.fbAsyncInit = function() {
    FB.init({appId: YOUR-APP-ID, status: true, cookie: true,
             xfbml: true});
  };
  (function() {
    var e = document.createElement('script'); e.async = true;
    e.src = document.location.protocol +
      '//connect.facebook.net/en_US/all.js';
    document.getElementById('fb-root').appendChild(e);
  }());
</script>

Remember, substitute YOUR-APP-ID for your appication ID you got when you signed up above. We're almost there, one more change! Now we need to find
<div class="post-footer">. We're going to add the tag that begins with fb:like in there.

So your final code there should be similar to:

<div class="post-footer">
<fb:like action='like' colorscheme='light' expr:href='data:post.url' layout='standard' show-faces='false' width='450'/>
</div>

That's it! All done! Be sure to like this post below ;-)

Monday, May 3, 2010

Making Cross Domain jQuery AJAX Calls

Today's web browsers do not allow web pages to make cross-domain ajax calls. By this i mean that if you are at www.ajax.com and try to make an Ajax call ( an HTTP request using the XmlHttpRequest object) to www.other-domain.com the browser would not allow this to happen. Why? For security purposes that i cannot currently name.

However, at some point you get to a project where you're interfacing this third-party site that needs to talk to your main site, or some other similar situation where the only way you're going to get the data you need from point a to point b is with some javascript magic. Here is how to accomplish it:

How to get/post data using jQuery/javascript (JSONP)

The short answer: its not ajax at all, its JSONP. Yes, JSONP is not Ajax. I just learned this today. Like i said earlier, browsers do not allow XHR/Ajax cross-browser requests. JSONP avoids this by making a request for a script file-- no Ajax at all. Let me explain:

  1. Instead of accessing the XHR object, the browser first creates a new script tag to inject into the HTML DOM
  2. The script tag's URL is set to the URL you're looking to get/post(using HTTP GET) data to
  3. The script tag is injected into the page, causing...
  4. The request is sent to the server, even if its cross-domain
  5. The server returns the data in the form of a javascript function call
  6. The browser receives the data and executes the function call

jQuery code

//use a get to post a querystring value via HTTP GET to an asp.net webhandler
$.getJSON("http://www.example.com/get-post.ashx?var1=var1value&callback=?",function(data){
     //really no need to do anything here, we're just posting data
     //but this will output success
     alert(data.return);
});

asp.net generic handler/webhandler code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;

namespace jsonp_test
{
    /// 
    /// Summary description for $codebehindclassname$
    /// 
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class get_post : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            string callback = "";
            try
            {
                if (!string.IsNullOrEmpty(context.Request["callback"]))
                {
                    if (!string.IsNullOrEmpty(context.Request["var1"]))
                        SaveData(context.Request["var1"]);
                    callback = context.Request["callback"];

                    context.Response.Write(callback + "({ \"return\": \"Success\" })");
                }
            }
            catch (Exception exc)
            {
                //hopefully this error doesnt contain any quotes... you know?
                context.Response.Write(callback + "({ \"return\": \"" + exc.Message + "\" })");
            }
        }

        private void SaveData(string value)
        {
            //do something with the var1 posted to us
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

So what we effectively have here is the setup for asp.net cross domain ajax calls using jQuery

How to do cross-domain calls to others' servers: YQL

What if you need to do a get but don't have the ability to make the page its posting to return a JSONP response? Using YQL is a great way to achieve this.

YQL is a way to query the internet like it is a database. For example, one could easily run

select * from html where url="http://www.microsoft.com"

and recieve a JSONP return containing all of the site's HTML. You could also, do the following

select * from html where url="http://www.mircorosft.com?var1=var1value"

and HTTP GET values to the server. YQL does not allow this to happen on any area of any site that is blocked by the robots.txt file. Here's full example code:

//feel free to add querystring vars to this
var myurl="http://www.example.com/get-post.ashx?var1=var1value&callback=?";
//make the call to YQL 
$.getJSON("http://query.yahooapis.com/v1/public/yql?"+
                "q=select%20*%20from%20html%20where%20url%3D%22"+
                encodeURIComponent(myurl)+
                "%22&format=xml'&callback=?",
        function(data){
          if(data.results[0]){
            //this data.results[0] is the return object you work with, 
            //if you actually want to do something with the returned json
            alert(data.results[0]);
          } else {
            var errormsg = '

Error: could not load the page.

'; //output to firebug's console //use alert() for other browsers/setups conole.log(errormsg); } } );