Sleep

Paul Brown @ 2006-07-02T07:20:00Z

Back in January, I blogged about the kid's sleeping issues, and things have suddenly and inexplicably turned the corner — last night she slept like a rock from 11:00PM until 5:30AM. (Do rocks dream?) The past few nights have been pretty good, too. While we worked through getting her to sleep, we talked to plenty of people who had taken a similarly permissive stance on enforcing sleep habits, and they all said the same thing, i.e., one day you wake up in the morning and the kid will have slept through the night. I guess that today was our day.

(comment bubbles) 0 comments

The Joys of Trunk-Surfing

Paul Brown @ 2006-07-02T07:09:00Z

A while back, in order to get the tag functionality in Typo, I upgraded from the stable download to the trunk. Typo is in flagrant and ongoing violation of the “release early, release often” directive for software projects, but it's been a nearly painless experience each time. Except for this last time. To get an update to the Typo sidebar plugin API, I ran svn update on the Typo on my local machine, tweaked a couple of things, and tested; then I ran svn update on the Typo on my remote machine, and... crash. The difference was the theme that I use on the production server, and I resorted to Google before fishing through the theme layouts for issues. Ironically, I found a quick answer on Phil Cryer's blog and had things back to (what passes for) normal in a few minutes.

I say ironically for two reasons. First, it's ironic for me to find the answer on Phil's blog because he just gave up on Typo and went to WordPress over this very issue. And that is ironic because I gave up on Wordpress over a recurring annoyance with incorrectly set Media-type and encoding (see RFC3023 and Mark Pilgrim's discussion for some background) where I had to trace through multiple noodles of PHP spaghetti code to fix it each time Wordpress shipped a new version. (Each time, the upgrade was security related, so I felt obliged to apply it.)

(comment bubbles) 0 comments

Decoupling Teams through Service-Orientation

Paul Brown @ 2006-06-30T05:38:00Z

There is plenty of talk about service-orientation as a way to decompose software, but I've come to look at it differently. Service-orientation is equally important as a way to decompose work.

As an impermeable barrier between the inside (i.e., implementation) of a service and the outside, service-orientation helps to reduce complexity of a larger system composed of multiple services. (Pat Helland's paper on “Data on the Outside vs. Data on the Inside” makes the case in detail.) This is a good thing, but it's not a great thing. Don't get me wrong — architecture requires a certain sensibility and flair, and there are plenty of deep thoughts yet to be thought about software. Nonetheless, the majority of the complexity in software engineering lies in putting a system into production (and keeping it there), not in coming up with an elegant design.

Service orientation also decouples teams. For example, the team working on the customer information system and the team working on the inventory management system only need to adhere to each other's service interfaces in order to collaborate. There is a huge difference between an interface and an implementation as the vehicle for collaboration. Once one system is built around the knowledge of something inside (i.e., the implementation of) another system, those two systems are rigidly linked, and this constrains the actions of both teams. For two teams trying to evolve two systems, this isn't a significant burden, but for dozens of teams trying to evolve dozens of systems toward different goals, it is debilitating.

Some e-commerce leaders talk the talk and walk the walk, but it doesn't take “interplanetary scale” to realize the benefits. Companies that ship complex, customized software to multiple customers have to manage the collaboration between product development and multiple professional services teams, and if they've done it for any length of time, they've probably encountered the challenge of migrating customizations between versions or even just between patches. (I've even seen systems — from a safe distance — where the customizations cross multiple tiers.) Trading communities are another example where service-orientation (albeit seldom SOAP/WSDL-style or even XML-based) or the lack thereof drives complexity and cost.

At any rate, yet another discussion thread on “business/IT alignment” in my inbox is what got me on the train of thought that spawned this entry, but I think that most such discussions miss the point. I do see service-orientation as a way to help align business and IT by pairing the semantics of the business with the semantics of the services, but it's the business of IT where service orientation pays the strongest benefits.

(comment bubbles) 0 comments

Songbird

Paul Brown @ 2006-06-30T04:15:00Z

I followed the instructions and got Songbird built and running on my Mac without too much trouble. (I made a couple of very minor tweaks, as I prefer fink to darwinports, but it is essential to get the glib2 (2.10.3) and orbit2 from darwinports and in that order, as the locations of libraries are hardwired into some of the dependencies.)

I remain pleased with my minimal headless music configuration, but if I wanted something more iTunes-like, Songbird looks like it's going to be a good candidate. (Maybe the Mozilla plumbing will give Eclipse RCP a run for its money in the cross-platform rich client space...?) For a pre-alpha, it's in good shape so far. It imported most of my MP3s but turned up its beak at my FLACs and Oggs even though it looks like the embedded VLC engine should support them. It will be interesting to see how plugins and some of the network and social aspects evolve; if nothing else, Javascript as an extension language is more likely to spawn a community than iTunes's COM SDK on Windows and AppleScript API on OS X.

(comment bubbles) 1 comment

Either You Suck or You Don't Suck

Paul Brown @ 2006-06-20T07:07:00Z

It takes some big hairy coconuts to knock on someone's front door and announce that you'd like to eat their lunch, so I assume that Kristopher Tate is half man and half palm tree. (The usual approach is to sneak up on them, even just a little bit, but then you don't usually ape their name, either...) On the other hand, either you suck or you don't suck. Either your business is solid or it isn't. Either you have a complete product or you don't. Either your customers love you or they don't. Either you can move faster than your competitors or you can't. Refusal to compete is admission of weakness, so it's great to see Flickr step up to Zoomr's challenge.

On the flip side, I see my Flickr photos as just that — mine. So don't use feudalistic control of your API as pseudo-DRM to lock me into your service, unless you want to ensure that I'll take my business elsewhere on principle. Instead of creating competitors by forcing people to work around you, either go so fast that no one can keep up or ensure that your service is so open, so flexible, and so compelling that people extend it rather than imitate it with minor twists.

(comment bubbles) 0 comments

Lo-Fi Diagramming

Paul Brown @ 2006-06-20T04:39:00Z

When I was a mathematician, my preferred tools were a hard-bound notebook, a rollerball pen, and a box of crayons. I drew tons of pictures to help myself make sense of my ideas, and when I needed one for a document, I'd spend some time and draw it up in Adobe Illustrator or write a program in a TEX macro package to draw it. I've written other entries about why as-plain-as-possible text files are preferable to formatted documents in a system like Microsoft Word or Open Office, and the same applies to drawings, except that in this case, it involves not using a computer at all.

A piece of paper or pieces of paper, fed into a fax machine and then received via j2 (or eFax or another similar service) or scanned with a multifunction machine and converted to a convenient format (i.e., PDF), are more time-effective than a drawing tool like Visio or even OmniGraffle. It takes a few minutes to sketch out what's needed, drop it in a sheet feeder, and then collect the results for use as an email attachment or for cut-and-paste. (At least on the Mac, Preview supports cut-and-paste to other applications as native PDF.) For a related take, see Paper Prototyping Graphics, although the idea of using stickers seems like a step back toward unnecessary frills to me.

In the form of a “do the simplest thing” corollary: If you need to draw a picture, use a pen. If you need to draw a pretty picture, use an app.

(comment bubbles) 2 comments

Genericize for Testability

Paul Brown @ 2006-06-17T03:19:00Z

I needed an algorithm to traverse a graph of relationships and test whether it was a connected tree or not, so I coded-up a quick (and relatively efficient) search. No matter how many times I code graph searches, I know myself well enough to expect a couple of mistakes, so I went to write some tests after I'd finished with the algorithm. The reason that I'd put off writing the tests was that the signature for my search was the following:

static FancyIface findRoot(Map<FancyIface,FancyIface[]> graph)

FancyIface is an interface with a bazillion methods and where the API doesn't expose any implementations. Rather than mocking instances of FancyIface for testing purposes, it makes sense to genericize the method:

static <T> T findRoot(Map<T,T[]> graph)

and then code the tests with something nice and simple, like integers:

public void testFindRoot() {
  Map<Integer,Integer[]> m = new HashMap<Integer,Integer[]>();
  m.put(1,new Integer[] {2,3});
  m.put(2,new Integer[] {4});
  // should return 1, as this is a tree rooted at 1.
  assertTrue(Foo.findRoot(m) == 1);
  m.put(3,new Integer[] {4});
  // should return null because this is no longer a tree.
  assertFalse(Foo.findRoot(m) == null);
}

And that's it.

(comment bubbles) 0 comments

All Posts contains 399 items in 57 pages of 7 items each:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57