Wednesday, December 29, 2010

A Pretty Functional Dynamic Proxy for jni4net

Wish you could use the dynamic keyword to access java objects created using jni4net?  I use this class to do that.  Feel free to reproduce it, modify it, or incorporate it into your own products so long as you don't claim that it is "yours" and start suing other people who use it.

It's cut-and-pasted out of my code so there's no guarantee that you won't need to tweak it a little. One might say it's pretty much guaranteed that you will. :)

using net.sf.jni4net;
using System.Dynamic;

public class JavaObjectProxyFactory
{
  public class JavaObjectProxy : DynamicObject
  {
    private readonly java.lang.Object o;
    private readonly java.lang.Class c;

    private JavaObjectProxy(
      java.lang.Object o,
      java.lang.Class c)
    {
      this.o = o;
      this.c = c;
    }

    public static dynamic GetInstance(
      java.lang.Object o,
      java.lang.Class c)
    {
      return new JavaObjectProxy(o, c);
    }

    public override bool TryGetMember(
      GetMemberBinder binder,
      out object result)
    {
      var field = c.getField(binder.Name);

      if (field == null)
      {
        result = null;
        return false;
      }

      result = ConvertToDotNetObject(field.get(o));

      return true;
    }

    public override bool TrySetMember(
      SetMemberBinder binder,
      object value)
    {
      var field = c.getField(binder.Name);

      if (field == null)
      {
        return false;
      }

      field.set(o, ConvertToJavaObject(value));
      return true;
    }

    public override bool TryInvokeMember(
      InvokeMemberBinder binder,
      object[] args,
      out object result)
    {
      var signature = new java.lang.Class[
        binder.CallInfo.ArgumentCount];
      var arguments = new java.lang.Object[
        binder.CallInfo.ArgumentCount];

      for (var i = 0; i < args.Length; ++i)
      {
        java.lang.Object arg = 
          ConvertToJavaObject(args[i]);
        if (arg != null)
        {
          signature[i] = arg.getClass();
          arguments[i] = arg;
        }
      }

      var method = c.getMethod(binder.Name, signature);
      if (method == null)
      {
        result = null;
        return false;
      }

      result = ConvertToDotNetObject(
        method.invoke(o, arguments));

      return true;
    }

    private object ConvertToDotNetObject(
      java.lang.Object o)
    {
      if (o == null)
      {
        return null;
      }

      if (o is java.lang.String)
      {
        var s = (java.lang.String)o;
        return new string(s.toCharArray());
      }

      return GetDynamicProxy(o);
    }

    private java.lang.Object ConvertToJavaObject(
      object p)
    {
      if (p == null)
      {
        return null;
      }

      if (p is string)
      {
        return new java.lang.String((string)p);
      }

      return (java.lang.Object)p;
    }
  }

  public static dynamic GetDynamicProxy(
    java.lang.Object o)
  {
    if (o == null)
    {
      return null;
    }

    return JavaObjectProxy.GetInstance(o, o.getClass());
  }
}

Enjoy.

Friday, December 17, 2010

"Happy Holidays" is what terrorists say. Merry Christmas!

Even though I'm not a Christian, merry Christmas everyone.

As a gift to the public at large, I've lowered the price of the Goad Testing PDF to free.  So get your copy now.

-- Max

Thursday, August 12, 2010

United Airlines: An Example of Why Airlines must be Allowed to Fail

United Airlines just fucked away an entire day of travel for me and managed to not get me anywhere.

I guess it's my fault, really.  How silly was it of me to think that eighteen hours was enough time to transport me three hundred miles.

On the other hand, you do have to cut me a little slack because I could have driven to San Francisco from Bend and checked in to my hotel in the time it took United to decide they weren't going to send us where we paid to go.

So here's what happened.  I showed up a good two hours early.  You know... like you're supposed to.  I was told there was going to be a "slight delay" of two hours.  "Okay," I said.  "That's okay.  That's why I am giving myself so much time to get where I need to go."

The idea was to give myself enough time to ensure that the airlines couldn't possibly screw up my very important trip.  Long story short: I'm pissing and moaning about the flight being canceled nine hours later (right after I got home).

There was not one person on that plane who would have been less satisfied with a trip to Oakland and a train-ride to SFO than they were with what they got (nothing).  Airlines are, by and large, idiocratic entities.  Stupid people are allowed to set up elaborate systems that are simultaneously incapable of meeting the fictitious needs initially envisioned and incapable of dealing with the actual needs of real customers.

When a limb is that rotten, the only thing left to do is chew it off.  We must allow the airlines to fail.

Wednesday, July 28, 2010

Quickie Orange Sauce

Quickie orange sauce:
  1 orange
  1 "new mexico pepper" (whatever the hell that is)
  1/3 cup (ish?) marsala
  1 slice butter
  1 tsp (ish?) cooking oil
  1 tsp (ish?) sugar

Crush orange into a glass
Add the other ingredients
Put in a pan on lowish heat
Stir until it reaches desired thickness (20 - 30 minutes?)
Turn to low heat
Continue to stir occasionally until time to serve

Monday, July 26, 2010

Lowering Cost of Goad Testing

I've lowered the cost of my long paper: Goad Testing.  This booklet shows a weakness in the way we usually do test-driven development along with a discipline we can apply to mitigate it.

Sunday, July 18, 2010

I Write Like

I write like is a pretty neat little tool and surprisingly precise.  I haven't read either of the authors it says I write like so I cannot say how accurate it is but I can definitely say it is precise.

Most of the time I paste in a blog entry, it says I'm like this Canadian blogger, eh.  The rest of the time, it says I'm like some science-fiction writer/essayist.  Even if the comparisons are totally, horribly wrong.  Just having metrics capable of consistently mapping one person's writing to one or two other people's writing is worth a golf clap.

Rock on, guys.  Rock on.

Software Development and Flow

In response to Marco Dorantes's post on flow in software development.

Flow is part of it.  There are five Lean principles, all of equal importance:

  • Start with a clear concept of value as a customer would define it
  • Lay out the series of steps required to create value to define the value stream
  • Create flow across the value stream
  • Let the customer pull value
  • Compete against perfection rather than other organizations

There are tools that allow us to do all five of these.  In fact, the tool that Al is promoting quite heavily right now - kanban - enables every single one of those things.  So, while I agree that flow is a critical part of the software development process - I don't understand why we are all so focused on the middle part.

It's like saying a ham sandwich with cheese and lettuce is all about cheese.  The cheese is necessary and not sufficient.

Saturday, July 17, 2010

Moq Sequencing

Declan Whelan recently responded to my Moq Sequencer post.

Looks pretty good.

Switching web hosts

My current webhost - ServerIntellect.com - appears to be completely incompetent.  I'd put my uptime in the vicinity of seventy-five to eighty percent.  Generously.  I highly recommend that you do not use them, if you have the ability to avoid it.

I'm going to be switching away in a bit, here.

Tuesday, July 06, 2010

Support Matrix and Short Term Planning for DataClass

The next three months are going to be all about expanding DataClass's platform support.  I've published the current support matrix.  That same page also includes estimates as to when currently-unsupported platforms will become supported.

Anywho... check it out.  Also, if you haven't already, check out the way I documented the DataClass syntax and let me know what you think.

RE: Uncle Bob's "Software Calculus"

...which can be found here:
http://blog.objectmentor.com/articles/2010/07/05/software-calculus-the-missing-abstraction

It don't think the problem is a lack of thought-tools at all.  The problem is people won't use the tools we have.  Sure, we can keep refining our tool set.  We should always do that.  I just don't think we should hold our breath for a revolution...

Software development is the revolution.

Monday, July 05, 2010

DataClass Syntax Documentation now Available Online

I've posted documentation for the syntax of a DataClass source file online (here).  It was really not that hard to build the engine that provides documentation in that format and I think it really helps you learn the language.  It leads one to the question "Why aren't all languages documented this way?"  Surely a human language would be a lot harder but at least programming languages.

Anyway, let me know what you think.

Saturday, July 03, 2010

We Reap What We Sew

...and I have sewn the seeds of a marriage to a tool that no longer provides adequate functionality.  All throughout DataClass, I coupled directly to Microsoft's CodeDom framework.

The following were my excuses for not encapsulating this stuff:

  • What a convenient way to model the code I want to generate.
  • It's just data.
  • It's part of the framework, I can trust it.
  • It will be easy to add support for Java because this is a language-independent format.
Bull...

...shit.

All of it.

Microsoft screwed us all over by getting rid of the J# code provider.  The C# code provider ought to work just fine with some small extensions but it is almost impossible to extend.  Bottom line, I'm having to write a working code modeling library; albeit one that only meets my needs.

They also gave .net eventing - a bastardized, incomplete, attempt at generically implementing the Observer pattern - a "little overhaul."  Translation: the way that you depended on these things working (crappy though it was) is no more.  Fortunately, I avoid those like the goddamn plague.

The bottom line, here, is this: If you didn't write it, don't trust it.  I'm not saying that Microsoft is likely to deprecate System.Int32 any time soon but you cannot count on them not changing something about how it works.  Encapsulate, encapsulate, encapsulate.

...or you will be sorry.

Thursday, July 01, 2010

Why Me?

Has anyone else noticed that the universe or, at the very least, our social and economic system, is set up to reward the stupid, the weak, and the wicked while punishing those who are smart, strong, and virtuous?

Idiots get bailed out from their bad decision making with their credit cards and I labor under the weight of those bailouts.  Weaklings choose to live off the government and I struggle under their considerable mass as well.  Jackasses intentionally screw over the economy and it's my job to give them a handout too.

Yet, while doing all of that and trying to contribute to society, I can't get a goddamn computer to run right.  First, it's hard-drive dies.  Then it's power intake.  Where is the support system for the people who are generally making this a better place to exist but just happen to actually, literally be down on their luck?

Wednesday, June 30, 2010

Flattery will Get you All Kinds of Places

Someone "liked" the DataClass homepage on Facebook.  I wish I could figure out who it was.  It's very flattering as it was not particularly solicited.

Anywho.  Today is the last day before tomorrow and tomorrow is the first day of the DataClass beta.  I'm leaving registration open until the 10th.  If you don't get a chance to get involved in this beta, there will be another chance in August if you are a Java programmer or work with Java programmers who use a database you maintain.

Monday, June 28, 2010

What Can We Learn about Agility from the Pyramids?

In response to http://whitewaterprojects.com/2010/06/28/were-pyramids-the-first-iterative-development/.

The author makes a good point.  In all likelihood the pyramids were built that way and, again in all likelihood, it did have the effect of a pyramid being ready whenever a pharaoh died.  The way these facts are presented tells us something about a lot of things.  Not the least interesting of which is the ever-present and ever-intriguing issue of perspective.

On the surface, this story tells us how Agility helped the people building tombs for pharaohs in ancient Egypt.  Another layer down, it tells us about how large groups of people organize to become agile.  Deeper still is a story of motivations and perspective.  Think of this as a practicality sandwich on philosophy bread.  The outer layers are important but I'm going to focus on the meat.

How did the ancient Egyptians learn to become Agile when it took us so many decades of lean thinking?  It's amazing, really.

In the words of Chazz Michael Michaels, it's mind-bottling.  You know, when things are so crazy it gets your thoughts all trapped, like in a bottle?

So while you are sitting there being all astounded by the wisdom of the ancients, let me just add this one little piece of info to the puzzle:

There were no massive cranes back then.  There were no steel girders.  There was no such thing as temporary scaffolding that could suspend one of those stones for a substantial period of time.

Knowing that, the question has to be asked.  How else would they have built a pyramid?  What structural, architectural, or engineering tools could they have used to do anything else but build it in shells?

Once you answer those questions, it becomes apparent that they had to be agile.  They had no alternative.  There were no tools available that would accommodate a big-batch approach in the first place.  Being ready to bury a pharaoh who died before his time probably was not even on anybody's mind.

...at least until the first time one died young.  Then, maybe, someone said "Hey!  It's really handy we've been building these tombs this way, now we can just drop him off in the center and start working on the next guy's pyramid!"

There is no evidence that the ancient Egyptians' agility was a consequence of their wisdom or foresight.  Quite the opposite, agility was mandated by the context in which the supposedly agile people did their work. There is a nugget of wisdom in that fact.

I think it is this: People are not naturally agile.  Don't try to control the person, instead control the context in which they work.  Make agility easier than the alternative and the people will do the hard part of the transition for you.

Saturday, June 26, 2010

Frustrated by SlideShare

SlideShare has some cool features and I really like the idea.  However, I do find its user experience maddening.  Not that I am the king of user experience or anything... the Hexagon Software website is evidence enough of that.

Still.  I'm one guy with a day job.  SlideShare appears to be a company that does this as a reason to exist.  Mostly the problems I have come from two things:

  1. Delays
  2. Unclear directives
Delays
I get that it takes time to do something like process a document into a SlideCast.  What I don't get is why there is no indication to me that I should be waiting.  Frequently, SlideShare will tell me something is "done" but it does not appear to actually be done, yet.  There is no way for me to determine whether something went wrong or everything is fine except to wait.

Unclear Directives
Generally speaking, buttons don't do what I think they should do.  This is especially true of file uploads.  Am I uploading a video?  A slide deck?  A document?  Why, when I try to upload a video, does the Open dialog not show videos but, when I try to upload a slide deck, I have to sift through a bunch of videos?

What Can We Learn?
In reality, these are all just examples of poor feedback.  A simple note saying "Your new document is in the final stages of processing.  Please be patient."  Would save a lot of pain and suffering.  A few extra developer hours on their upload technology would save decades in user time over the course of the next year.

Friday, June 25, 2010

Why & how DataClass can facilitate Agile database development

I've released another video on the topic of DataClass.  This time I go over what the problems related to database development are and how DataClass helps you resolve them.

Wednesday, June 23, 2010

DataClass 1.0 Beta Program Impending

Well, I'm excited to say that the beta program has reached critical mass in terms of registrants so we are definitely on for July.

Make sure you sign up here if you are interested.

I'm really excited about the opportunity to build a new product using what I know about business, product, and software development today.  DataClass is something that is a big deal for me because it is the result of nearly half a decade of accumulated knowledge.  Everything I learnt we shouldn't do with DataConstructor, I made sure isn't done by DataClass.  All the most important things I wished I could have are in DataClass.

Moreover, it represents a whole new way of thinking and of working with databases.  The vision I've been pushing in my courses and in my writings is now facilitated by a single logical document compiled by a single tool.

I look forward to getting real feedback and releasing the initial version of DataClass and I hope you do, too.

Saturday, June 19, 2010

DataClass Case Study #1: Solving the Duplication Problem

I've posted a short (12 minute) video on SlideShare that shows how you can use DataClass to eliminate duplication between the documents you used to define your database and your .net database client. I intend to hit Java in the near future.

Here is a link to the video.

Stay tuned and be sure to sign up for the beta if you want to be a part of it.

DataClass 1.0 Beta Program Open

The DataClass 1.0 Beta program is now open. DataClass is the next generation of DataConstructor technology. It is smaller, faster, and does a heck of a lot more.

If you are interested, the sign-up form can be found below. You will get a beta license to the product to be used over the course of the month of July. You will then get a survey to fill out in August. When you fill out the survey, you will get a complementary 1-seat license to DataClass as a thank you.


Click here to go to the beta sign-up page.

Monday, June 07, 2010

Two Customers

In response to http://whitewaterprojects.com/2010/06/04/who-is-your-cutomer/.

I respectfully disagree with the concept of a "technical customer" in addition to a "business customer."  It may just be a semantics thing but I think it's important to keep the customer's place special.

The customer is the customer.  For the team closest to the customer, that is not difficult to see.  For teams "behind" the teams on the "surface" of an organization, it gets a little cloudier.  I think it makes more sense to think of the intervening teams between yours and the customer as downstream work-cells.  As such, they have the power to specify what an upstream work-cell builds in the moment.

The mental difference, however, is that they are not considered customers when your organization is working to optimize the whole.

Now, if there are two kinds of customer, I would say that there is a business customer and a process customer.  That is, you can spend time delivering value to your actual customers, or you can spend time increasing your organizations capacity or lowering its cost.

The process customer is going to be interested in any project that eliminates waste.  This might be traditional process projects like training in the latest methodology.  This might be the acquisition of a tool.  This might be something we don't think of as process but that plays heavily into it, like refactoring or covering legacy code it tests.

The business customer just wants what it wants.

Friday, May 28, 2010

Oblivion for One
By Max Guernsey, III

Stop all the clocks?
Why bother?

This is the end...

...of life.
...of love.
...of joy.
...of pain.
...of experience.

At least, for one.  At 2:30 pm, today, one of our cats, Seelie, died.

For those of us left here, we go on; some more affected than others.  Yet, that's not really the point... is it?  Mourning is an inherently selfish thing.  We lament our loss; our pain; our experience; but those things all pale in comparison to what Seelie has lost: existence itself.

She is no more.  To her, there is no more "to be."  There is no more her for there to be no "to be" to.  Nothing.  No experience.  No love.  No joy or hate.  The world does not exist.

So I say "Stop all the clocks?  No need.  Prevent the dog from barking with a juicy bone?  No call."

For Seelie, the clocks have stopped and the dogs have stopped barking.  From her perspective, those things all happened and more: The entire universe, including herself, ceased to exist the moment she died.

Who will be next?

Friday, May 21, 2010

DataClass is almost here!

The new version of DataConstructor, DataClass, is almost ready for prime-time.  I've got all of the critical v1.0 features ready for release and all I have left is the packaging and tutorials.  I'm looking for beta testers so, if you are interested, let me know.

Each beta tester earns one Agile team a license to use v1.x of DataClass.

Quitting stack overflow

I tried being a member of the stackoverflow community.  At the end of the day, it appears to be no different from facebook... just another waste of time mindlessly drifting wherever the winds of mob mentality take it that day.  All investment, no return.

I'm done and you should seriously consider the following question, if you are a user: do you really get any value from it or is it just another addiction to a meaningless point system.

Tuesday, May 11, 2010

DataClass nearing completion

As many of you know, I'm working on the next generation of DataConstructor technology, DataClass.  I am personally very excited about this new product - it takes database building, design, and testing to the next level.  Here are some of the benefits that DataClass has (with red asterisks next to the benefits DataConstructor gave you):

  • It is a compiled language.
    • The only things not compiled are the SQL and DDL scripts themselves.
  • It enables designs with zero duplication.
    • No duplicated strings even between database scripts and .NET code.
  • It facilitates transition testing knowledge.*
    • DataClass still enables you to build a database from any historical version to any future version.*
  • It alleviates the need for most transition testing design.
    • For certain database platforms, basic design structures will be validated implicitly.
  • It does not require a license at runtime.
    • The compiler is the licensed component, not its output.
    • The developer is licensed rather than the application.
  • It allows you to define a complete class of database.
    • Transition logic.
    • Public, private, and protected design elements are all defined in one document.
    • Version info.
    • All are compiled into a single .NET class.
    • Public aspects are made public.

Tuesday, April 13, 2010

Mr. Graffin: My Uneaten Greens Are a Feast for Some, I Say

I just went two days without a substantive meal.  That's right: Fatty go hungry.  After two freaking days, I prepared for myself a meal I would never have previously considered eating and, guess what: It tasted great.

It takes me back to when I was a boy scout.  We went on this one hike that felt like forever.  At the end of the day, we made ourselves "hobo dinners."  Right up until now, that dining experience is still my fondest.  When I try to recreate it, I never succeed because I am not famished.

Here we are, the fattest, most abundantly fed nation in the known history of the world, and we can't get a decent meal.  The constant availability of relatively cheap, delicious food has driven our expectations to the point where we are difficult to satisfy and impossible to wow.

So, when I listen to the Bad Religion song "Quality or Quantity" - which I often do - and I hear Mr. Graffin lament the woes of the poor folk who live on "just seventy cents a day," I am forced to wonder "Do they really have it so bad?"

My point is this:
Have no sympathy for people who are living off of "less than the cost of a cup of coffee" a day; they are eating better than we do.

Monday, April 12, 2010

Book Titles

As some of you know, I am in the process of writing a book having to do with Agile database development. This book contains a lot of the ideas I cover in my course (shameless plug).

Since a lot of Agility ports straight across to database development, I'm largely not dealing with those issues. I'm trying to come up with a name that conveys "this book helps you overcome the technical impediments to Agile database design." Following are my ideas.  Any votes or suggestions would be welcome:


  • Agile Database Design: Just-Right, Just-in-Time
  • Agile Database Development: A Technical Perspective
  • Just-in-Time Database Design: And All It Entails
  • The Test-Driven Database: Building Solid, Flexible Data Stores
  • The JIT Database: How To
Basically, I'd love to hear any suggestions you have.

Sunday, April 04, 2010

Very Simple Sequencer for Moq...

Following is a very simple tool for testing Moq...


public class MoqSequence
{
  private int expectedSteps;
  private int actualSteps;

  private MoqSequence() { }

  internal static MoqSequence GetInstance()
  {
    return new MoqSequence();
  }

  private class SequenceException : Exception
  {
    private SequenceException(string message)
      : base(message)
    {
    }

    internal static SequenceException GetInstance(
      int expectedStep, int actualStep)
    {
      return GetInstance(
        "Step " + expectedStep + " executed when step "
        + actualStep + " should have been.");
    }

    internal static SequenceException GetInstance(
      string message)
    {
      return new SequenceException(message);
    }
  }

  public void InSequence<T>(ISetup<T> iSetup)
    where T : class
  {
    var expectedStep = expectedSteps++;

    iSetup.Callback(
      () =>
      {
        if (actualSteps != expectedStep)
        {
          throw SequenceException.GetInstance(
            expectedStep, actualSteps);
        }

        actualSteps++;
      });
  }

  public void Verify()
  {
    if (expectedSteps != actualSteps)
    {
      throw SequenceException.GetInstance(
        "Expected " + expectedSteps + 
        " steps but only got " + actualSteps +
        " steps");
    }
  }
}
Here is an example of how to use it:



[Test]
public void ExecutesStepsInCorrectOrder()
{
  var sequence = MoqSequence.GetInstance();

  sequence.InSequence(transactionMock.Setup(
    t => t.Lock()));
  sequence.InSequence(transactionMock.Setup(
    t => t.TransferAssetsIntoEscrow(escrowMock.Object)));
  sequence.InSequence(transactionMock.Setup(
    t => t.SchedulePayouts(escrowMock.Object)));
  sequence.InSequence(escrowMock.Setup(
    e => e.ReconcilePayoutsWithHoldings()));
  sequence.InSequence(escrowMock.Setup(
    e => e.ExecutePayouts()));
  sequence.InSequence(transactionMock.Setup(
    t => t.Complete()));

  transactionCoordinator
    .RunTransaction(transactionMock.Object);

  sequence.Verify();
}

Saturday, March 27, 2010

Do You Have a Jesus Problem? Alcohol is the answer.

Do you frequently get high on Jesus or Moses when you are alone?  Are you afraid to talk to your friends about where you went last Sunday?  Do you hide bibles around the house so your spouse can't find them?

These are all signs of religion abuse.  Religion abuse is a very serious condition that affects nearly two out of every three Americans.  If you don't suffer from religion abuse, look to your left, then to your right.  Both of those people probably do.

The affects of religious abuse last a lifetime.  Long term religion abuse can affect your personality, making your presence less pleasant or even unbearable to others.  People who are high on religion are often extremely suggestible and will do practically anything to "score" a shot at "heaven."  Worse still: people who abuse religion often pass their condition on to their children.

Even though it's completely ridiculous, these facts show that religion is no laughing matter.

But... if you suffer from this condition, I have some good news: there is a way out.  By giving yourself over to Alcohol, you can blind yourself to the evils of the world.  Through Its powers, you will become blissfully unaware of your suffering and will no longer feel the need to justify it by contriving fictitious entities who watch over you and have a "good reason" for putting you through a living hell.

And the wages of delusion is death of joy, but in Alcohol there is joy everlasting.
 Remember: you don't have to live like this.  You can think for yourself and you can find a way to cope with the cold, barren, empty void that is our existence without depending on imaginary figures from ancient fairy tales.  In Alcohol, there is redemption.  Turn yourself over to Alcohol and start living your life.

Saturday, March 20, 2010

The New Threat: Global Sideways-ing

People just don't get it.  Ever since several groups started trying to warn us about man-made global warming, there's been a small cadre of crackpots who've said crazy things like "Wait a minute!  Isn't the Earth just going through its normal cycle of warming and cooling?" or "Hey!  It seems like we shouldn't be worried about global warming when the Earth is near the bottom of it's ordinary temperature range."

Oh sure, the scientific and media community has been able to throw together some numbers and change their language against statements like the latter by changing "global warming" to "climate change."  ...but the threat those people pose still remains.  How exactly do you deal with it when someone has a modicum of knowledge about the Earth's climate history in a larger context, one that generally does not include man?  How do you handle pesky lunatics who want to point out that tens of thousands of years ago could not have been the last ice age because it was part of this ice age and, in fact, we are in what is known as an "interglacial period?"

You can try and show how insane they are for pointing at things like "evidence" and "historical data."  I'm sure that's what these fine, upstanding people would say is the right course of action.

However, I would like to point out that those of us who do believe in global warming; those of us who keep the faith in spite of the evidence - because that's what it's about, after all: keeping the faith - have been focusing on the wrong thing...

You see, this is a complex problem full of complex numbers and, as everybody knows, complex numbers have two components: the real part and the imaginary part.  Our problem is that we've been trying to convince people that man-made global climate change exists using real numbers and the real numbers have been very uncooperative.

What we need to start doing is helping people comprehend the threat posed by the imaginary numbers.  After all, the true threat lies in the imaginary component of the evidence we have collected, rather than the real part.  Let's look at a concrete example.

Let's say that last year, the global average temperature went up by 0.1°F - don't bother to fact-check, I made that up as a hypothetical.  Someone could argue we have absolutely no evidence whatsoever that, when exiting an ice age, the temperature should not go up as fast as it did.

What these people don't understand is the imaginary impact of that change and the very real threat it poses.  Let's take a closer look:

While, in our hypothetical example, the real component of climate change was only 0.1°F, the imaginary component could be 10i√(°F).  The good news is that we have no way of measuring this number so there is no way for those "that's not what the evidence suggests" fruitcakes to show that they are completely fabricated.  The bad news is that same attribute makes it so that those same nut jobs can say "because we cannot measure it, it won't have any measurable impact on our lives."


This can be resolved with the simple remedy of applying "what if;" the tool we used to generate a buzz and get people worried about global warming climate change in the first place.  All we have to say is "What if some event were to occur that caused the imaginary portion of our climate change to be squared?  Where would be be then?"

If our actual global average temperature were, say 67°F + 10i√(°F), and the imaginary portion were to be squared, the real part of our global average temperature would drop 100°F - a global catastrophe.  Likewise, if the temperature started out as 67°F - 10i√(°F), the temperature would jump 100°F - killing pretty much everything everywhere.


This proves, I think, that the real threat is not global warming, weirding, or climate change but Global Sidways-ing, man-made changes to the imaginary portion of our global average temperature that could lead to very disastrous consequences if mathematics were to fundamentally change in a way that caused those imaginary numbers to become real.

Living without Dryer Sheets

Now that I live in Bend, one of my biggest problems is static electricity.  Every time that I reach for my computer at work, I get shocked; sometimes hard enough that the affected finger goes a little numb for a few minutes.

Another problem I have is that I am lazy.  Horribly, horribly lazy... at least when it comes to mundane things.  Ask my wife, she'll confirm: I'm the laziest person there is.  Think you're the laziest?  Wrong.  It's me.

So, long story short: I don't have dryer sheets because I am too lazy to walk across the street and buy them.  So my static electricity problem is worse than ever before.

Problem: My pants carry too high a static charge.

Solution: Wrap them around the faucet while I'm brushing my teeth.

Faucets are pretty well grounded things.  Wrapping your clothes around them for a few minutes will drain them of most of their static charge.

So, if you are lazy and don't want to go get dryer sheets - or maybe your one of those new-age enviro-douches who lives in constant fear of the dryer-sheet-ocolypse... whatever the case, if you don't want to use dryer sheets use the faucet to de-staticify your clothes before you wear them.  You have my personal guarantee that it will work.*

* Personal guarantees made by Max Guernsey, III are backed by nothing.  Void where prohibited.  Void where permitted.

Monday, March 15, 2010

Your Last Chance to Sign up for My Database Agility Course is Approaching!

Tomorrow, the Early Bird Special prices for the March-April Database Agility Online Training will expire.  Although I will probably start another one no later than July, my schedule is pretty hectic so don't assume that I'll be starting one in May or June.  I might but I cannot make any promises.

For those of you who don't know what this course is about: it tackles the critical problems that make Agile software development difficult in the database domain.

Sunday, March 14, 2010

Automation and Value Streams

Recently, I release a book called "Goad Testing: Deepening our Understanding of Automated Tests."  While the general purpose of that particular writing is to help people find ways to keep their bed of tests as healthy as the tests help them keep their production code, it also hits on something that I believe and I talk about implicitly but never call out as a topic of its own...

Automation of any kind - programs written for customers, machines that build cars, video games, and, yes, tests too - are really instruments of process improvement.  In every single case they have no less than one of the following effects on some value stream:

  • They provide access to information which enables the completion of a step
  • They reduce the amount of time a step takes
  • They improve the quality of the outcome produced by a step
...and really, these all resolve down to a single impact:

Every piece of useful software reduces the amount of time required to complete some step in a value stream.

Whether or not the amount of time required without software made the step in question infeasible or caused the quality of its output to suffer is irrelevant, it's all a function of not being about to make a decision, come to a realization, trigger an action, store your findings, etc. quickly.  There is nothing that software can do but we people cannot, given enough time.  Even the fact that software runs the same way every time it is executed in the same context translates into an impact on the time it takes to get something done by minimizing the potential for rework.

It all comes down to time and process, which is what Lean told us in the first place.  The customer for a test just happens to be the development team that will use the test to avoid releasing crappy software to their customers.

Why does this matter?  ...because people bandy about all these different explanations of what tests "really are..."
  • A test isn't really a test... it's a specification
  • A test isn't really a test... it's process control
  • A test isn't really a test... it's a performance metric
Tests have the side effect of eliminating the need for a lot of those things but, at the end of the day, a test is a piece of software that reduces the cycle time of a development team by eliminating delays between the introduction of a defect and its discovery.

A.K.A.: a "test."

Thursday, March 04, 2010

Monday, March 01, 2010

Branching with Design

Code.  Code never changes. 
The end of the world occurred pretty much as we predicted.  Too much duplication.  Not enough manpower to go around.  The details are trivial and pointless.  The reasons, as always, purely human ones. 
(adapted from the beginning of the last real Fallout game)
 I hate branches.  I hate them... and why shouldn't I?  Here is the promise of a branch...

We're going to defer integration for a long time so that it will cost more when we do it but don't worry, until the branch is merged, we're going to essentially maintain two copies of the same code base.  Make that three.  Make that four.  Make that... ah fuck it.
Recently, a pretty decent argument was made in favor of branching...
We have to change X.  Whenever we change X, everyone on the team is broken for months.
Naturally, the first response is "Well, it shouldn't be that way."  To which the person with whom I was having the debate replied...
I know but it is.
Check...
We're trying to fix it but that's the way things are right now.
 ...aaaaaaand mate.

The team understood that it was a huge problem and wanted desperately to fix it but didn't have the resources to do all of the necessary refactoring before they had to change X.  Because of the size of the system, its complexity, and the level of encapsulation around X, there were going to be breaks; no "if"s, "and"s, or "but"s about it.


So what to do, then?  The answer is, as I'm sure you've guessed now, to branch with design.  What, precisely, does that mean?  The steps can be summarized pretty simply as follows:

  1. Find the places where X, is used and its behavior needs to change.
  2. Create a Facade that exposes just the functionality needed by those touch-points.
  3. Promote the Facade to an abstraction with its only variation being the classic usages of X.
  4. Make the old behavior the default variation of your Facade abstraction.
  5. Create another variation into which the new behavior is placed; provide QA with a place to "turn on" the new behavior.
The alternate behavior can be a Proxy to X, an alternate implementation... it can even be incomplete or not work - it's not being used in the normal "production" code path.  Yet, your "branch" is continuously integrated.


Without even touching your continuous integration configuration code, your "branch" will be built with the rest of the code.  If a test fails against it, your build goes red.  If you forget a semicolon, your build goes red.  You will receive continuous feedback as though you didn't branch... because you didn't.  Yet you will be able to insulate people working on other things from pain caused by your changes as if you did.


Now, I'm not claiming this as my own.  It would have to be crazy to do so as it is basically nothing more than a narration of how the Facade pattern plays out when you pursue it aggressively.  My point is not "Hey!  Look at this neat thing I invented," because I didn't invent it.


Instead, my point is that you can always do this and it always works.  I'm sure that, somewhere out in the world, someone has a good reason why they absolutely have to branch.  Disregarding such one-in-a-million scenarios, you should always branch with design rather than with source control.  It's safer, cleaner, and lower cost.

Sunday, February 28, 2010

Upcoming Database Agility Online Training

I will be running another course on database agility over the internet starting on March 16th.  This course is designed to give you an understanding of what the impediments to Agility in database development are and, of course, to show you how to overcome those impediments.

For more information click on the following link:
http://www.netobjectives.com/course-schedule/database-agility-online-mar-2010

Saturday, February 27, 2010

Facts and Certitude (A Retardation Celebration!)

Remember this dumb article?

Well, I've heard back from the team involved - at least from the assistant.

I'll paraphrase:

Them: You don't understand, this guy didn't agree with us.
Me: Oh I get that, how come that's wrong and you not agreeing with him is okay?
Them: His argument was "Nuh-uh."
Me: Are you sure that wasn't your argument?
Them: But he didn't accept a fact.
Me: Where does the fact come from?  How come your source is more valid than his?
Them: No... no... you just don't get it.  This is a proven fact.
Me: Proofs are only ironclad in how it leads from assumptions to conclusions.  The postulates (and, therefore the conclusions) themselves are still open for debate.
Them: You're trying to claim I don't understand.  Thanks for your input.
Me: (thinking duh!) I hope you see how funny that is.  I sure do, so thanks for enriching my day.

I'll go out on a limb here and say that there are some far worse arguments against the freedom of the press than these people - Glen Beck, for example - but, still, the fact that they are contributing to the media and inundating the weak minded with false certainty makes them part of the problem not part of the solution.

We need to come up with a system that routes people like this to jobs for which they are better suited.  For instance, I would suggest that the person I talked to should be taking out the trash rather than filling people's heads with it.

Thursday, February 25, 2010

Original Sin

Either make the abstraction good and its variations good, or make the abstraction bad and its variations bad; for the abstraction is known by its variations.
 We do not inherit to specialize, we inherit to add variation behind abstraction.  Yet both of the major platforms today - Java and .NET - force every object to specialize a base class.  For Java, you have to inherit java.Object, and for .NET it is System.Object.


...but it really doesn't matter; the damage is done either way.

This is the "original sin" of software development.  Every object must be able to determine if it is equivalent to another.  Every object must be able to bucket itself with equivalent and similar objects.  Every object must be able to convert itself to a string.

Whether you need these features or not, you must, at the very least, inherit them.  The true nature of abstraction is, therefore, tarnished.  You can never have a pure interface for every object is tarnished by the sins of its base class's designers.  Consequently, programmers will, forever, be weighed down by the mental model of objects as "data with behavior" that is so apparent in their platform's design.

I hope that, when he next real platform (ruby and python don't count, guys... I hope you all figure that out, soon), its architects will be more enlightened.  In the mean time, I hope you can bring yourself to flat-out ignore those garbage behaviors that every object inherits.

P.S.: Isn't it interesting that we, the gods of software, are the ones truly responsible for a sin of design committed by a single ancestor and that said sin burdens its every inheritor?

Wednesday, February 24, 2010

Remember when Facts Ended Arguments?

I sure don't.

Thanks to fark, I recently stumbled upon this article.  Go ahead and read it for yourself, if you like.  If you'd prefer to spend a few minutes of your life doing something more productive - like setting an orphanage on fire or smoking crack - I'll save you the trouble with by summarizing:

"I miss the days when people who didn't agree to me would simply cow tow to an appeal to authority."

Yep.  Those were the days.  I sure miss the days when people refused to think for themselves or ask "why."  Remember all the good things that came out of mindless obedience to those who claim knowledge with sufficient emphasis?  It's hard to count them all but I'll take a shot:

  • Witch-hunts
  • The Inquisition
  • The Crusades
  • The "War" on Terror
  • The "War" on Drugs
  • The Holocaust
I knew I would never make it through to the end of the list... after all, I'll probably only live another thirty to sixty years... but it was worth a try.  That guy's article is like a handmade Christmas card: heartfelt an the product of careful attention but ultimately worthless.

If you don't agree, indulge me by considering the following questions:
  • Do you understand the difference between "hypothesis," "truth," and "theory?"
  • What do you think the difference between our collective model of the universe and the universe itself is?
  • Do you remember when facts settled arguments?
    • When, specifically, was that?
  • What are “facts?”
    • What makes a “fact” good enough to “settle” an argument?
    • Who chooses these which assertions are “facts” and which are “opinions?”
  • Was phlogiston theory a fact when it was ?
    • Is it now?
    • Was it one before it was believed?
    • If it wasn't a fact, was it bad?
  • Do you have the power to tell me which facts are true and which will be contraindicated in the future?
    • If so, can you tell when?
    • (I would pay you handsomely for the use of that talent, by the way)
  • How, in your mind, do facts and beliefs differ?
  • What is the difference between proof and evidence?

Sunday, February 21, 2010

Is Encapsulation Creating Duplication?

The answer is a definite "no."  Each is the other's anathema.  Yet sometimes it looks like concision and encapsulation are at odds.

Let's take the simple example of encapsulating construction.  When you encapsulate a constructor, you might do something very simple as follows:

public class MyService {
  private MyService() { }


  public static MyService GetInstance() {
    return new MyService();
  }
}

The argument for encapsulating construction are pretty ironclad.  It's essentially free, and it lets you promote a class from a concrete class to an abstract one.  At least, theoretically speaking...

When you get into it, you find that something very annoying occurs.  Let's say that we need a new parameter when producing instances of MyService.  We have to make that change in two places.


public class MyService {
  private MyService(string parameter1) { }

  public static MyService GetInstance(string parameter1) {
    return new MyService(parameter1);
  }
}


This is arguably unavoidable: the system was closed to variation in whatever parameter1 represents.  We had to refactor the system to be open to that kind of variation and closed to future change pertaining to the same concept.  Yes we had to make a change in two places to be complete but we did it to improve design so its okay.

What about when we add another parameter?  Is that just another refactor?  What about when we want to delegate some of the work off to another method?  Do we now have to maintain two parameters in three signatures and some number of method calls?  In areas where change is the most common, the problem becomes clear quickly.

"Keep it simple!" someone might cry, "That's what you did wrong, you made things complex by adding a whole bunch of unnecessary methods."

Nonsense.

The problem isn't that I improved design.  The problem is that I missed an opportunity to improve design again when I added the parameter.  I made the called methods open-closed to the arguments with which they could be called (which is the whole point of a parameter) but I didn't encapsulate them from changes to the arguments, themselves.

What if I had done something like the following, instead?

public class MyService {
  public class InstantiationArguments {
    public string Parameter1 { get; set; }
  }



  private MyService(InstantiationArguments arguments) { }

  public static MyService GetInstance(InstantiationArguments arguments) {
    return new MyService(parameter1);
  }
}


That would have been a much better refactor.  For one thing, I would have been applying the open-closed principle correctly - rendering the thing I am refactoring open-closed to the kind of change I am introducing (changes to method signature).  For another, I could have done my work in smaller steps: first making the instantiation behavior open-closed to its parameters, then adding the parameter and handling its value.

The point here is this: the principles of design seem unassailable; at least, with our current knowledge.  When it look like a principle isn't working, it is most likely that you (or I) just cannot see how it applies and less likely that the principle is wrong or requires refinement.

There is no room for "moderation" when adhering to principles.  If there were, they wouldn't be principles.  You either refine them, figure out how to follow them, or perish at the hands of someone more competitive.

Friday, February 19, 2010

Goad Testing

Well.  I've spent long enough with this particular writing sitting on the shelf collecting dust.  I decided to finally get off my ass and publish it.  It is entitled Goad Testing: Deepening our Understanding of Automated Tests.  In addition to (hopefully) doing as the subtitle promises, the booklet teaches a technique that expands test driven development by ensuring that each test makes a distinction.

As was the case with Transition Testing: Cornerstone of Database Agility, I intend to have this writing be a short introduction to a broader concept.  Later, when I have more time on my hands, a book will follow about the larger concept.

Click here to check out Goad Testing now.