Monday, March 3, 2014

Persistence Ignorance with Entity Framework

I've never been shy about the fact that I don't like Entity Framework. It's not because I think it's a bad framework, it's just that for my code it didn't seem to fit the task. And after all, the tools should support the need. The reason for this was mainly because I didn't want a data access framework to pollute my otherwise dependency-free domain.

For a lot of applications this isn't a problem, but I'm not working on those applications. For the stuff I work on, keeping dependencies isolated is very valuable. Additionally, any introductory walk-through of Entity Framework usually involved one of two things:
  1. Generate the models from the database. I really, really don't like doing this. Again, for a lot of applications this is fine. But more often than not I'm working in a fairly complex domain and need to have some real business-logic control over the models. I often find myself insisting such truths as, "Not every table is a business entity" or "Relational structures and object-oriented structures don't always match perfectly." In the end, as an object-oriented developer I like to have control over my models. (Also, I hate EDMX files. A lot.)
  2. With the advent of "Code First," generate the database from the models. While I certainly support the idea of starting with the domain modeling, and while I think it's an interesting approach to generate the database structure, does any significant real-world project actually do this? Are you really going to explain to your IT manager that they don't need to worry about their database schema and the framework is just going to handle that for them? Good luck with that.
So, really, what I've always wanted the framework to be able to provide for me was just a mapping between the models I create and the database schema I create. (Understanding that different models created in different applications may also map (albeit differently) to those same database tables.) And while I always thought that Entity Framework could do this, it wasn't obvious and I never had a compelling reason to dig into it.

But times change, and if you're doing data access work on the Microsoft stack these days then you'd be remiss not to be following along with Entity Framework. So recently I had an opportunity to really dig into it on a fairly simple project and see if I could achieve real persistence ignorance in an application. And, much to my surprise, I did. And very easily at that. So let's take a look at what's involved here...

First let's start with the models. (I told you I really support that.) Note that what follows is, of course, simplified for this example. But it works just fine. Now, in this business domain we have a concept of an Occurrence, with a stripped-down model here:

public class Occurrence
{
    public int ID { get; private set; }
    public bool InterestingCase { get; set; }
    public string Comments { get; set; }
    public Status ReviewStatus { get; set; }

    public string FieldToIgnore { get; private set; }

    public virtual ICollection<ContributingFactor> ContributingFactors { get; private set; }

    protected Occurrence()
    {
        ContributingFactors = new List<ContributingFactor>();
    }

    public Occurrence(bool interestingCase, string comments)
        : this()
    {
        InterestingCase = interestingCase;
        Comments = comments;
        ReviewStatus = Status.New;
    }

    public enum Status
    {
        New,
        In_Progress,
        Finalized
    }
}

public class ContributingFactor
{
    public int ID { get; private set; }
    public string Factor { get; private set; }

    protected virtual Occurrence Occurrence { get; private set; }
    public static readonly Expression<Func<ContributingFactor, Occurrence>> OccurrenceProperty = c => c.Occurrence;
    public int OccurrenceID { get; private set; }

    protected ContributingFactor() { }

    public ContributingFactor(string factor)
        : this()
    {
        Factor = factor;
    }
}

Simple enough, and as I said it's been stripped-down of a lot of business logic. (For example, the real one has a bunch of logic in the setters for tracking historical changes to the model at the field level, as well as a custom implementation of ICollection which prevents modifying the collection without using other custom methods on the model, again to ensure tracking of changes to values.) Let's identify a couple of the interesting parts:
  • The ID setter is private. This is because identifiers are system-generated by the backing data store and consuming code should never need to set one.
  • There's a contrived FieldToIgnore in the model. This is present in the example solely to demonstrate how the Entity Framework mappings can be set to ignore fields. By default it tries to make sense of every field, and a complex model can have a lot of calculated or otherwise not-persisted properties.
  • The collection of child objects is virtual, this helps Entity Framework populate it. It's kind of an example of EF leaking into the domain, but there's no compelling reason in the domain not to make it virtual, so I'm fine with it.
  • On the child object there's a protected reference to the parent object. Normally this might be public, but since the child can't exist outside the context of the parent then there's no need to be able to navigate back to the parent. Indeed, being able to do so introduces an infinite recursion when serializing and would require additional workarounds.
  • Also on the child object is a reference to the ID of the parent object. This will become clear when we discuss our database structure. Essentially it's needed because it's part of the key in my table. (I tend to use the identity column and the parent foreign key column as the primary key when a child is explicitly identified by its parent.)
  • You're probably also noticing that Expression property. That's another example of the Entity Framework implementation kind of leaking into the domain, sort of. It's there because the mappings in the DAL are going to need to reference that Occurrence property in order to map the relational structure. But since it's protected, they can't. Honestly, I've since discovered that having property references like this can be very handy for objects, so it's quickly becoming a more common practice for me anyway.
  • The child object is intended to be something of an immutable value type. The parent is the aggregate root and is the real domain entity, the child is just a value that exists on the parent.
A simple enough domain for an example. Now, our persistence-ignorant domain is going to need a repository and, just for good measure, a unit of work:

public interface OccurrenceRepository
{
    IQueryable<Occurrence> Occurrences { get; }
    void Add(Occurrence model);
    void Remove(Occurrence model);
}

public interface UnitOfWork : IDisposable
{
    OccurrenceRepository OccurrenceRepository { get; }
    void Commit();
}

That looks persistence-ignorant enough for me. So consuming code might look something like this:

using (var uow = IoCContainerFactory.Current.GetInstance<UnitOfWork>())
{
    var occurrence = new Occurrence(true, "This is a test");
    occurrence.ContributingFactors.Add(new ContributingFactor("Test Factor"));
    uow.OccurrenceRepository.Add(occurrence);
    uow.Commit();
}

Now, in order to get that to work (glazing over the IoC implementation, which isn't relevant to this example, but just know that I'm using a simple home-grown service locator) we're going to need our DAL implementation. That's the project which will hold the reference to Entity Framework. But before we get to that, let's create our tables:

CREATE TABLE [dbo].[Occurrence] (
    [ID]              INT            IDENTITY (1, 1) NOT NULL,
    [Comments]        NVARCHAR (MAX) NULL,
    [InterestingCase] BIT            NOT NULL,
    [Status]          INT            NOT NULL,
    CONSTRAINT [PK_Occurrence] PRIMARY KEY CLUSTERED ([ID] ASC)
);

CREATE TABLE [dbo].[ContributingFactor] (
    [ID]           INT            IDENTITY (1, 1) NOT NULL,
    [OccurrenceID] INT            NOT NULL,
    [Factor]       NVARCHAR (250) NOT NULL,
    CONSTRAINT [PK_ContributingFactor] PRIMARY KEY CLUSTERED ([ID] ASC, [OccurrenceID] ASC),
    CONSTRAINT [FK_ContributingFactor_Occurrence] FOREIGN KEY ([OccurrenceID]) REFERENCES [dbo].[Occurrence] ([ID])
);

Again, as you can see, I'm using a composite key on the child table. Everything else is pretty straightforward. Best of all so far is that nothing has referenced Entity Framework. The domain, the database, the application... They're all entirely ignorant of the specific implementation of the DAL. So now let's move on to that DAL implementation.

Entity Framework has objects which are analogous to the repository and the unit of work, called DbSet and DbContext respectively. Let's start with the unit of work implementation:

public class UnitOfWorkImplementation : DbContext, UnitOfWork
{
    public DbSet<Occurrence> DBOccurrences { get; set; }

    private OccurrenceRepository _occurrenceRepository;
    public OccurrenceRepository OccurrenceRepository
    {
        get
        {
            if (_occurrenceRepository == null)
                _occurrenceRepository = new OccurrenceRepositoryImplementation(this);
            return _occurrenceRepository;
        }
    }

    static UnitOfWorkImplementation()
    {
        Database.SetInitializer<UnitOfWorkImplementation>(null);

        // A fix for a known issue with EF
        var instance = SqlProviderServices.Instance;
    }

    public UnitOfWorkImplementation() : base("Name=EFBlogPost") { }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new OccurrenceMap());
        modelBuilder.Configurations.Add(new ContributingFactorMap());
    }

    public void Commit()
    {
        SaveChanges();
    }
}

The interesting bits here are:
  • A reference to the DbSet which will correspond to the repository.
  • A late-bound repository property to implement the interface. Note that we're passing a reference of the unit of work itself to the constructor, we'll see why when we build the repository.
  • A static initializer to set the database's initializer. (Also present is a small fix for an issue I spent an hour or so researching online regarding the SqlProvider. Without this line of code that doesn't do anything, Entity Framework was failing to load the provider at runtime. With it, no problems.)
  • The constructor passes a hard-coded connection string name to the DbContext's constructor. Feel free to make this as dynamic as you'd like.
  • An override for OnModelCreating which specifies our mappings. We'll create those in a minute.
  • The Commit implementation for the interface, which just called SaveChanges on the DbContext.
So far so good, pretty simple and with minimal code. Now let's see the repository implementation:

public class OccurrenceRepositoryImplementation : OccurrenceRepository
{
    private UnitOfWorkImplementation _unitOfWork;

    public IQueryable<Occurrence> Occurrences
    {
        get { return _unitOfWork.DBOccurrences; }
    }

    public OccurrenceRepositoryImplementation(UnitOfWorkImplementation unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }

    public void Add(Occurrence model)
    {
        _unitOfWork.DBOccurrences.Add(model);
    }

    public void Remove(Occurrence model)
    {
        _unitOfWork.DBOccurrences.Remove(model);
    }
}

Even simpler, with even less code. It's basically just a pass-through to the DbSet object referenced on the unit of work implementation. (Indeed, you can just pass the DbSet itself in the constructor instead of the whole unit of work, but this plays nicer with dependency injector graphs.) So far there hasn't been much ugliness from the framework at all. How about the mappings...

public class OccurrenceMap : EntityTypeConfiguration<Occurrence>
{
    public OccurrenceMap()
    {
        ToTable("Occurrence").HasKey(o => o.ID).Ignore(o => o.FieldToIgnore);
        Property(o => o.ID).IsRequired().HasColumnName("ID").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        Property(o => o.InterestingCase).IsRequired().HasColumnName("InterestingCase");
        Property(o => o.Comments).IsUnicode().IsOptional().HasColumnName("Comments");
        Property(o => o.ReviewStatus).IsRequired().HasColumnName("Status");
    }
}

public class ContributingFactorMap : EntityTypeConfiguration<ContributingFactor>
{
    public ContributingFactorMap()
    {
        ToTable("ContributingFactor").HasKey(c => new { c.ID, c.OccurrenceID });
        HasRequired(ContributingFactor.OccurrenceProperty).WithMany(o => o.ContributingFactors).HasForeignKey(c => c.OccurrenceID);
        Property(c => c.ID).IsRequired().HasColumnName("ID").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        Property(c => c.Factor).IsRequired().IsUnicode().HasColumnName("Factor");
    }
}

Still pretty simple and straightforward. Indeed, I've written more code than I really needed to here. A lot of this mapping logic is implicit in the framework, but making it explicit I think makes it more clear and at a cost of very little additional code. Again, the interesting bits:
  • In the parent object's map we set the field to ignore as an extension of defining the table and key.
  • We explicitly tell it when a column is an identity. For the parent object this actually isn't a problem, the framework figures this out. However for the child object it doesn't figure it out (because of the composite key) and needs to be explicitly specified. I just added the specification to the parent object's mapping as well for consistency.
  • The child object uses an anonymous type to define the composite key.
  • The child object requires that a parent object exists.
And, well, that's about it. The code runs as-is and consuming code can instantiate a unit of work, interact with it, commit it, and be done with it. Change tracking is all handled by the framework. Even setting those private fields, since the framework internally uses reflection to do all of this.

In fact, if you inspect your models at runtime you'll find that they're not actually your models, they're a dynamically-built type which inherit from your models (having used reflection to define the type). This is how the framework gets into your domain in this case, to perform entity tracking and all that good stuff. Which is great, because it means that I don't have to actually change my models to account for Entity Framework. The framework does that at runtime, leaving my design-time code unpolluted and re-usable.

All things considered, and I never thought I'd say this... I'm really liking Entity Framework at this point.

(If interested, the code from this post is available here.)

Thursday, February 27, 2014

It's OK to use POST

I recently attended a great presentation by Rob Daigneau on RESTful services, and as with any discussion about REST the group briefly waxed philosophical. (We were a pretty laid back group on the subject, actually. Conversations between software architects about what REST is and what it means can get pretty dogmatic.) And, as any such conversation goes, we ended up asking an age-old question...
How can we perform complex searches on a resource?
Rob categorized three general approaches, ordered from least flexible to most flexible:

  • Query string parameters
  • Basic DTOs
  • Complex DTOs with expression trees
(Note that this is also ordered from least difficult to most difficult.)

While we'd all love to have the complex DTOs which can express boolean logic and complex search criteria, I think we can all agree that the vast majority of cases doesn't merit the effort. Most of the time we just use query string parameters, and that's a perfectly workable reality for a lot of cases.

But some of us (read: me) are purists. We don't want strings, we want objects. Looking at a request with lots of query string parameters is like looking at a function signature with lots of parameters. It's distasteful. For functions which accept complex parameters, we build a structure to hold those parameters. It's why we use model binding in our MVC actions, it's why we use anonymous objects to initialize jQuery plugins, heck for some of us these object oriented principles are why we get out of bed in the morning.

So we land on the basic DTOs for issuing searches to resources. Right? Sounds good to me. Except... Aren't these GET requests?

Aye, there's the rub. For in that GET of requests what DTOs may come, when the server have shuffled off the request body?

The fact that we are purists is what brought us here. And the fact that we are purists is what troubles us still. As a purist for object oriented design principles, we want to use a DTO for our search predicates. As a REST purist, we want to issue a GET request because we're only fetching data, not creating or updating it. A quandary indeed. Or is it?

Life just wouldn't be the same without semantics. We argue them all the time, and we also use them to our advantage all the time. This situation is no different. So instead of trying to muck with the technology to hopefully put together something that works, let's step back and look at this from a semantic point of view. Let's think about this for a moment not in terms of technologies and implementations, but in terms of patterns and domain languages.

What is the request that we are making? If we're simply fetching a resource, then clearly it should be a GET request. But... are we simply fetching a resource? Or are we doing something more? Let's look at our object-oriented principles again, since those are what brought us here in the first place. We're not necessarily fetching an instance of a resource, we're fetching a collection of resources. And a collection of objects is itself an object, with its own logic and rules operating at the collection level.

Let's examine this collection a little further. Does this collection already exist on the server? Its elements exist, and ultimately those are what we're looking to fetch. But does the collection exist? More to the point, does this specific instance of such a collection exist?

No, it doesn't. We're using custom search criteria for our predicate. We're... creating a new instance of a collection of these entities. And what, dear fellow REST purists, do we use when we're creating a new instance of something? :::drumroll::: POST.

Take a moment to think about it. Let the ramifications sink in and fit so elegantly into all of the dogmatic puritan notions we share about REST. See the beauty of it.

Just look at the semantics of our clean URLs. For fetching an instance of a Customer, we might use this:
GET /Customers/123
 And for creating an instance of a collection of customers, we might use this:
POST /CustomerSearches
Clean. Beautiful. Poetic. We're creating a new collection of Customers, unique and unlike any other existing collection that may already be on the server. So we stuff a DTO into the request body, which contains all of the information needed to create this resource, and we get back the resource we just created.

But wait, there's more. You may have noticed that there's a possibility of a performance boost here. Now, the server makes no guarantee that this new unique instance of a CustomerSearch is going to stay there for long. Indeed, you may expect the server not to retain it at all. But it can. It can store the results, caching them if you will so as to not bother the backing data store if the user wants to run the same search again before some expiry time, and return an identifier along with the resource. So perhaps some time later the user can issue:
GET /CustomerSearches/456
And that user will get back the same results from that previous search. Or maybe it's not even the same results, maybe what was cached were the criteria of the search, and that GET request on CustomerSearches is simply a way to re-run the same search again. (Not unlike how databases cache query execution plans.) The possibilities are all there, and they're all semantically sound with RESTfulness.

We have beautiful objects, beautiful URLs, and beautiful HTTP verbs. We even have the added benefit of caching results and/or query executions. The purist in me rejoices.

Now, Rob would be the first to point out that the spec actually allows for POST to be used to solve our original problem anyway. Technically there's nothing wrong with sending the search DTO here:
POST /Customers
Go ahead and read the spec for yourself. POST can indeed be used to handle a number of alternate functions besides simply adding a new instance of a resource. So Rob's right about that, and in most cases that's not only acceptable but prudent and pragmatic. But settling for that doesn't satisfy the purist in me, not one bit. The above scenario, on the other hand, does. It reminds me of the REST promise ring I metaphorically wear (or perhaps the Clean Code wristband).

Either way, it's OK to use POST for the scenario of a complex search. Both approaches satisfy the spec, and more importantly both work for the system and are easily understood and supportable. The above approach, however, also fills me with that emotion I'm told is called joy.

Thursday, January 16, 2014

Capitalism - Still A Better Love Story Than Twilight

We live in a capitalist society. And I think that word has become socially distasteful over the years. (To be fair, living any any *-ist society sounds kind of distasteful. Perhaps it's the act of classifying and not the classification itself that's really at the heart of the perception?) We can debate at length as to how and why, or whether or not such perceptions are justified, but that's not what this is about.

I am a capitalist. There's that distaste again. Can you feel it? Just by hearing me say that, can you feel an almost foaming-at-the-mouth either in yourself or in others? After all, this means I'm greedy, doesn't it? It means I worship money, right? That I want to enslave the downtrodden so I can stand on their backs and smoke an expensive cigar?

I really don't think that's what it means. I honestly don't draw such a connection between being an active part of the society in which I live and being Kingpin. Though I've certainly met (or in some way interacted with) a fair number of people who, for whatever reason or set of reasons, don't separate the two concepts. And that's too bad for them, really.

Capitalism is not inherently evil. Are there evil people within capitalist societies? People who lie, bully, extort, and generally do terrible things for personal gain? Absolutely. If you can find me any society in the entirety of human history, capitalist or otherwise, which didn't suffer from that plague then I'm certainly interested to hear about it.

So no, I don't sit around reading Ayn Rand and thinking of ways I can abuse people and take their money. To be honest, I barely only tangentially knew who Ayn Rand was until the accusations of this behavior started to become more frequent. Cursory research on the subject led me to three conclusions about her work:
  1. Her fiction work was awful. I mean really just abysmal. This isn't to say that mine is any better (or even, you know, extant), but that's neither here nor there. If you're curious to learn just how bad it is but don't want to invest the time in reading one of her novels (who could blame you?), know that at the time of this writing parts 1 and 2 of the Atlas Shrugged movies are available for your viewing, um, pleasure. Pay close attention to the forced narrative, un-relatable characters, and absurd storyline.
  2. People who claim to hate her are obsessed with her. Again, the name was barely a footnote in my knowledge prior to encountering such people. Prior to this writing, I don't recall ever once injecting the subject into any conversation. But she sure has come up a lot from other people. I guess I don't see the attraction.
  3. To disagree with her philosophies is a human right. To deny her impact on modern business practices is, at best, naive.
But I digress. A lot. This isn't about the notion that people fervently accuse me of evil deeds simply because I have a fairly successful career. No, this is about a little corner of capitalism that is often forgotten. This is about the idea that just because we're looking at a spreadsheet of numbers doesn't necessarily conclude that we're not doing something good for the world.

That's all it really comes down to, isn't it? A spreadsheet of numbers? Capitalism isn't about being evil. There are no Captain Planet villains who spend billions on a business model that has no customers, only destructive deeds. It's about money. You know, capital. The rules are simple. If the gain outweighs the cost, it's a go. (Of course, there is much disagreement about the "cost" of non-tangibles, such as employee work/life balances or environmental damage. There is much disagreement about a lot of things. Welcome to life.)

At its simplest, if the numbers in Column A add up to more than the numbers in Column B then clearly Column A is the sound choice. All the complaining and arguing in the world isn't going to change the clarity of numbers. However, with a little reason and pragmatism, you can change the numbers themselves.

They're just variables. Values with weights assigned to them. If you desperately want Column B to be the outcome of the decision then your goal is pretty clear. Is your goal to argue? No. Is your goal to accuse the supporters of Column A of malfeasance? That doesn't seem productive either. Indeed, your goal is to get more numbers. What other factors haven't been considered? What other variables can be weighed and accounted? Outside of what other boxes can you think?

Because guess what? That works. I doubt any business leader or board member or what-have-you has ever been under the delusion of knowing everything. Sure, they may put up a front of sorts, because that's part of their job. But business decisions are based on information. And with a goal as clear as one number being greater than another number acting upon information seems like a pretty straightforward activity.

So... What information can you add to the discussion? Keep in mind that your personal opinions, regardless of how much passion you have for those opinions, are not information. Sorry to break it to you, but strongly-held opinions are not facts.

But that's not necessarily evil. No more than the application of the scientific method in research is evil. I dare say that a separation of opinion from fact is a cornerstone of enlightened society. (Though that's just my opinion.)

Now before the accusations fly again, let me assure you that I still realize that there are bad people who do bad things in the world. I toil under no delusion that capitalism by design is "good" (whatever that word means) or benevolent. (There is, after all, a lot of money to be made in standing on the backs of others. I don't personally do that, but it's hard to deny the motivations of those who do.) But just as it's not one extreme of that particular spectrum, it's also not the other.

Somewhere in the middle, in an oft forgotten corner of society, there exist numbers which add up to really, really good things. And when they do, it is indeed the function of capitalism which turns those good numbers into those good things. After all, if Column A is a greater sum than Column B then there's profit to be made. And if Column A also happens to be really good for the world, so much the better, right?

I sometimes refer to this phenomenon as The Lost Dream Of Capitalism. And, yes, I have examples.

Have you seen how Utah is planning to end homelessness? The statement alone sounds pretty good, doesn't it? But surely, surely such an endeavor would be expensive and nobody would want to pay for it, right? Nope. It's actually going to be cheaper. How did they come up with this? Simple. The numbers in Column A added up to more than the numbers in Column B.

The premise is financially sound. A bit of research into some data, pivoted and examined in the right light, led to a fascinating conclusion. The state basically figured out how much money they pay to subsidize emergency room services for care directly resulting from the poor living conditions of the homeless. (This is Column B.) Then they figured out how much it would cost to give apartments to their homeless population and assign them case-workers to help them become self-sustaining. (This is Column A.)

Both columns are a deficit, clearly. Both involve spending tax money. But the two numbers are not equal. While still in the negative, Column A was a greater value than Column B. It was a net gain for the budget. Helping people was deemed profitable. So, in traditional capitalist style, the more fiscally-sound choice was made. And, lo and behold, it wasn't inherently evil.

There are, indeed, a lot of businesses who are actively working toward this same fiscal model. A little closer to home for me is the company Dovetail Health. This is a company which reduces healthcare costs, increases patient care quality, and makes money doing it. (And they're not alone, they're just the only one I know off-hand.)

The business model is simple... Intervene in patient care conditions outside of a hospital setting at periodic intervals for the purpose of preventing further hospital visits. After all, hospital visits are expensive. Really expensive. But with a little bit of in-home intervention and comparatively simple patient care, hospital visits can be avoided. Insurance companies pay less for care (win), benefits-holders pay less for insurance (win), hospitals pay less in overhead (win), patients are healthier and more effectively avoid injuries (win), and finally... the company doing this makes money (win). Where's the evil in that last one again? Cause I'm not seeing it.

By thinking outside of a box or two, shifting the occasional paradigm, or whatever cliche business gobbledygook you want to use, the idea of making money can actually conform with the idea of improving the world in which we live.

It's something people don't often see when they look at the (evil) capitalist society around us. But for those who find it, for those who participate in it, the monetary rewards alone pale in comparison to the profound sense of community and fraternity to be found in not just doing something well, but doing something... good. Therein lies that lost dream of capitalism. Stepping outside the stereotype of nickeling-and-diming everybody into oblivion to squeeze more profit from society, and stepping into the simple notion of putting the right numbers into Column A to actually make the world a slightly better place to live.

It's all too rare, hence the "lost dream." But it's real. It exists. And if I can wish for anything on the subject it would be that the rabid opponents to the very word "capitalism" could step away from their Facebook rants for a moment and actually help with efforts like this. Actually use their intelligence for the better. The world could use better numbers in Column A, it can't use angry Facebook posts.

Tuesday, October 29, 2013

Refactoring Screencasts V

There exist a host of excuses for why it took so long to get these finished. But they boil down to two:
  1. There is no quiet place to record at home.
  2. There is no quiet place to record at work.
The first one is being remedied as we speak, for I'm in the process of moving to a new house and there will be space to set aside for a make-shift "recording studio" in said house. (Which will basically be a table and chair in the basement with some heavy blankets draped around it for sound dampening. But it's something at least. Note, however, that this "being remedied" is a long and drawn-out process, to be followed by the holidays, so I may be quiet for a while. But I digress...)

The second one hadn't been a problem during the summer, when my work mainly involved travel and hotel rooms are notoriously quiet when one is alone. However, for some time now I've been "between projects" and mainly sitting around in the company's office. (Which is not normally where a consultant spends his time.) Again, normally this isn't a problem. We have a conference room for this sort of thing. But another large project has been much taken over our office's conference room, for reasons I'm not aware of but aren't so uncommon to bear going into.

Yesterday, however, the conference room was inexplicably empty. So I was able to knock out the remaining recordings for the Making Method Calls Simpler series in an afternoon. Hopefully they don't appear hurried as a result. In any event, here they are. Enjoy!

Rename Method

Add Parameter

Remove Parameter

Separate Query From Modifier

Parameterize Method

Replace Parameter With Explicit Methods

Preserve Whole Object

Replace Parameter With Method

Introduce Parameter Object

Remove Setting Method

Hide Method

Replace Constructor With Factory Method

Encapsulate Downcast

Replace Error Code With Exception

Replace Exception With Test

Next I'll move on to the Dealing With Generalization series of patterns.

Friday, October 25, 2013

The Left Turn At Albuquerque

Bugs Bunny is lost. Really lost. And looking at a map of his current location doesn't seem to be helping him.
You see, he should have taken that left turn back at Albuquerque. Unfortunately, he missed that turn and just kept going in the wrong direction. And kept going, and kept going. Where is he now? Is this place even on his map? One thing's for certain... Getting from where he is now to where he wants to be isn't going to be easy. His original intent assumed a left turn at Albuquerque, so by definition everything he's done since then has been wrong.

This happens to programmers a lot. Invariably they find their way to Stack Overflow to ask a question about where they should go next. And very often they get a series of comments similar to this:
"Why are you doing it that way? There's no need for that. You're doing something else wrong."
It seems unhelpful on its face, but it's exactly the problem the programmer is facing. He's trying to solve a problem that he shouldn't have in the first place. And he's getting frustrated by the fact that there isn't a readily available solution to the problem that he just invented.

How should Bugs Bunny get to where he's going? Well, we don't know. We'll never know, because he didn't tell us where he's going. Nor did he tell us where he came from. We don't know the problem domain that he's trying to solve.

The programmer needs to step back for a moment and examine the bigger picture. It's not that we don't want to help him solve his problem, it's that we don't know what the actual problem is. And we need to know that to be of any use. Sure, maybe we can help him with his current roadblock. Then he'll just come back in an hour trying to solve his next roadblock.

If Bugs Bunny's tunnel encounters a massive outcropping of rock, he's going to ask someone how to get around that rock. And maybe they'll show him. Great, now he's on the other side of the rock. But is he any closer to his destination? We don't know, because that's not what he asked us. He only asked us how to get around the rock.

The programmer took a wrong turn somewhere. Perhaps a very wrong turn. Perhaps somewhere a long time ago. We don't know. All we know is that the sequence of steps, with no weights assigned to them to provide any perspective, went something like this:
  1. Programmer performed Step 1.
  2. Programmer performed Step 2.
  3. Programmer messed up on Step 3.
  4. Programmer figured out how to perform Step A.
  5. Programmer figured out how to perform Step รพ.
  6. Programmer got stuck on Step ± and asked for help.
  7. Programmer became frustrated that the help didn't get him any closer to Step 10.
  8. Rinse, repeat.
We want to help this programmer. We really do. But we can't unless we know the actual problem he's trying to solve. Not the immediate roadblock he's facing right now, but the actual problem being solved.

I guess if there's any piece of advice I can give from this little rant, it's this...
  • Never assume that everything you've done until now has been correct.
  • Never assume that just because you got something to work it means you're any closer to your goal.