Random Thoughts of a Scatterbrain.
 Tuesday, January 09, 2007

On Software "Architects"

1/9/2007 10:28:54 AM (Eastern Standard Time, UTC-05:00)

I've always had a disdain for the term "architect" in the context of software development. Possibly due to my not-so-fond experience with an "architect" during my days at Factiva.

I popped open Fred Brooks' The Mythical Man Month last night searching for a specific passage on project management, but stumbled on another passage that I had highlighted which caught my attention:

The manual, or written specification, is a necessary tool, though not a sufficient one. The manual is the external specification of the product. It describes and prescribes every detail of what the user sees. As such, it is the chief product of the architect.
The manual must not only describe everything the user does see, including all interfaces, it must also refrain from describing what the user does not see. That is the implementer's business and there his design freedom must be unconstrained. The architect must always be prepared to show an implementation for any feature he describes, but he must not attempt to dictate the implementation.

I think this is a golden rule that is often broken by software architects. The reason that it's so common to break this rule is that in most organizations and teams, the architect is not necessarily:

  1. labeled as such; instead, the term that might more commonly be used to describe such a person would be "business analyst",
  2. a distinct position/role, which means that a high level/senior (read:"been here the longest") developer assumes the role of architect,
  3. accustomed to the practice of separating usage from implementation.

On point 1, by Brooks' definition, an architect is not necessarily a developer, but an individual more aligned with the business side of the client/company with perhaps some technical background or maybe even a trusted technical advisor. The architect must be able to interface with business users and extract the information required to create the right product.  Such incorrect labeling of the position often leads to conflict.  When Confucius was asked what his first measure would be as a minister in the court of Wei, he commented:

It will certainly concern the rectification of names.  If names are not rectified, then language will not be in accord with truth.  If language is not in accord with truth, then things cannot be accomplished.  If things cannot be accomplished, then ceremonies and music will not flourish.

-- Confucius (Chan, A Source Book in Chinese Philosophy, p.40)

The role of architect and developer should be distinct and well defined.  This is not to say that the architect shouldn't have a development background.  Quite the opposite is true; the architect should know the technologies and know the tools, but should refrain from telling others how to implement a feature.  By Brooks' definition, the architect should only tell others what to implement.

On point 2 and 3, in most cases, companies do not always specifically allocate the role of "architect" without also making sure that said individual does not lead the direction of development. In smaller organizations, it's perhaps not an option to create such a distinct role. In these cases, the architect-developer must be able to separate the responsibilities of the duties of both roles.  The problem that arises when this happens is that the developer-cum-architect needs to have the discipline to switch contexts between architect mode and developer mode.  The individual must not think of interfaces in terms of code, but in purely terms of use cases.  This is a difficult task as when I'm presented with a proposed interface (be it visual or programmatic), my natural reaction is to wonder "how will I implement this feature?", "what libraries can I use?", and other such thoughts instead of focusing on dissecting the features of the interface from a use case perspective.

In any case, the architect can still guide the development process by continually updating the specs, conveying user feedback, and offering implementation advice when requested, but the architect must not dictate the details of the woodwork. Doing so always inevitably causes friction between those that create the code and those that create the specification. For, as Brooks says, the act of software engineering is, ultimately, a creative process for the programmer and by restricting this aspect, only begrudging compliance can be achieved.

 Monday, January 08, 2007

ContentTypeIds In WSS3

1/8/2007 4:50:43 PM (Eastern Standard Time, UTC-05:00)

In WSS3, if you execute the following SQL:

    SELECT
        ContentTypeId
    FROM 
        ContentTypes

You will notice that the content types are represented in the output as hex.  If you take a look at the table definition, you'll see that the actual data type of the column is VARBINARY(512).

Doing a lookup like so:

    SELECT
        ContentTypeId
    FROM 
        ContentTypes
    WHERE 
        ContentTypeId = '0x101'

Will not work since you cannot perform a comparison between VARBINARY and a character data type directly.

Doing the following will also not work:

    SELECT
        ContentTypeId
    FROM 
        ContentTypes
    WHERE 
        CAST(ContentTypeId AS VARCHAR(512)) = '0x101'

This doesn't work because the underlying type of the binary data isn't character data.  It's integer data.  You can confirm this by running the following query:

    SELECT
        ContentTypeId,
        CAST(ContentTypeId AS VARCHAR(512))
    FROM 
        ContentTypes

You'll see that it's just a bunch of gibberish.  Try the same query with INT and you'll see that the data makes much more sense.  What you'll notice is that content types that inherit from a base content type will have numerical values that increment by 1.

This information is useful, but not nearly as useful as the data that you can glean from the hex string representation of the ContentTypeId.  You see, in the hex string representation, the base ID is a substring of the ID of any inheriting content type.  For example, if I have a content type which has a ID (as a hex string) of 0x0101345346345312234346, then any child content types will have 0x0101345346345312234346 as a substring (e.g. 0x010134534634531223434601, 0x010134534634531223434602).

So how do we get this data in SQL Server for comparison purposes?  We need to use an "undocumented" SQL function: fn_varbintohexstr().

This allows you to do nifty queries to find a given content type and all child content types (or any query where you have to retrieve information about a hierarchy of content types) like so:

    SELECT
        *
    FROM 
        ContentTypes
    WHERE 
        master.dbo.fn_varbintohexstr(ContentTypeId) LIKE 
            '0x0101345346345312234346%'

You can find out more information on this function here.

 Sunday, January 07, 2007

A Note On Copying Files In WSS3

1/7/2007 2:52:33 PM (Eastern Standard Time, UTC-05:00)

I dunno if this was supported in WSS2 or not, but in WSS3, when a file is copied to a new destination, a link is stored which indicates where the new document is copied from.

In the database, you can see this by running the query:

SELECT
    tp_dirname,
    tp_leafname,
    tp_copysource,
    tp_hascopydestinations,
    tp_guid,
    *
FROM ALLUSERDATA

The tp_CopySource column holds the URL of the source document from which the given file is copied from.  If you simply change the URL here, you can point it to any file you want.  If the file is a copy, then the following information bar will be displayed on top of the file properties in the properties page:

copy-indicator.jpg

However, it's not so obvious how to do this programmtically.  First, I tried using the CopyTo() method of SPFile.  Aside from not having the desired effect, this method does not seem to allow copying files across site boundaries (for example, from a root site to a document workspace -- for that, you have to use the Add() method on the Files property of the target SPWeb).

On my second attempt, I tried to set the "Copy Source" property of the file.

foreach (object key in file.Properties.Keys) {
    Console.Out.WriteLine("{0} : {1}", key, file.Properties[key]);
}

Iterating through the properties of an SPFile instance, I found that one of the properties, was "Copy Source" (internal name of "_CopySource") and in fact, held the URL of the source document.  I tried to set this value and update the file, but this was unsuccessful yet again.

On my third attempt, I came across the CopyTo() method on the SPListItem class and this did it for me :-) Conveniently, it also allows you to copy an item across site boundaries.

I felt so stupid afterwards because it should have been obvious that I had to use the CopyTo() method on the SPItem because the SPItem is also where the UnlinkFromCopySource() method is located.

 Thursday, January 04, 2007

More on Dean Karnazes

1/4/2007 9:21:29 PM (Eastern Standard Time, UTC-05:00)

I mentioned a short article on Dean Karnazes in the current (January, 2007) issue of Outside magazine in my previous post.

There's a great passage that I really liked:

I think Western culture has things backwards.  We equate comfot with happiness, and now we're so comfortable we're miserable.  There's no struggle in our life, no sense of adventure.  I've found that I'm never more alive than when I'm pushing and I'm in pain and I'm struggling for high achievement.  In that struggle, I think there's a magic.

Unless you're pushing yourself, you're not living to the fullest.  You can't be afraid to fail, but unless you fail, you haven't pushed hard enough.  If you look at successful people and happy people, they fail a lot, because they're constantly trying to go further and expand.

It's a good mindset to keep in mind as you start out your new year and try to stick to your resolutions :-)

 Wednesday, January 03, 2007

I Want To Dunk.

1/3/2007 11:16:33 AM (Eastern Standard Time, UTC-05:00)

I have no idea why, but I woke up this morning and I thought to myself "I want to dunk" :P

First, a little background: I've been playing basketball on and off during the last 10 years, some times really intensely (like in high school, when I played 2-3 hours every day) and sometimes less (like nowadays, when I only have time to play an hour or two at the gym).  During my high school days, I could actually dunk a ball on the rim (it's true, I actually did it once).  (But alas, cursed with average sized hands for a 5'10" guy, I could never palm the ball with a strong enough grip with one hand for a dunk.)  Yes, at one time, I could actually jump vertically (no running start) and grab onto the rim.

Over the years, as I've become more sedentary, as most programmers are inclined to, I've lost much of that leaping ability (although my calves still look fantastic (no, really :-D)) even with regular weightlifting and workouts.

For the past three months, I've been battling various issues that have hampered my usual workouts: a sprained ankle in Sept./Oct., my intensely dry skin which basically precludes me from playing basketball at all, and my fractured finger (which is just now healing to the point where I can close my fist).  Not to mention that I packed on 6 pounds (mostly -- okay, all -- fat) due to inactivity and holiday feasting.

But I figure now is as good a time as any to work on this goal and get back to my regular regiment.

By way of Google, I stumbled upon an article by Josh McHugh of Outside (which, by the way, recently had an excellent mini article on Dean Karnazes -- so good that someone actually ripped the page out of the Outside magazine at the gym) and Wired magazine fame.  I think I'm gonna try for it.  There's quite a bit of investment involved in some equipment (enough to get myself a Treo 700wx!), but I think it'll be worth it even if I can't dunk, at least so that I can swat some more shots at my gym pickup games :P (man I sound like such an old fart).

JumpUSA has most of the products including:

I'm having a hard time deciding between the weight vest and the belt.  The vest seems like it's more natural and easier to deal with (less motion on the body when running/jumping) but seems like it'd collect more sweat and also add more weight above the waist, which could strain my lower back.

So it'll be interesting to see how far I can take it.  I'll keep my progress posted.

 Tuesday, January 02, 2007

To Follow Up...

1/2/2007 5:30:48 PM (Eastern Standard Time, UTC-05:00)

So it turns out that Paul Andrew, the technical product manager of WF linked to my very abstract review of Essential Windows Workflow Foundation.  For those that haven't been following, I wrote an awesome review of the book on Amazon and sent it in (or so I thought!) but I haven't seen it show up on the page yet :-S

So for the sake of others considering this book, I'll review it again.

There are two types of developers that you will come across: those that are content to make things work and solve business solutions from the top down and those that want to understand the underlying technologies to build solutions from the bottom up.  This is not so much a discussion on "architecting", mind you, but rather a discussion on how different developers approach tools and frameworks.  Not that one is better than the other, but each brings a different approach and each has different preferences with regards to technical resources.

If you fall into the former and you are mostly concerned with your immediate business solutions (learn top-down) and you learn best by doing, then this book is not for you.  The contents of this book are not so much concerned with how to solve business solutions with WF nor is it a cookbook for WF solutions.  This book doesn't have many pictures of the design surface and doesn't concern itself much with building workflows in the designer.  It is an introductory guide to the underpinnings of the WF framework.  It delves into the workings of WF and the principles behind many of the advanced concepts that may not necessarily crop up in most use cases.

If you fall into the latter category of developers (learn bottom-up) and you learn best by first understanding the tool and the design principles of the tool, then this book will be a good starting point to understanding WF.  In fact, the first chapter of the book walks through a sample implementation of a simple "workflow engine" and covers the principles that drive the implementation of the WF framework.  The chapter presents a "If I were writing a workflow engine, how would I write it?" scenario (if that makes any sense).  This outline then serves as a basis for understanding the function and design of the WF engine.

The book provides insight into advanced concepts and does a fairly good job of it (examples are simple and straightforward - oddly, not all of the code is provided online), but it seems to come up short in the last chapter, where the authors just kind of jumbled everything that they didn't cover into one chapter.  It almost seems like the authors were working on a 10 or 12 chapter book but were forced to cram the remaining topics (unfinished) into chapter 8.  In short, the book seems unfinished.

This book is not for everyone.  It does assume some familiarity with higher level .Net framework concepts that many developers from the ASP.Net world may not have experience with (specifically, threading and asynchronous method calls) so for that reason, I would recommend a companion book: Pro C# 2005 and the .NET 2.0 Platform, Third Edition.  As a general note, I've found that the "Microsoft .Net Development Series" of books from Addison Wesley typically does not cater to the first class of developer as the titles tend to be architecture and framework oriented as opposed to solution and implementation oriented.

In summary: 4 out of 5 stars; a worthy book that deserves a space on your bookshelf if you plan on doing WF.

 Thursday, December 28, 2006

Happy Holidays!

12/28/2006 8:22:57 PM (Eastern Standard Time, UTC-05:00)

Yeah, it's been a looooong time.

First of all, happy holidays to anyone reading this (hi Mom!).

Second, I know, no one likes to read excuses on blogs :P but I swear, I've been super busy and that fractured finger made extracurricular typing difficult.

One of the more exciting things that happened this week is that we switched the whole family to Sprint.  It's one of those weird things...no one I know aside from my boss has Sprint.  No one my sister knows has Sprint.  So it was kind of scary to switch; when you think about it, it's really a huge commitment!  But the allure of Sprint is in their rock bottom prices compared to the other major carriers and also the $15 for unlimited data access (I didn't believe my boss when he mentioned this, but it's true!).

Yeah, it's been a pretty freakin' long time since I've switched carriers, but for the price I was paying, Cingular just wasn't cutting it with the services provided.  For less than what we were paying for three phones (well, we did have 900 more minutes), we now have four phones with unlimited data access on two phones.

So yeah, speaking of phones, I think we may have gone overboard in that regards.  We ended up getting two Treos, one 700p and one 700wx (taking advantage of the 30 day exchange period so that we could figure out which one is better). I've read that the wx has some issues, but so far so good.  While I'm happy with the features I'm getting for my price, one thing that has me second guessing is that there seem to be pockets of my house where I'm roaming (as weird as that sounds).  Well, we'll see how it goes, but I'm loving the download speeds on the Sprint Vision network.

I've also been trying to get back to the gym...man holidays.  I always end up gaining like 6-7 pounds.  This year, it was compounded by my still healing fractured finger.  One good resource I came across is the Mayo Clinic's guide to core exercises.  I'm going to put some of these to good use.

On the professional front, I've been doing a lot of work with WF, WSS3, and Office 2007.  I wrote a great review on Amazon for Essential Windows Workflow Foundation by Dharma Shukla and Bob Schmidt, but it seems like it never made it to the product page :-(  It's a 4-star book for those that want to understand what's under the hood and the internals of WF (from a high level).  It's not a good "cook-book" type of book and it doesn't have lots of pictures, but I think it has some great info.

Well, that about wraps this up.  Happy New Year folks!

 Wednesday, November 22, 2006

EditPlus Rocks!

11/22/2006 4:19:38 PM (Eastern Standard Time, UTC-05:00)

Not that EditPlus didn't rock before, but it's rockin' even harder now with the release of version 2.3!

Two of the biggest features are the addition of indentation based collapsable code regions (I've already got collapse/expand hotkeyed!) and "Copy as HTML" which allows you to copy the contents of the workspace as HTML which retains the formatting and your environment colors!  Awesome!  This makes it perfect for writing up web based documentation.

Aside from this, 2.3 also introduces other features like the new "Find in Directory" command you can use on the directory toolbar, the "View in Browser 2" command which allows you to hook up IE and FireFox (or IE6 and IE7) to have seamless browsing with one and external launch with the other, and various bug fixes with the FTP component.

All in all, an awesome version that has some loooong overdue features.  If you don't have it already, nows the time to download it!

 Friday, November 17, 2006

Down on ASP.Net

11/17/2006 11:51:51 AM (Eastern Standard Time, UTC-05:00)

First, some random stuff.  I got a free t-shirt from Newegg yesterday and I didn't even have to buy anything!  It turns out that scammers have been using Newegg's domain in phishing attacks.  As I was reading through this, I thought to myself: isn't there some way to counter this?  I came up with a pretty simple solution and emailed it to Newegg's customer service email: why not just have all account holders, when they enter their information, also enter three code words -- for example: "Apple", "Frankie", and "Coolio" -- and from that point on, any correspondence would include one of these three words, selected at random, in the subject line.  This way, a customer can easily scan emails which appear to be coming from Newegg and tell which ones are spam and filters can also be set up to simply remove anything from Newegg that doesn't contain one of the code words in the title. 

There would be no way for a scammer to overcome this without knowing the codewords (yes, I did think about it for a while and one codeword would probably work just as well since if you compromise even one, you've compromised the effectiveness of the entire system).

So simple (simple to program, simple for customers), yet so effective...I like simple things.

On another front, I've been working on a consulting project kind of indepenently with a development team in a primarily Java environment.  I've been doing some really nifty UI work and the sort of cutting edge web software that I love to do (I know you can't tell by this webpage :-D and I know his blog is displaying incorrectly in IE7).

Working with this team has reinforced my belief that web UIs have no place on server side applications except in HTML pages and JS files; server side UIs must die.  The entirety of the work that I've done has been in JavaScript classes that are essentially client side renderers which consume data provided by JSP pages as JSON strings.  It's a beautiful thing to behold from a design perspective.  Those guys that have no clue how to do UI are not tasked with doing any of the UI work; they just provide the data services that I need to render my UI.

Since I first came across AJAX, it has always been in my mind that, given this tool (a gift from the web programming gods, I tell you), the ideal way to write web apps goes sooo far beyond what any server web application platform can offer.  Perhaps some view this as a bit radical, but I have proposed that the application server be completely oblivious to the existance of any UI at all; all functionality is exposed as a web service and it is then up to the consumer of those services to decide what to do with it.  What exactly does this mean?  The server delivers what is essentially a base HTML page and from that point on, the server side app has no further involvement in the UI.  All of the rendering is then accomplished by client side scripts through DOM manipulation.

This has HUGE advantages over traditional postback/getback models.

  1. The rendering script can be cached.  That means that while you may bulk up on the scripts, you end up saving a HUGE chunk of bandwidth on not delivering highly redundant HTML.  Using this model, you only ever deliver data, NEVER delivering UI markup.
  2. The design is incredibly clean on the server side.  None of this intertwining of UI postback handling and layout garbage.  The application is responsible for providing data services and data services only.  This is a win-win situation as it does not ask the application programmer to build UI (something which most are terribly incompetant at).  At the same time, given a base set of messages, the UI developer can start working on client side code immediately with mocked up messages.
  3. The application is highly reusable now.  The same web services powering the web application can be retooled a bit to power ANY client.
  4. It offers a better user experience.  This is true for any usage of AJAX.
  5. It offers a clean separation of concerns for the two domains of the application: the UI and the server components.  Completely clean.  No half-assed distinction as with ASP.Net and ASP.Net controls.  There is no concept of UI at the server side -- NONE -- only data.

I can't be the only one that believes in this, can I?

But in any case, I'm really down on out-of-the-box ASP.Net and I'm really down on people that adhere to it because it's easy (don't get me wrong, I love .Net).  It all goes back to the drag-&-drop mentality.  I abhor this approach to software.  When something goes wrong, developers that adhere to this philosophy are like deer in headlights.  Source is your friendGet to know Source.  It'll be good for you in the long run.

Nothing against Infragistics, but has anyone seen the HTML source produced by their ASP.Net controls?  Wow.  Fugly beyond belief and HEAVY to boot (the same is true of SharePoint...it's unbelievable).  Not only that, the markup in the page is horrendous and completely illegible...how do they stay in business?  Oh yeah, the gigantic cadre of drag-&-drop professionals brought up in the drag-&-drop era.  They've sold the idea that these controls save time and money while I would argue that the time & money saved is not that significant it since it leads to hard to maintain code, heavy markup delivered to the client, "cookie" cutter UIs that tend to look alike (even across organizational and business boundaries), and a lack of tailoring to the users.  I mean, it may save what? a few hours of development time?  But you end up with code that is incredibly heavy, hard to read, and hard to maintain.  It's time for server side UI to die.  Completely.

I'll admit: not everyone is as comfortable as I am working in the DOM on the client side and working with JavaScript and raw HTML constructs.  But heck, this stuff isn't brain surgery man.

 Wednesday, November 15, 2006

Quote of the Day #001

11/15/2006 1:25:57 PM (Eastern Standard Time, UTC-05:00)

From November 20 issue of Time:

I also am in favor of toppling dictators, establishing democracy and watching it spread painlessly throughout every region where there is no experience of it.  Not only that: I am in favor of turning sand into ice cream and guaranteeing a cone to every child in the Middle East.  But you can't turn sand into ice cream.  That is not a defect in the execution of the idea.  It is a defect in the idea itself.

-- Michael Kinsley

RSS 2.0 Atom 1.0 CDF