Skip to content

Instantly share code, notes, and snippets.

@JayBazuzi
Last active March 17, 2017 05:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JayBazuzi/0828de9d73740fcbbdd7350a8806a9cf to your computer and use it in GitHub Desktop.
Save JayBazuzi/0828de9d73740fcbbdd7350a8806a9cf to your computer and use it in GitHub Desktop.
Three Kinds of Code

I propose a refactoring "Extract Open Source Project".

We build software systems to some purpose. But when I read code, I see that some of that code directly serves that purpose while other code does not. I see three categories:

Features

This is the stuff you and your customers care about. It's the reason your software system exists.

In an e-commerce system, that's code that says "when a customer uses a discount code, the discount is applied to the order."

If you learn about code smells, great names, and duplication, and then refactor with those in mind, you'll find that some code is explicitly the feature and some that is not. That leads to:

Utilities

Code that helps you write code, but has nothing to do with the problem domain you're working in. It's often hidden right in the middle of the rest of your code, but as you refactor to improve readability and reduce duplication, it can become visible.

For example, consider this refactoring sketch. You start with this run-of-the-mill WPF View Model:

public class MyViewModel : INotifyPropertyChanged
{
  public event PropertyChangedEventHandler PropertyChanged = delegate {};

  string _name;
  public string Name
  {
    get { return _name; }
    set
    {
      if (_name == value) return
      _name = value;
      PropertyChanged(this, new PropertyChangedEventArgs("Name"));
    }
  }
}

If you have several such properties, you may notice the duplication in each of their setters (PropertyChanged(this, new PropertyChangedEventArgs("...")) and extract a method to reduce duplication. This also lets you take advantage of [CallerMemberName]. This cleans up the code a little:

public class MyViewModel : INotifyPropertyChanged
{
  public event PropertyChangedEventHandler PropertyChanged = delegate {};

  string _name;
  public string Name
  {
    get { return _name; }
    set
    {
      if (_name == value) return
      _name = value;
      RaiseNotifyPropertyChanged();
    }
  }
  
  void RaiseNotifyPropertyChanged([CallerMemberName]string propertyName = null)
  {
      PropertyChanged(this, new PropertyChangedEventArgs("Name"));
  }
}

You may then notice that saying that you implement that interface + the event member + RaiseNotifyPropertyChanged() all go together, and are a different level of abstraction from "Name". Or you may have multiple View Models with this same code, and notice the duplication. Suppose you decide to extract a base class to eliminate that duplication:

public class MyViewModel : NotifyPropertyChanged
{
  string _name;
  public string Name
  {
    get { return _name; }
    set
    {
      if (_name == value) return
      _name = value;
      RaiseNotifyPropertyChanged();
    }
  }
}

public abstract class NotifyPropertyChanged : INotifyPropertyChanged
{
  public event PropertyChangedEventHandler PropertyChanged = delegate {};

  void RaiseNotifyPropertyChanged([CallerMemberName]string propertyName = null)
  {
      PropertyChanged(this, new PropertyChangedEventArgs("Name"));
  }
}

Now you have a new class (NotifyPropertyChanged) that is in no way part of your domain; it's just about doing programming in WPF.

If you refactor mercilessly, you'll end up with a lot of this stuff. It's not part of the value you offer, and it would be useful to the programming community. Factor it out to be an open source project and share with the world.

Some examples of this are Boost in C++, FluentAssertions in C#, and Ruby on Rails in Ruby.

Domain Libraries

You'll also have some code that is specific to your domain, but is not the feature you're creating. This is code that lets you describe your feature. A library for building features in this domain. Maybe a DSL.

In that e-commerce system, it might be class like "Money". In a multiplayer game that might be "matchmaking".

While this is not the value you are offering, it is key to offering that value. You get to decide whether to release it as open source (so other people can build more systems in the same domain), or keep it under wraps (so your competition has to build their own).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment