DaedTech

Stories about Software

By

The Journeyman Idealist: Architect of Programmer Paycuts

A couple of months ago, I mentioned that I’d be featuring more cross posts so that I could concentrate on my book.  I’ve lived up to that, mixing in the occasional answer to a reader question with posts I’ve written for other sites.  I haven’t queued up a good old fashioned rant in a while, but I think it might be time.

I want to start talking about topics from the book, and this particular topic, the “journeyman idealist” has relevance to a number of different, random conversations I’ve heard of late.  Don’t worry if you don’t know what “journeyman idealist” means — you shouldn’t because I made that up while writing my book.  And I’ll get to that and to our self-defeating pay tendencies a bit later.

Hourly Billing

Recently, I have consumed a great deal of content related to freelancing, consulting, and billing models.  This includes the following items, for those interested.

As I fall further into this rabbit hole, I become increasingly convinced that billing by the hour for knowledge work is a pile of fail.  Jonathan Stark of “Ditching Hourly” makes the case more eloquently in this episode, but I’ll offer a tl;dr.

Let’s say that a prospective client comes to you and says, “I want you to build me a website.”  Great!  Let’s do some business!

HighFive

Hourly Billing as a Zero Sum Game

At this point, you begin to think in terms of cost and how high you can go above it.  For the purpose of your business, this means “what is the minimum amount for which I will do this project?”  The client begins to think in terms of value and how far they can go below it.  For them, this means “what is the maximum amount I can pay and still profit?”  Perhaps you won’t build the site in question for less than $10,000 and the client needs the figure to be less than $100,000 for the venture to bring a profit.  Thus if you agree on a price between $10,000 and $100,000, you both benefit, though the amount of the benefit will slide one way or the other, depending on how close to each end point you settle.

If you were selling websites as commodities, you’d haggle, then settle on price, as with a used car.  But building custom websites by the hour differs substantially.  In that world, you strike a deal without agreeing to price.  You just both hope that when the dust settles, the price tag falls in the range of mutual profit, and no lawsuits commence.  But within that range, each party hopes for a different end of the spectrum.  And what’s more is that neither party knows the other’s figure.  You know only that you need more than $10K and client knows only that it needs less than $100K.

As the website provider, you want the project to take as long as possible.  It needs to go sailing past $10K, and hopefully as close to client’s upper bound as possible.  The less efficiently you work — the more hours it takes to build the site — the better your financial outlook.

Read More

By

Avoid these Things When Logging from Your Application

Editorial note: I originally wrote this post for the LogEntries blog.  You can check out the original here, at their site.  While you’re there, sign up for the service and check it out.

It seems almost strange to talk about avoiding things while logging.  After all, logging is your last line of defense or your salvation in many cases.  Some crazy bug in the field that shows up every third full moon?  An external auditor looking at your app’s runtime behavior?  Logging to the rescue.

So naturally, is stands to reason that you would want to log just about everything your application.  Whenever there’s any doubt, slam a logger call in there and let log level sort out the details.  You can always filter logs, but you can’t magic stuff into them after the fact.  So why, then, talk of avoidance?

wizard

Well, it turns out that, while logging may be a highly inclusive activity in terms of what should be included, there are ways to create problems.  You want to be liberal in terms of what you log, but judicious and wise in terms of how you log it.  You don’t want to indulge in a feckless free-for-all when it comes to the calls you make to your application’s logger.

So what are these problems, and how to avoid them?  Let’s take a look at some things that can come back to bite you.

Read More

By

Enforcing Immutability in Multi-Threaded Projects with NDepend

Editorial Note: I originally wrote this post for the NDepend blog.  You can check out the original here, at their site.  While you’re there, have a look around at some of the features you get by downloading NDepend.

Early in the days of object oriented programming, we really got a lot of mileage out of the language and paradigm features.  For instance, if your memory extends back far enough (or your application is legacy enough), you’ll see really, really deep inheritance hierarchies.  Since inheritance was a language feature, it stood to reason that we should get our money’s worth, and boy did we ever.  We look back on that as an anti-pattern now with our 20/20 hindsight.

The same was true of application state.  The classic notion of object oriented programming was one in which objects of state and of behaviors.  For perhaps the most iconic early conception of this notion, consider the active record design pattern.  This pattern addressed the so-called impedance mismatch by presenting us with an in-memory, object-based representation of a database table.  The object’s state was the table and the behaviors were records that you could perform on it, such as saving or deleting or what have you.

While active record, particularly in some communities, has not been as roundly rejected as deep inheritance hierarchies, it no longer enjoys the favor that it did more than a decade ago.  And a big part of the reason that it, and other state-based patterns don’t, is that the object-oriented community has come to favor immutability, meaning that any data stored in an object is read-only for the lifetime of that object.

vendingmachine

Immutable objects are, first and foremost, easier to reason about.  Take, for instance, the humble object collaborator.

public class ServiceConsumer
{
    public Service TheService { get; set; }

    public void UseTheService()
    {
        var aBeer = TheService.GetMeABeer();
    }
}

This may or may not work, depending on what people come along and do with TheService.  What happens if they null it out?  To make life easier, we move away from mutable state implementations in favor of approaches like this.

public class ServiceConsumer
{
    private readonly Service _service;
        
    public ServiceConsumer(Service service)
    {
        if (service == null)
            throw new ArgumentNullException(nameof(service));

        _service = service;
    }

    public void UseTheService()
    {
        var aBeer = _service.GetMeABeer();
    }
}

Now there’s no reason to worry about the service being valid.  At the time of object construction, we enforce any preconditions, and then we don’t need to worry that _service.GetMeABeer() is going to generate a null reference exception or wind up calling a different implementation than the last time it was invoked.  ServiceConsumer is now immutable with respect to Service.

Read More

By

Happy Thanksgiving, 2016!

I won’t be doing the regularly scheduled Thursday night/Friday morning post this week.

For those of you not in the US, today is the national holiday Thanksgiving for us.  To those of you in the US, happy Thanksgiving!  To celebrate, please enjoy this drawing of a turkey.  The turkey was almost the national bird of the US, but we ate it and chose the eagle instead.

turkey

By

Improve Your Code Review Game with NDepend

Editorial Note: I originally wrote this post for the NDepend blog.  You can check out the original here, at their site.  If you like posts about static analysis, have a look around while you’re there.

Code review is a subject with which I’m quite familiar.  I’m familiar first as a participant, both reviewing and being reviewed, but it goes deeper than that.  As an IT management consultant, I’ve advised on instituting and refining such processes and I actually write for SmartBear, whose products include Collaborator, a code review tool.  In spite of this, however, I’ve never written much about the intersection between NDepend and code review.  But I’d like to do so today.

I suppose it’s the nature of my own work that has made this topic less than foremost on my mind.  Over the last couple of years, I’ve done a lot of lone wolf, consultative code assessments for clients.  In essence, I take a codebase and its version history and use NDepend and other tools to perform extensive analysis.  I also quietly apply some of the same practices to my own code that I use for example purposes.  But neither of these is collaborative because it’s been a while since I logged a lot of time in a collaborative delivery team environment.

DevOpportunityCost

But my situation being somewhat out of sync with industry norms does not, in any way, alter industry norms.  And the norm is that software development is generally a highly collaborative affair, and that most code review is happening in highly collaborative environments.  And NDepend is not just a way for lone wolves or pedants to do deep dives on code.  It really shines in the group setting.

NDepend Can Automate the Easy Stuff out of Code Review

When discussing code review, I’m often tempted to leave “automate what you can” for the end, since it’s a powerful point.  But, on the other hand, I also think it’s perhaps the first thing that you should go and do right out of the gate, so I’ll mention it here.  After all, automating the easily-automated frees humans up to focus on things that require human intervention.

It’s pretty likely that you have some kind of automation in process for enforcing coding standards.  And, if you don’t, get some in place.  You should not be wasting time at code review with, “you didn’t put an underscore in front of that field.”  That’s the sort of thing that a machine can easily figure out, and that many, many plugins will figure out for you.

The advantages here are many, but two quick ones bear mentioning here.  First is the time-savings that I’ve discussed, and second is the tightening of the feedback loop.  If a developer writes a line of code, forgetting that underscore, the code review may not happen for a week or more.  If there’s a tool in place creating warnings, preventing a commit, or generating a failed build, the feedback loop is much tighter between undesirable code and undesirable outcome.  This makes improvement more rapid, and it makes the source of the feedback an impartial machine instead of a (perceived) judgmental coworker.

Read More